Android获取用户当前位置并在MapView添加标记问题求助
Hey Paul, let's break down why your current location marker isn't working and fix it properly.
a) Why Your Code Isn't Working
Here are the key issues in your current implementation:
- Unused & Deprecated API: You declared
GoogleApiClientbut never initialized or used it. Worse, this API is deprecated—Google recommends usingFusedLocationProviderClientfor location updates now. - Unconnected Location Callback: Your
onLocationChangedmethod is custom, but you never registered it with the system. Android won't automatically call this method unless you set up a location listener. - Incomplete Permission Handling: You request location permissions in
onCreate, but you don't handle the user's response (allow/deny) withonRequestPermissionsResult. If the user grants permission after your initial request, your code won't trigger a location refresh. - No Location Update Request: Even if permissions are granted, you never tell the system you want to receive location data. There's no code to request periodic or one-time location updates.
- Missing "My Location" Setup: You didn't enable the built-in "My Location" layer on the map (via
mMap.setMyLocationEnabled(true)), which is the simplest way to show the user's current position, or implement logic to add a marker once you have location data.
b) Fixed Implementation
Here's the revised code with all issues addressed. I've added comments to explain each change:
import android.Manifest; import android.content.Intent; import android.location.Location; import android.net.Uri; import android.os.Bundle; import android.widget.Button; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationCallback; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationResult; import com.google.android.gms.location.LocationServices; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import static android.content.pm.PackageManager.PERMISSION_GRANTED; public class fthactivity extends AppCompatActivity implements OnMapReadyCallback { private GoogleMap mMap; private FusedLocationProviderClient fusedLocationClient; private LocationCallback locationCallback; private static final int LOCATION_PERMISSION_REQUEST_CODE = 3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fthactivity); // Initialize modern location API client fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); // Set up callback to handle incoming location updates locationCallback = new LocationCallback() { @Override public void onLocationResult(@NonNull LocationResult locationResult) { if (locationResult == null) { return; } // Get latest location and update map if available Location location = locationResult.getLastLocation(); if (location != null && mMap != null) { updateUserLocationMarker(location); } } }; // Initialize map fragment SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.fthmap); mapFragment.getMapAsync(this); // Phone dialer button logic (unchanged) findViewById(R.id.fthphone).setOnClickListener(v -> dialContactPhone("1234567890")); // Web link button logic (unchanged) Button btn = findViewById(R.id.fthweb); btn.setOnClickListener(v -> { Intent myWebLink = new Intent(Intent.ACTION_VIEW); myWebLink.setData(Uri.parse("http://google.ca/")); startActivity(myWebLink); }); // Check location permissions on launch checkLocationPermissions(); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // Add your fixed marker (unchanged) LatLng fthloc = new LatLng(51.036585, -114.066152); mMap.addMarker(new MarkerOptions().position(fthloc).title("Certain Location")); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(fthloc, 18.0f)); // Re-check permissions after map is ready to enable location features checkLocationPermissions(); } private void checkLocationPermissions() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PERMISSION_GRANTED) { // Request permission if not granted ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); } else { // Permissions granted: enable built-in location dot and request updates if (mMap != null) { mMap.setMyLocationEnabled(true); // Shows blue dot for current location } startLocationUpdates(); } } private void startLocationUpdates() { // Configure location update settings LocationRequest locationRequest = LocationRequest.create(); locationRequest.setInterval(10000); // Update every 10 seconds locationRequest.setFastestInterval(5000); // Fastest allowed update interval locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Request location updates (only if permissions are granted) if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PERMISSION_GRANTED) { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null); } } private void updateUserLocationMarker(Location location) { LatLng userLoc = new LatLng(location.getLatitude(), location.getLongitude()); // Add custom marker for user's current location mMap.addMarker(new MarkerOptions().position(userLoc).title("Your Location")); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLoc, 18.0f)); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) { // Permission granted: set up location features checkLocationPermissions(); } else { // Permission denied: add logic here (e.g., show a toast explaining why permission is needed) } } } @Override protected void onPause() { super.onPause(); // Stop location updates when activity is paused to save battery fusedLocationClient.removeLocationUpdates(locationCallback); } @Override protected void onResume() { super.onResume(); // Resume location updates when activity is active again checkLocationPermissions(); } private void dialContactPhone(final String phoneNumber) { startActivity(new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumber, null))); } }
Additional Required Step: Update AndroidManifest.xml
Make sure you've added these permissions to your manifest file (inside the <manifest> tag, outside <application>):
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- For Android 10+, add this if you need background location (optional for your use case) --> <!-- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> -->
Key Improvements Explained:
- Modern Location API: Uses
FusedLocationProviderClientinstead of deprecatedGoogleApiClientfor reliable, optimized location data. - Proper Callback Registration: The
LocationCallbackis connected to the system, so it will receive location updates automatically. - Complete Permission Flow:
onRequestPermissionsResulthandles user choices and triggers location setup if permission is granted. - Lifecycle-Aware Updates: Location updates stop when the activity is paused (saves battery) and resume when it's active again.
- Built-in Location Layer: Enables the default blue dot for current location (you can keep this or use only your custom marker, or both).
内容的提问来源于stack exchange,提问作者Paul Jonathan
相关产品推荐
相关产品推荐

