You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

更新FusedLocationProviderClient后,开关GPS获取lastLocation始终为null求助

解决FusedLocationProviderClient重启GPS后lastLocation返回null的问题

嘿,我之前也踩过这个FusedLocationProvider的坑!你遇到的问题根源其实很明确:lastLocation 本质上是获取系统已经缓存的最近位置,当你关闭再重新开启GPS后,系统还没来得及获取新的位置数据,缓存是空的,自然就返回null了。而且你调用的flushLocations()只是把当前已有的缓存位置推送给监听器,并不能触发新的位置采集请求,所以帮不上忙。

下面给你两个靠谱的解决方案,根据你的业务场景选就行:

方案一:获取单次位置更新(适合只需要一次位置的场景)

如果你只需要拿到一次最新位置,用requestSingleUpdate来主动触发一次位置采集,而不是依赖缓存:

// 先定义你的LocationRequest(确保精度符合需求)
private fun getLocationRequest(): LocationRequest {
    return LocationRequest.create().apply {
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY // 高精度适配GPS刚开启的场景
        interval = 10000
        fastestInterval = 5000
    }
}

// 在位置设置成功的回调里替换原来的lastLocation逻辑
checkLocationSettings(callingActivity, turnOnGpsRequestCode, callback) {
    // 位置设置成功
    val locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult?.lastLocation?.let { location ->
                // 这里就能拿到最新的位置啦
                Log.d("Location", "获取到位置:${location.latitude}, ${location.longitude}")
            }
            // 记得用完移除回调,避免内存泄漏
            fusedLocationProviderClient.removeLocationUpdates(this)
        }
    }
    fusedLocationProviderClient.requestSingleUpdate(getLocationRequest(), locationCallback, Looper.getMainLooper())
}

方案二:注册持续位置监听(适合需要实时位置更新的场景)

如果你的业务需要持续获取位置变化,就注册一个长期的位置回调:

// 先定义全局的LocationCallback(方便后续移除)
private val locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult?) {
        locationResult?.lastLocation?.let { location ->
            // 处理每次更新的位置
            Log.d("Location", "实时位置:${location.latitude}, ${location.longitude}")
        }
    }
}

// 在位置设置成功后发起监听请求
checkLocationSettings(callingActivity, turnOnGpsRequestCode, callback) {
    fusedLocationProviderClient.requestLocationUpdates(getLocationRequest(), locationCallback, Looper.getMainLooper())
}

// 一定要在不需要的时候移除监听,比如在Activity的onDestroy里
override fun onDestroy() {
    super.onDestroy()
    fusedLocationProviderClient.removeLocationUpdates(locationCallback)
}

额外注意事项

  • 确保你已经申请了ACCESS_FINE_LOCATION权限,并且在运行时成功获取了用户授权(高精度定位需要这个权限)。
  • 如果不需要极高精度,可以把LocationRequest的优先级改成PRIORITY_BALANCED_POWER_ACCURACY,平衡功耗和精度。
  • 永远不要把lastLocation作为获取位置的唯一方式,它只适合快速获取之前缓存的位置,在GPS重启、首次打开、长时间未定位等场景下几乎都会返回null。

内容的提问来源于stack exchange,提问作者Jesus Almaral - Hackaprende

火山引擎 最新活动