I'm using this code to be notified when the connection is lost in API 20 and down.
registerReceiver(getConnectivityStateBroadcastReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
private class ConnectivityStateBroadcastReceiver extends BaseBroadcastReceiver {
    /**
     * @param userLoggedIn
     * @param context
     * @param intent
     */
    @Override
    protected void onReceive(Boolean userLoggedIn, Context context, Intent intent) {
        Bundle extras = intent.getExtras();
        boolean notConnected = extras.getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
        // DO something
    }
}
but it's not working in API 21.
How can I fix that? maybe it's got to do with ConnectivityManager.NetworkCallbak but I didn't find any example to how to use it. Thanks.
OK, so I figure out how to do it but would appreciate confirmation that this solution is the right one.
All I did is add a call to this code in the onCreate of my application class
/**
 *
 */
@SuppressLint("NewApi")
private void registerConnectivityNetworkMonitorForAPI21AndUp() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        return;
    }
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder builder = new NetworkRequest.Builder();
    connectivityManager.registerNetworkCallback(
            builder.build(),
            new ConnectivityManager.NetworkCallback() {
                /**
                 * @param network
                 */
                @Override
                public void onAvailable(Network network) {
                    sendBroadcast(
                            getConnectivityIntent(false)
                    );
                }
                /**
                 * @param network
                 */
                @Override
                public void onLost(Network network) {
                    sendBroadcast(
                            getConnectivityIntent(true)
                    );
                }
            }
    );
}
 /**
 * @param noConnection
 * @return
 */
private Intent getConnectivityIntent(boolean noConnection) {
    Intent intent = new Intent();
    intent.setAction("mypackage.CONNECTIVITY_CHANGE");
    intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, noConnection);
    return intent;
}
and in the IntentFilter that already monitoring my connectivity for API 20 and less I added this
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction("mypackage.CONNECTIVITY_CHANGE");
and now my already working broadcast receiver get notification about network changes in API 21 too.
I'll paste my complete solution since I needed to look into many places in order to make it work:
In Application class
public void onCreate(){
...
IntentFilter filter = new IntentFilter();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Timber.d("using registerNetworkCallback");
        createChangeConnectivityMonitor();
        filter.addAction(MY_CONNECTIVITY_CHANGE);
    } else {
        Timber.d("using old broadcast receiver");
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    }
    registerReceiver(new SyncOnConnectivityReceiver(), filter);
 }
  @RequiresApi(Build.VERSION_CODES.N)
   private void createChangeConnectivityMonitor() {
    final Intent intent = new Intent(MY_CONNECTIVITY_CHANGE);
    ConnectivityManager connectivityManager = (ConnectivityManager) 
  getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        connectivityManager.registerNetworkCallback(
               new NetworkRequest.Builder().build(), 
               new ConnectivityManager.NetworkCallback() {
                    /**
                     * @param network
                     */
                    @Override
                    public void onAvailable(Network network) {
                        Timber.d("On available network");
                        sendBroadcast(intent);
                    }
                    /**
                     * @param network
                     */
                    @Override
                    public void onLost(Network network) {
                        Timber.d("On not available network");
                        sendBroadcast(intent);
                    }
                });
    }
}
In my receiver:
public class SyncOnConnectivityReceiver extends BroadcastReceiver {
@Override
 public void onReceive(@Nullable final Context context, Intent intent) {
    Timber.d("triggering on connectivity change");
    if (context != null && isNetworkAvailable(context)) {
        Executors.newSingleThreadExecutor().submit(new Runnable() {
            @Override
            public void run() {
                syncBusData(context);
            }
        });
    }
}
private boolean isNetworkAvailable(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (cm != null) {
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
    return false;
}
private void syncData(Context context) {
}
}
In AndroidManifiest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<receiver android:name="com.innofied.viapool.location.SyncOnConnectivityReceiver"/>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With