19

I have defined a receiver in a sandbox Android N application:

<receiver
    android:exported="true"
    android:name="com.sandboxapplication.NetworkReceiver">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

It's rather simple:

public class NetworkReceiver extends BroadcastReceiver {
    private static final String TAG = NetworkReceiver.class.getName();
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "Received Network Change event.");
    }
}

This receiver is working fine if in my build.gradle file my targetSdkVersion is 23. However, if I set my targetSdkVersion to 24, the receiver never receives anything. In fact if I place a debug break point in my receiver Android Studio gives me the visual indication that it looks like the class is never even loaded into memory.

Did I miss something very basic in the Android N documentation? Is there a new way to detect connectivity change events?

Floern
  • 33,559
  • 24
  • 104
  • 119
DanMD
  • 287
  • 1
  • 3
  • 8
  • Possible duplicate of [ConnectivityManager.CONNECTIVITY\_ACTION deprecated](https://stackoverflow.com/questions/36421930/connectivitymanager-connectivity-action-deprecated) – rds Sep 03 '18 at 16:21

3 Answers3

25

Use this code to register receiver in your Activity or in Application class

IntentFilter intentFilter = new IntentFilter(); 
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTI‌​ON); 
registerReceiver(new NetworkConnectionReceiver(), intentFilter); 

Where NetworkConnectionReceiver is a class extended by BroadcastReceiver. Just add this class in your app and perform action in onReceive(Context context, Intent intent) method.

Note: If you register this receiver in an Activity, don't forget to unregister it.

JJD
  • 50,076
  • 60
  • 203
  • 339
Ambar Jain
  • 508
  • 5
  • 11
  • In Nougat, Will the BroadcastReceiver triggers when the app is force closed ? – Priya Feb 05 '18 at 12:05
  • 1
    @Priya No, when the app is force closed the process is gone and everything registered in code is gone too. You should only listen to this broadcast when the app is in the foreground anyway. – BladeCoder Feb 22 '18 at 12:55
24

Apps targeting Android N (Nougat) do not receive CONNECTIVITY_ACTION broadcasts, even if they have manifest entries to request notification of these events. Apps that are running can still listen for CONNECTIVITY_CHANGE on their main thread if they request notification with a BroadcastReceiver.

To see what changed in Android N (Nougat). Please refer below link. Android N Behaviour Changes

Kalpesh Patel
  • 1,638
  • 1
  • 20
  • 35
  • Thank you so much, I knew I must have missed something very basic in the documentation... – DanMD Aug 22 '16 at 10:20
  • 4
    @DanMD That's probably because https://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION doesn't make the slightest effort to mention this... What a waste of time. – Daniel F Dec 04 '16 at 11:25
  • 3
    Working link: https://developer.android.com/about/versions/nougat/android-7.0-changes.html – rmtheis Dec 06 '16 at 00:36
  • Thanks for updating the link. – Kalpesh Patel Dec 31 '16 at 07:51
  • Is there a work around? What is the syntax to get the connectivity change via "registering BroadcastReceiver with Context.registerReceiver()" – Frank Zappa Apr 19 '17 at 01:48
  • 1
    @FrankZappa: Use this code to register receiver in your Activity or in Application class - IntentFilter intentFilter = new IntentFilter(); IntentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(new NetworkConnectionReceiver(), intentFilter); Note: If register this receiver in Activity, don't forget to unregister it. – Ambar Jain Apr 19 '17 at 10:25
  • Monitor for changes in connectivity Apps targeting Android 7.0 (API level 24) and higher do not receive CONNECTIVITY_ACTION broadcasts if they declare the broadcast receiver in their manifest. Apps will still receive CONNECTIVITY_ACTION broadcasts if they register their BroadcastReceiver with Context.registerReceiver() and that context is still valid. https://developer.android.com/training/monitoring-device-state/connectivity-monitoring – SChalice Apr 11 '19 at 17:35
3

Meanwhile ConnectivityManager.CONNECTIVITY_ACTI‌​ON was deprecated:

@deprecated 
apps should use the more versatile {@link #requestNetwork},
{@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback}
functions instead for faster and more detailed updates about the network
changes they care about.

So registerDefaultNetworkCallback should be used:

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
cm.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback(){
    @Override
    public void onAvailable(Network network) {
        doOnNetworkConnected();
    }
});
eleven
  • 6,779
  • 2
  • 32
  • 52
  • 1
    On adding this code it's saying "Call requires API level 24 (current min is 21)". What to write for lower api levels devices ? – Ambar Jain Mar 28 '19 at 23:44
  • @AmbarJain just use deprecated method. It will not be removed from old devices. – eleven Mar 29 '19 at 10:52
  • but this will only work if the app is run/running right? if the app is not running, there is no way. – chitgoks Nov 11 '19 at 04:05
  • ouch. tough luck. looks like there is no way to detect online/offline anymore. Sure, JobScheduler has constraints but only for CONNECTED network type. WorkManager's minimum periodic re-run is 15minutes (too long). – chitgoks Nov 11 '19 at 13:59