Monday, October 9, 2017

Android - Programmatically Register System Broadcast Receiver at Runtime

The Problem - Registering connectivity change when targeting API 24+


Not all Android Broadcasts are created equally and you can't create them in the manifest in all cases. There are some you must configure at runtime because of changes Google made to apps targeting N (API 24).

From the documentation: Apps targeting Android 7.0 (API level 24) and higher do not receive CONNECTIVITY_ACTION broadcasts if they declare their broadcast receiver in the manifest.

The Solution


The docs are not as clear how to handle this, so here is the code to allow your app to still receive connectivity change broadcasts after targeting N or later:

public void onCreate() {
    ...
    //Change 'YourConnectionChangedBroadcastReceiver' to the class defined to handle the broadcast in your app
    registerReceiver(new YourConnectionChangedBroadcastReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    ...
}

I'd also recommend removing the declaration from AndroidManifest.xml as if you leave it in there, it will actually create multiple instances of your broadcast receiver.

        <receiver android:name="YourConnectionChangedBroadcastReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>


Registering it programmatically unlocks the receiver for use by your app (including those for CONNECTIVITY_ACTION in your manifest), and that's all there is to it. You can save the registered receiver instance and unregister it when no longer needed, however, this is not necessary if it lasts the entire lifetime of your application.