Android定位服务每次返回不同数值的原因及精准经纬度获取咨询
Hey there! Let's break down your problem first: you can never get exactly the same latitude and longitude every time, even if you're standing completely still. GPS and location services inherently have some level of noise—signal reflections, atmospheric interference, satellite geometry, and even device hardware all contribute to small variations. That said, an 800-meter deviation is way too high, so we can definitely fix that to get much more consistent, accurate results.
Here are the key steps to optimize your location setup:
1. Prioritize High-Accuracy Location Providers
The 800m error is likely coming from using the NETWORK_PROVIDER (which relies on cell towers/Wi-Fi and has wide error margins) instead of the GPS provider. Make sure you're requesting the most precise provider available:
// Create criteria to filter for high-accuracy providers Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); // Prioritize GPS criteria.setPowerRequirement(Criteria.POWER_HIGH); // Allow higher power for better accuracy String bestProvider = locationManager.getBestProvider(criteria, true); // Only use the best provider if it's available if (bestProvider != null) { locationManager.requestLocationUpdates(bestProvider, 0, 0, yourLocationListener); }
2. Filter Out Low-Accuracy Readings
In your onLocationChanged method, ignore any location updates that don't meet your accuracy threshold. This weeds out noisy or outdated readings:
@Override public void onLocationChanged(Location location) { // Only accept locations with accuracy better than 10 meters (adjust as needed) if (location.getAccuracy() <= 10) { // Use this reliable location double lat = location.getLatitude(); double lon = location.getLongitude(); } else { // Skip this reading—it's too inaccurate Log.d("Location", "Ignoring location with accuracy: " + location.getAccuracy() + "m"); } }
3. Wait for a Stable GPS Fix
When your app starts, the first few location updates might be rough as the GPS module locks onto satellites. You can wait until you have a sufficient number of satellites before using the location:
locationManager.addGpsStatusListener(new GpsStatus.Listener() { @Override public void onGpsStatusChanged(int event) { if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) { GpsStatus status = locationManager.getGpsStatus(null); Iterable<GpsSatellite> satellites = status.getSatellites(); int lockedSatellites = 0; for (GpsSatellite sat : satellites) { if (sat.usedInFix()) { lockedSatellites++; } } // Wait until at least 4 satellites are locked (minimum for a reliable fix) if (lockedSatellites >= 4) { locationManager.requestLocationUpdates(bestProvider, 0, 0, yourLocationListener); // Remove this listener once we have a fix to save resources locationManager.removeGpsStatusListener(this); } } } });
4. Switch to Fused Location Provider (Highly Recommended)
The old LocationListener API is pretty basic. Google's Fused Location Provider (part of Google Play Services) is smarter—it combines GPS, Wi-Fi, cell towers, and device sensors to deliver more accurate and consistent results, while also being more power-efficient. Here's a quick snippet to get you started:
// Initialize FusedLocationProviderClient FusedLocationProviderClient fusedClient = LocationServices.getFusedLocationProviderClient(context); // Create a high-accuracy location request LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(1000); // Update every 1 second (adjust as needed) locationRequest.setFastestInterval(500); // Request location updates fusedClient.requestLocationUpdates(locationRequest, new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) return; Location location = locationResult.getLastLocation(); if (location != null && location.getAccuracy() <= 10) { // Use this accurate location double lat = location.getLatitude(); double lon = location.getLongitude(); } } }, Looper.getMainLooper());
5. Avoid Using Cached Locations
Sometimes the system returns a cached location from a previous session. You can check the timestamp of the location to ensure it's recent:
long currentTime = System.currentTimeMillis(); // Only accept locations that are less than 10 seconds old if (currentTime - location.getTime() < 10000) { // This is a fresh, reliable location }
Important Note
Even with all these optimizations, you'll still see tiny variations (a few meters at most) in your coordinates—that's normal for GPS. But you should easily eliminate that 800m deviation and get consistent, accurate readings within 5-10 meters when outdoors with a clear view of the sky.
内容的提问来源于stack exchange,提问作者Pradeep Kumar

