LocationManager.PROVIDERS_CHANGED_ACTION will not work on API 26 and higher
Asked Answered
D

3

22

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.

Depoliti answered 7/2, 2018 at 8:30 Comment(12)
This is a complicated issue due recent changes on API. Best answer I found is available hereHypothesis
Hi did you manage to find out the solution?Ferrosilicon
@k_kumar. No...Depoliti
@Depoliti please tell how did you achieved geofence thing ?Ferrosilicon
@Ferrosilicon I simply followed developer.android.com/training/location/geofencing to achieve geofence.Depoliti
@Depoliti can you please tell at what all instance I will get GEOFENCE_NOT_AVAILABLE signleFerrosilicon
@Ferrosilicon This typically happens after NLP (Android's Network Location Provider) is disabledDepoliti
@Depoliti Thanks for your reply. I wanted to know that is there any other time that we can get this GEOFENCE_NOT_AVAILABLE ? thanksFerrosilicon
@k_kumar, AFAIK only when we are switch off Location. And also I face GEOFENCE_NOT_AVAILABLE only I switch off Location.Depoliti
@Depoliti Thanks once again, I have many questions dont know I can askFerrosilicon
@Ferrosilicon You can bundle all your questions clearly with whats all you have tried in a separate question. And you will get more responses from more developers.Depoliti
@Depoliti Okay, ThanksFerrosilicon
G
7

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.

Gatling answered 15/2, 2018 at 12:0 Comment(1)
I know this is not the best solution, But its close to the solution. So I will add bounty to this solution. Thanks.Depoliti
A
5

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!

Administrator answered 12/2, 2018 at 15:33 Comment(5)
But this will work only in foreground. I need to check even app is in background also.Depoliti
This works also if the app is in background. Only if it's closed (swipping out of recent apps list) you cannot listen to PROVIDERS_CHANGED anymoreAdministrator
Only if it's closed (swipping out of recent apps list), the app considered as background my dear friend. Otherwise the app still in foreground.Depoliti
@Depoliti you will find the right definition of the foreground process hereGatling
onTerminate() This method is for use in emulated process environments.Eckard
L
1

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

Lubbi answered 20/2, 2018 at 7:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.