LocationAvailability无可用位置

lor*_*nzo 7 android google-api

Google FusedLocationProviderApifor Android最近在过去几个月内被弃用,FusedLocationProviderClient作为其继任者,因此我最近更新了客户端应用中使用的位置API以使用新的API.

每次onLocationAvailability被触发时LocationCallback我都会在locationAvailability.isLocationAvailable()返回时通知用户false,但看起来这种情况比我在某些设备上预期的更频繁.我在前台内运行这些位置更新Service,这些位置更新保持一致至关重要.有没有办法确定这种失败的原因

  1. 我们不会向最终用户表明任何误报
  2. 我们可以尝试解决问题,或者至少向最终用户报告他们应该做些什么?

在我看来,被弃用的API提供了对这些问题的更多洞察,因为它与它一起使用GoogleApiClient或者我可能缺少一些较小的细节.

poq*_*oqw 5

我经历过同样的问题。经过三天的尝试后,我开始着手解决。

我还必须像你一样收集前台状态的位置,如果前台服务被破坏,我就必须取消注册。

我犯的第一个错误是不保证它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 吸引emitteraddOnCompleteListenerin以确保后面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)

希望我犯的三个错误及解决办法对您有所帮助!


Wac*_*oon 1

正如谷歌文档所说:

当 isLocationAvailable() 返回 false 时,您可以假设在设备设置或环境发生更改之前,不会在 onLocationResult(LocationResult) 中返回位置。

因此,您可以假设位置可能不可用,不仅是因为位置设置被禁用,还因为信号强度,或者卫星不可见或其他原因,它只是表明在发生变化之前您不会收到位置更新。您可以向用户显示相关通知,例如“我们无法获取您的位置,请尝试启用位置设置”