Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LocationManager.PROVIDERS_CHANGED_ACTION will not work on API 26 and higher

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.

like image 625
Gunaseelan Avatar asked Feb 07 '18 08:02

Gunaseelan


2 Answers

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.

like image 127
artkoenig Avatar answered Nov 14 '22 13:11

artkoenig


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!

like image 27
mlo Avatar answered Nov 14 '22 14:11

mlo