更新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




