Android设备Google Map显示当前位置:Marker不显示及定位异常求助
Hey there, let's work through this Google Maps marker issue together – I’ve dealt with similar headaches before, so I think I can point you in the right direction! The root cause here is likely a combination of permission gaps, outdated location APIs, or device settings misconfigurations. Let's break it down step by step.
First: Fix the "Provider Unavailable" Problem
The isProviderAvailable returning false is a red flag that your app can't access location services at all. Here's what to check:
1. Device Settings Check
- Turn on Location Services: Go to your device's Settings > Location and toggle it ON.
- Set High Accuracy Mode: Switch the location mode to "High Accuracy" (this combines GPS, Wi-Fi, and mobile networks to ensure the system can find a valid provider).
- Verify App Permissions: Head to Settings > Apps > [Your App] > Permissions > Location and make sure you've granted either "Allow only while using the app" or "Allow all the time" (depending on whether you need background location access).
2. Update Your Permissions in AndroidManifest.xml
You're missing critical permissions if your app can't access location providers. Add these to your manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Required for Android 12+ --> <application ...> <!-- Don't forget your Google Maps API key --> <meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_GOOGLE_MAPS_API_KEY"/> <uses-library android:name="com.google.android.gms.maps" android:required="true" /> </application>
3. Ditch the Old LocationManager for FusedLocationProvider
The classic LocationListener + LocationManager setup is outdated and unreliable on modern Android versions. Google recommends using the Fused Location Provider from Google Play Services – it automatically handles provider selection, battery optimization, and accuracy.
Second: Get Your Marker to Show Up
Once location access is working, adding a marker is straightforward. Here's a complete, tested code example using Kotlin and FusedLocationProvider:
import android.Manifest import android.content.pm.PackageManager import android.location.Location import android.os.Bundle import android.widget.Toast 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.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 class MapsActivity : AppCompatActivity(), OnMapReadyCallback { private lateinit var mMap: GoogleMap private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var locationCallback: LocationCallback private var currentMarker: com.google.android.gms.maps.model.Marker? = null private val LOCATION_PERMISSION_REQUEST = 1001 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_maps) // Initialize Fused Location Provider fusedLocationClient = FusedLocationProviderClient(this) // Set up map callback val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) // Define what happens when we get a location update locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) locationResult.lastLocation?.let { updateMarker(it) } } } } override fun onMapReady(googleMap: GoogleMap) { mMap = googleMap mMap.uiSettings.isMyLocationButtonEnabled = true // Check permissions before accessing location if (ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { // Request permissions if not granted ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST ) return } // Enable the built-in "my location" layer (optional but helpful) mMap.isMyLocationEnabled = true // Start receiving location updates startLocationUpdates() } private fun startLocationUpdates() { val locationRequest = LocationRequest.create().apply { interval = 10000 // Update every 10 seconds fastestInterval = 5000 // Allow faster updates if available priority = LocationRequest.PRIORITY_HIGH_ACCURACY } if (ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { return } fusedLocationClient.requestLocationUpdates( locationRequest, locationCallback, null // Use main thread by default ) } private fun updateMarker(location: Location) { val currentLatLng = LatLng(location.latitude, location.longitude) // Remove old marker if it exists currentMarker?.remove() // Add new marker with your location currentMarker = mMap.addMarker( MarkerOptions() .position(currentLatLng) .title("My Location") .snippet("Lat: ${location.latitude}, Lng: ${location.longitude}") ) // Move camera to center on your location mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f)) } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == LOCATION_PERMISSION_REQUEST) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission granted – start location updates if (::mMap.isInitialized) { if (ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { return } mMap.isMyLocationEnabled = true startLocationUpdates() } } else { Toast.makeText(this, "Location permission is required to show your marker", Toast.LENGTH_SHORT).show() } } } // Stop location updates when app is paused to save battery override fun onPause() { super.onPause() fusedLocationClient.removeLocationUpdates(locationCallback) } // Resume updates when app is active again override fun onResume() { super.onResume() if (ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED ) { startLocationUpdates() } } }
Final Checks
- Test on a Real Device: Emulators often have location simulation issues. If you must use an emulator, set a mock location via the emulator's controls.
- Verify Your API Key: Make sure your Google Maps API key is enabled for the Maps SDK for Android in the Google Cloud Console, and that it's restricted to your app's package name and SHA-1 fingerprint.
- Check for Background Location Needs: If your app needs location access when it's in the background (Android 10+), you'll need to add the
ACCESS_BACKGROUND_LOCATIONpermission and request it dynamically.
内容的提问来源于stack exchange,提问作者Gorib Developer

