lor*_*nzo 7 android google-api
Google FusedLocationProviderApifor Android最近在过去几个月内被弃用,FusedLocationProviderClient作为其继任者,因此我最近更新了客户端应用中使用的位置API以使用新的API.
每次onLocationAvailability被触发时LocationCallback我都会在locationAvailability.isLocationAvailable()返回时通知用户false,但看起来这种情况比我在某些设备上预期的更频繁.我在前台内运行这些位置更新Service,这些位置更新保持一致至关重要.有没有办法确定这种失败的原因
在我看来,被弃用的API提供了对这些问题的更多洞察,因为它与它一起使用GoogleApiClient或者我可能缺少一些较小的细节.
我经历过同样的问题。经过三天的尝试后,我开始着手解决。
我还必须像你一样收集前台状态的位置,如果前台服务被破坏,我就必须取消注册。
我犯的第一个错误是不保证它removeLocationUpdates会在与requestLocationUpdates. 实际上,它不必是同一个线程,但是在 a 之后requestLocationUpdates,您必须调用removeLocationUpdates以使 nextrequestLocationUpdates有效。为了确保这一点,在同一个线程上工作要容易得多。
例如:
private fun FusedLocationProviderClient.requestLocation(
request: LocationRequest
): Single<LocationResult> {
return Single.create<LocationResult> { emitter ->
requestLocationUpdates(request, object : LocationCallback() {
override fun onLocationResult(result: LocationResult?) {
removeLocationUpdates(object : LocationCallback() {})
.addOnCompleteListener {
if (emitter.isDisposed) {
info("onLocationResult called after disposing.")
return@addOnCompleteListener
}
if (result != null && result.locations.isNotEmpty()) {
onSuccess(result)
} else {
onError(RuntimeException("Invalid location result"))
}
}
}
private fun onError(error: Exception) {
if (!emitter.isDisposed) {
emitter.onError(error)
}
}
private fun onSuccess(item: LocationResult) {
if (!emitter.isDisposed) {
emitter.onSuccess(item)
}
}
}, Looper.getMainLooper())
}
}
Run Code Online (Sandbox Code Playgroud)
正如代码所示,我已将 Single 吸引emitter到addOnCompleteListenerin以确保后面removeLocationUpdates的调用。当然,如果没有RxJava,实现起来会更容易。removeLocationUpdatesrequestLocationUpdates
我犯的第二个错误是错误的interval设置LocationRequest。根据文档:
此方法设置您的应用程序首选接收位置更新的速率(以毫秒为单位)。请注意,位置更新可能比此速率更快或更慢,以优化电池使用,或者可能根本没有更新(例如,如果设备没有连接)。
这个解释很不友善,但最终,如果你调用一次,你必须在下一个之前requestLocationUpdates触发一个位置更新事件。发现这个错误是最难的。intervalrequestLocationUpdates
我犯的第三个错误是LocationRequest中设置错误priority。在 API 10 及以下版本中,不是这样PRIORITY_BALANCED_POWER_ACCURACY,但通过使用PRIORITY_HIGH_ACCURACY. 本例中,我只在模拟器上进行了测试,因此实际设备可能会有不同的结果。我想PRIORITY_BALANCED_POWER_ACCURACY似乎无法正常工作,因为模拟器不提供蓝牙硬件。
所以我的LocationRequest看起来像:
LocationRequest.apply {
priority = PRIORITY_HIGH_ACCURACY
interval = 10000L
}
Run Code Online (Sandbox Code Playgroud)
希望我犯的三个错误及解决办法对您有所帮助!
正如谷歌文档所说:
当 isLocationAvailable() 返回 false 时,您可以假设在设备设置或环境发生更改之前,不会在 onLocationResult(LocationResult) 中返回位置。
因此,您可以假设位置可能不可用,不仅是因为位置设置被禁用,还因为信号强度,或者卫星不可见或其他原因,它只是表明在发生变化之前您不会收到位置更新。您可以向用户显示相关通知,例如“我们无法获取您的位置,请尝试启用位置设置”
| 归档时间: |
|
| 查看次数: |
1579 次 |
| 最近记录: |