How to receive PROVIDERS_CHANGED broadcast in Android Oreo

Viewed 1277

Apps handle GeoFence needs to receive PROVIDERS_CHANGED broadcast since:

  1. Registered GeoFences will be removed when both 2 location providers (network and GPS) are turned off.
  2. When one of 2 location providers is turned on, app needs to register GeoFences to work. This should be performed w/o asking user to run my app again.

So my app has been registering its broadcast receiver in manifest. But it does not work any more in Android Oreo since PROVIDERS_CHANGED is not one we can make it work as before.

I can register broadcast receiver for that in app's activity or in service but it will quit (end its life cycle) sooner or later, then I need to unregister it. My app starts working by some events like GeoFence transition, but receiving PROVIDERS_CHANGED is critical to make it work.

I verified PROVIDERS_CHANGED can't be received by receiver registered in manifest in Android Oreo. Is there any solution for it?

1 Answers

@Tomcat and @Virat18 - I've come across a solution to the fact that you can no longer register a Broadcast Receiver in your Manifest to receive the PROVIDERS_CHANGED action Intent-filter in Android-OREO..

The solution? Simply register your BroadcastReceiver dynamically (from within your code), instead of from the Manifest.. Also, instead of checking for the hard-coded regex android.location.PROVIDERS_CHANGED, you should use LocationManager.PROVIDERS_CHANGED_ACTION (and of course import the LocationManager).

Here is an example of the Code I used to get this to work! (ex: from a Button Click):

public void buttonClick(View view) {

    IntentFilter filter = new IntentFilter();
    filter.addAction("android.location.PROVIDERS_CHANGED");

    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().matches(LocationManager.PROVIDERS_CHANGED_ACTION)) {
                Log.i(TAG, "Action MATCHES LocationManager.PROVIDERS_CHANGED_ACTION!");
            }
        }
    };

    this.getApplicationContext().registerReceiver(receiver, filter);
    Log.i(TAG, "RECEIVER HAS BEEN REGISTERED");

}

Also, don't forget to unregister the receiver in your code appropriately.

If you find this to be a good solution, please accept it as the Answer.
Happy Coding!

PS. This will continue to receive the broadcast from the background, even once the User leaves your Activity (presses the back-button, home-button, etc).. However, if the user closes your App from the Multitask button, it will no longer receive, so take note of that.

Related