LocationManager.PROVIDERS_CHANGED_ACTION will not work on API 26 and higher

混江龙づ霸主 提交于 2019-11-28 02:43:21

问题


I am using following code to get location on/off event.

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

I am developing geofence based app. Based on Re-register geofences only when required we have to re register the geofences after the app has received a GEOFENCE_NOT_AVAILABLE alert. This typically happens after NLP (Android's Network Location Provider) is disabled.

By using this broadcast receiver I re-registered the geofences when Android's Network Location Provider is enabled.

But from API level 26 this broadcast receiver will never work. See Background Execution Limits.

So how can I achieve the same task in API 26 and higher?

Note : I need to re-register the geofences even when app is in the background.


回答1:


You could switch to registering you receivers dynamically by Context.registerReceiver(), but IMHO there is no reliable way to get them registered "forever", because the system is going to terminate your process anyway on certain conditions.

Sure, you could re-register them by using e.g. white listed broadcast receivers, AlarmManager, JobScheduler etc. But this is not the best way in terms of battery and other resource consumption. Actually this is the reason, why Google disabled the implicit broadcasts.

The point is: By disabling implicit broadcasts in Oreo Google forces you to use some kind of recurring job to to do things like this. As the result, you don't need to listen for the NLP state updates, you just set your geofences with GeofencingClient.addGeofences (if NLP is enabled) in your recurring job over and over again.




回答2:


as mentioned in the article you've linked, there's no way on Android API 26 to listen to implicit broadcasts like

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

if the app is killed or isn't currently running in background. The only thing what you can do is to register the broadcast receiver on runtime, as stated in the migration guide.

What I did is calling registerReceiver in the application class in onCreate and unregister it in 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)
  }
}

Hopefully, this could help you!




回答3:


maybe you should try use background service and wakelock for long-running in the background when app closed/killed or screen off. it's works for me :)



来源:https://stackoverflow.com/questions/48659124/locationmanager-providers-changed-action-will-not-work-on-api-26-and-higher

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!