LocationManager.PROVIDERS_CHANGED_ACTION不适用于API 26及更高版本

Gun*_*lan 14 android broadcastreceiver

我正在使用以下代码来获取位置开/关事件.

<receiver
    android:name=".receivers.GpsReceiver"
    android:enabled="true">
    <intent-filter>
        <action android:name="android.location.PROVIDERS_CHANGED" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)

我正在开发基于地理围栏的应用程序.基于仅在需要时重新注册地理围栏,我们必须在应用程序收到GEOFENCE_NOT_AVAILABLE警报后重新注册地理围栏.这通常发生在禁用NLP(Android的网络位置提供程序)之后.

通过使用此广播接收器,我在启用Android的网络位置提供程序时重新注册了地理围栏.

但是从API级别26开始,这个广播接收器永远不会工作.请参阅 后台执行限制.

那么如何在API 26及更高版本中实现相同的任务呢?

注意:即使app在后台,我也需要重新注册地理围栏.

小智 5

正如您链接的文章中提到的,Android API 26 无法监听隐式广播,例如

<action android:name="android.location.PROVIDERS_CHANGED" />

如果应用程序被终止或当前不在后台运行。您唯一能做的就是在运行时注册广播接收器,如迁移指南中所述。

我所做的是在onCreate 中的应用程序类中调用registerReceiver并在onTerminate 中取消注册它。

class MyApplication : Application() {
  private val gpsReceiver = MyBroadcastReceiver()

  override fun onCreate() {
    super.onCreate()
    registerReceiver(gpsReceiver, IntentFilter("android.location.PROVIDERS_CHANGED"))
  }

  override fun onTerminate() {
    super.onTerminate()
    unregisterReceiver(gpsReceiver)
  }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助您!


art*_*nig 5

您可以切换到动态注册您的接收器Context.registerReceiver(),但恕我直言,没有可靠的方法让他们"永远"注册,因为系统将在某些条件下终止您的过程.

当然,你可以通过使用如重新注册这些白名单广播接收机,AlarmManager,JobScheduler等等.但是,这是不是在电池和其他资源消耗方面的最佳途径.实际上这就是谷歌禁用隐式广播的原因.

重点是:通过禁用Oreo中的隐式广播,Google会强制您使用某种重复性作业来执行此类操作.因此,您不需要监听NLP状态更新,只需GeofencingClient.addGeofences在您的定期作业中反复设置地理围栏(如果已启用NLP).