You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助FusedLocationProviderClient获取精准的经纬度定位

Hey, I’ve run into this exact location jump problem with FusedLocationProviderClient before—those sudden spikes from 10m to 200m (and right back) are almost always caused by switching between low-accuracy network positioning and GPS, or noisy, drifted location readings. Let’s walk through practical fixes tailored to your code:

1. Filter out low-accuracy location readings

The Location object returned by FusedLocationProvider includes an accuracy field (in meters) that tells you how reliable the reading is. You can set a threshold to ignore any readings that are too imprecise—for example, only keep locations with an error margin of 20 meters or less:

Update your onNewLocation method to add this check:

private fun onNewLocation(location: Location) {
    Log.i(TAG, "New location: $location")
    // Skip readings that are too inaccurate
    if (location.accuracy > 20) {
        Log.w(TAG, "Ignoring low-accuracy location (${location.accuracy}m error)")
        return
    }
    mLocation = location
    // Your existing distance calculation logic here...
}

2. Tweak your LocationRequest parameters

You’re already using PRIORITY_HIGH_ACCURACY (great call!), but we can add a couple more settings to reduce jumps:

  • Add smallestDisplacement: This tells the provider only to send updates when the user moves beyond a certain distance, which filters out tiny drift-induced updates.
  • Adjust interval timing if you don’t need 5-second updates—longer intervals give the GPS module time to lock onto a stable signal.

Modify your createLocationRequest function:

private fun createLocationRequest() {
    mLocationRequest = LocationRequest()
    mLocationRequest!!.interval = UPDATE_INTERVAL_IN_MILLISECONDS // You could bump this to 10000 (10s) if you don't need frequent updates
    mLocationRequest!!.fastestInterval = FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS
    mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    // Only trigger updates if the user moves 5+ meters
    mLocationRequest!!.smallestDisplacement = 5f
}

3. Add location smoothing with a simple cache

For occasional rogue jump readings, you can smooth your location data by averaging the last few valid points. This softens sudden spikes:

First, add a cache to your LocServices class:

private val validLocations = mutableListOf<Location>()
private const val MAX_CACHED_LOCATIONS = 3 // Keep last 3 valid readings

Then update onNewLocation to use this cache:

private fun onNewLocation(location: Location) {
    if (location.accuracy > 20) {
        Log.w(TAG, "Ignoring low-accuracy location (${location.accuracy}m error)")
        return
    }
    // Update the cache, keeping only the last 3 valid locations
    validLocations.add(location)
    if (validLocations.size > MAX_CACHED_LOCATIONS) {
        validLocations.removeAt(0)
    }
    // Calculate the average of cached locations for a smoothed reading
    val avgLat = validLocations.map { it.latitude }.average()
    val avgLng = validLocations.map { it.longitude }.average()
    val smoothedLocation = Location("smoothed").apply {
        latitude = avgLat
        longitude = avgLng
        accuracy = validLocations.map { it.accuracy }.average().toFloat()
    }
    mLocation = smoothedLocation
    // Use smoothedLocation for your distance calculation instead of raw location
    val selected_location = Location("locationA")
    selected_location.latitude = existLatitude!!.toDouble()
    selected_location.longitude = existLongitude!!.toDouble()
    val distance = selected_location.distanceTo(smoothedLocation)
    // Rest of your toast logic here...
}

4. Validate the "last location" before using it

Your getLastLocation call might return an old or inaccurate reading. Add checks to ensure it’s recent and precise enough:

private fun getLastLocation() {
    try {
        mFusedLocationClient!!.lastLocation
            .addOnCompleteListener { task ->
                if (task.isSuccessful && task.result != null) {
                    val lastLoc = task.result
                    // Only accept locations from the last 5 minutes with good accuracy
                    val fiveMinutesAgo = System.currentTimeMillis() - 5 * 60 * 1000
                    if (lastLoc.time > fiveMinutesAgo && lastLoc.accuracy <= 20) {
                        mLocation = lastLoc
                    } else {
                        Log.w(TAG, "Ignoring outdated or low-accuracy last location")
                    }
                } else {
                    Log.w(TAG, "Failed to get location.")
                }
            }
    } catch (unlikely: SecurityException) {
        Log.e(TAG, "Lost location permission.$unlikely")
    }
}

5. Ensure proper permissions and device settings

  • Double-check that you’re requesting ACCESS_FINE_LOCATION (not just ACCESS_COARSE_LOCATION) in your manifest and runtime permissions—high-accuracy GPS requires this.
  • Prompt users to enable High Accuracy mode in their device settings (this combines GPS, Wi-Fi, and cellular data for more stable readings).

These changes should drastically reduce those frustrating distance spikes and give your users a more reliable experience.

内容的提问来源于stack exchange,提问作者J. Shiv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:14:56