61

I want to check when the network of phone in Android goes off. Can I capture that event?

I am not getting the proper API or any example which would explain the same. If anyone had done or any example links would be really helpful.

Kara
  • 6,115
  • 16
  • 50
  • 57
Sam97305421562
  • 3,027
  • 10
  • 35
  • 45

4 Answers4

147

New java class:

public class ConnectionChangeReceiver extends BroadcastReceiver
{
  @Override
  public void onReceive( Context context, Intent intent )
  {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
    NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
    NetworkInfo mobNetInfo = connectivityManager.getNetworkInfo(     ConnectivityManager.TYPE_MOBILE );
    if ( activeNetInfo != null )
    {
      Toast.makeText( context, "Active Network Type : " + activeNetInfo.getTypeName(), Toast.LENGTH_SHORT ).show();
    }
    if( mobNetInfo != null )
    {
      Toast.makeText( context, "Mobile Network Type : " + mobNetInfo.getTypeName(), Toast.LENGTH_SHORT ).show();
    }
  }
}

New xml in your AndroidManifest.xml under the "manifest" element:

<!-- Needed to check when the network connection changes -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

New xml in your AndroidManifest.xml under the "application" element:

<receiver android:name="com.blackboard.androidtest.receiver.ConnectionChangeReceiver"
          android:label="NetworkConnection">
  <intent-filter>
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
  </intent-filter>
</receiver>
Eric
  • 5,323
  • 6
  • 30
  • 35
  • as @noillusioin says, the activeNetInfo can be null. This is an indication that the network connection JUST DISCONNECTED if you know (save state) that you were connected previously. – larham1 Apr 18 '13 at 21:10
  • @Eric is there any alternate for getNetworkInfo?? Because its deprecated. – MashukKhan Sep 26 '16 at 06:06
  • @MashukKhan it's....literally right there in the javadoc: "This method was deprecated in API level 23. This method does not support multiple connected networks of the same type. Use getAllNetworks() and getNetworkInfo(android.net.Network) instead." – Eric Sep 26 '16 at 18:37
  • 2
    Beginning with Android 7.0, you can't set `CONNECTIVITY_CHANGE` in your Manifest. You need to do that dynamically. – CopsOnRoad Mar 13 '18 at 18:20
18

I have been using a small setup to check the bandwidth for determining how to scale things, such as images.

Under the activity, in AndroidManifest:

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

In the activity where the checks are being performed:

boolean network;
int bandwidth;

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    network = isDataConnected();
    bandwidth = isHighBandwidth();
    registerReceiver(new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            network = isDataConnected();
            bandwidth = isHighBandwidth();
        }
    }, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
    ...
}
...
private boolean isDataConnected() {
    try {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo().isConnectedOrConnecting();
    } catch (Exception e) {
        return false;
    }
}

private int isHighBandwidth() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = cm.getActiveNetworkInfo();
    if (info.getType() == ConnectivityManager.TYPE_WIFI) {
        WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        return wm.getConnectionInfo().getLinkSpeed();
    } else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
        TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        return tm.getNetworkType();
    }
    return 0;
}

An example usage would then be:

if (network) {
    if (bandwidth > 16) {
        // Code for large items
    } else if (bandwidth <= 16 && bandwidth > 8) {
        // Code for medium items
    } else {
        //Code for small items
    }
} else {
    //Code for disconnected
}

It's not the prettiest, but it allows enough flexibility that I can change the bandwidth cutoff for items depending on what they are and my requirements for them.

Abandoned Cart
  • 4,512
  • 1
  • 34
  • 41
11

If using Android Annotations is an option for you try this in your activities - that's all, the rest is generated:

@Receiver(actions = ConnectivityManager.CONNECTIVITY_ACTION,
        registerAt = Receiver.RegisterAt.OnResumeOnPause)
void onConnectivityChange() {
    //react
}

Use this only if you already use AndroidAnnotations - putting this dependency inside your project only for this piece of code would be overkill.

luckyhandler
  • 10,651
  • 3
  • 47
  • 64
  • Can you please put more explanations about this answer. I have tried to find something but I couldn't. There is not @Receiver annotation in google annotation library. Thanks! – Stoycho Andreev Feb 10 '16 at 07:39
  • Hey, I refer to the 3rd party library AndroidAnnotations. I update my answer. – luckyhandler Feb 11 '16 at 18:49
  • Yes you right, with this library it is possible and also I found this https://github.com/jd-alexander/flender check it not bad, but you can use it only with gradle build 1.3, with the new build gradle plugins does not work – Stoycho Andreev Feb 11 '16 at 21:36
9

The above answer only works if mobile packet data is enabled. Otherwise, ConnectivityManager would be null and you can no longer retrieve NetworkInfo. The way around it is to use a PhoneStateListener or TelephonyManager instead.

noillusion
  • 163
  • 2
  • 5