2024.5.3

一点都不难發表於2024-06-28

最關鍵的一個功能——打卡功能,即“地圖”介面設計和功能實現
DituFragment.java
package com.example.share;

import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;

public class DituFragment extends Fragment implements AMapLocationListener {
private MapView mapView;
private AMap aMap;
private AMapLocationClient mlocationClient;
private AMapLocationClientOption mLocationOption;
private static final int REQUEST_LOCATION_PERMISSION = 100;

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_ditu, container, false);
    mapView = view.findViewById(R.id.map);
    mapView.onCreate(savedInstanceState);
    if (aMap == null) {
        aMap = mapView.getMap();
        aMap.setMyLocationEnabled(true);
        aMap.setOnMyLocationChangeListener(this::onMyLocationChange);
    }
    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
    } else {
        try {
            // 更新隱私合規狀態
            updatePrivacyShow(true);
            updatePrivacyAgree(true);

            // 初始化位置服務
            initLocation();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    addScenicSpotMarkers();
    return view;
}

public void onMyLocationChange(Location location) {
    if (location != null) {
        AMapLocation amapLocation = new AMapLocation(location);
        onLocationChanged(amapLocation);
    } else {
        Log.e("AmapErr", "Location is null");
    }
}

private void initLocation() throws Exception {
    mlocationClient = new AMapLocationClient(getActivity());
    mLocationOption = new AMapLocationClientOption();
    mlocationClient.setLocationListener(this);
    mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
    mlocationClient.setLocationOption(mLocationOption);
    mlocationClient.startLocation();
}

// 更新隱私合規狀態介面呼叫示例
private void updatePrivacyShow(boolean show) {
    // 在這裡呼叫你的隱私合規介面,例如:
    // PrivacyManager.updatePrivacyShow(show);
    AMapLocationClient.updatePrivacyShow(getActivity(), true, true);
}

// 更新使用者隱私同意狀態介面呼叫示例
private void updatePrivacyAgree(boolean agree) {
    // 在這裡呼叫你的隱私合規介面,例如:
    // PrivacyManager.updatePrivacyAgree(agree);
    AMapLocationClient.updatePrivacyAgree(getActivity(), true);
}

private void addScenicSpotMarkers() {
    LatLng spot1 = new LatLng(39.906901, 116.397972); // 替換為實際景點座標
    LatLng spot2 = new LatLng(39.908901, 116.397972); // 替換為實際景點座標

    aMap.addMarker(new MarkerOptions().position(spot1).title("景點1").snippet("景點1描述"));
    aMap.addMarker(new MarkerOptions().position(spot2).title("景點2").snippet("景點2描述"));
}

@Override
public void onLocationChanged(AMapLocation amapLocation) {
    if (amapLocation != null && amapLocation.getErrorCode() == 0) {
        checkInAtScenicSpot(amapLocation);
    } else {
        String errText = "定位失敗," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
        Log.e("AmapErr", errText);
    }
}

private void checkInAtScenicSpot(AMapLocation location) {
    LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());

    LatLng spot1 = new LatLng(39.906901, 116.397972); // 替換為實際景點座標
    float[] result = new float[1];
    Location.distanceBetween(userLocation.latitude, userLocation.longitude, spot1.latitude, spot1.longitude, result);

// if (result[0] < 100) { // 假設距離小於100米即為接近景點
// String username = getUsername();
// if (!username.isEmpty()) {
// DatabaseHelper dbHelper = new DatabaseHelper(getActivity());
// dbHelper.addCheckIn(username, "景點1");
// Toast.makeText(getActivity(), "成功打卡景點1", Toast.LENGTH_SHORT).show();
// } else {
// Toast.makeText(getActivity(), "使用者未登入", Toast.LENGTH_SHORT).show();
// }
// }
}

private String getUsername() {
    SharedPreferences sharedPref = getActivity().getSharedPreferences("app_prefs", Context.MODE_PRIVATE);
    return sharedPref.getString("username", "");
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_LOCATION_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            try {
                initLocation();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            Toast.makeText(getActivity(), "定位許可權被拒絕", Toast.LENGTH_SHORT).show();
        }
    }
}

@Override
public void onResume() {
    super.onResume();
    mapView.onResume();
}

@Override
public void onPause() {
    super.onPause();
    mapView.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
    if (mlocationClient != null) {
        mlocationClient.onDestroy();
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);
}

}
fragment_ditu.xml

<com.amap.api.maps.MapView
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />