How can I receive a notification when the device loses network connectivity?
Asked Answered
W

7

31

I know you can write code through which you can determine whether the device is connected to a network.

But in my app what I want to do is get a notification if the device changes its state from 'network' to 'no network'. This would happen, for example, when the user travels into a tunnel and loses signal, etc. Or when on WiFi, the user goes out of range of the access point and no longer has access to the internet.

Does the Android API provide something where you can register a listener so that you get notified every time there is a change in network state?

I found this code and tried to use it, but it does not do anything. I don't get any notifications when the network state changes.

public class ConnectivityManager extends PhoneStateListener{

Activity activity;
public ConnectivityManager(Activity a){
    TelephonyManager telephonyManager = (TelephonyManager)a.getSystemService(Context.TELEPHONY_SERVICE);
    telephonyManager.listen(this, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
    activity = a;
}

@Override
public void onDataConnectionStateChanged(int state) {
    super.onDataConnectionStateChanged(state);
    switch (state) {
    case TelephonyManager.DATA_DISCONNECTED:
        new AlertDialog.Builder(activity).
        setCancelable(false).
        setTitle("Connection Manager").
        setMessage("There is no network connection. Please connect to internet and start again.").
        setNeutralButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                System.exit(0);
            }
        }).create();
        break;

    case TelephonyManager.DATA_CONNECTED:
        break;
    }
}
}

Also, I have added the appropriate permissions in AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
Watt answered 30/5, 2011 at 19:7 Comment(1)
For more recent versions of Android (API >= 24) checkout this answer.Massimo
R
16
myTelephonyManager=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

callStateListener = new PhoneStateListener(){
    public void onDataConnectionStateChanged(int state){
        switch(state){
        case TelephonyManager.DATA_DISCONNECTED:
            Log.i("State: ", "Offline");
            // String stateString = "Offline";
            // Toast.makeText(getApplicationContext(),
            // stateString, Toast.LENGTH_LONG).show();
            break;
        case TelephonyManager.DATA_SUSPENDED:
            Log.i("State: ", "IDLE");
            // stateString = "Idle";
            // Toast.makeText(getApplicationContext(),
            // stateString, Toast.LENGTH_LONG).show();
            break;
        }
    }       
};                      
myTelephonyManager.listen(callStateListener,
            PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); 
Rankin answered 15/8, 2011 at 11:57 Comment(3)
Note: You can stop listening by calling listen again passing "LISTEN_NONE"; see: groups.google.com/forum/?fromgroups=#!topic/android-beginners/…Chrysa
How is TelephonyManager connected with the Wifi status updates. Does this really work for wifi and other 3g internet too ?Optical
This didn't work for me on my tablet which was connected to WiFi. When I change to Airplane mode - I receive no notifications!Electroplate
G
25

You might want to consider using a BroadcastReceiver for ConnectivityManager.CONNECTIVITY_ACTION instead. From the docs:

A change in network connectivity has occurred. A connection has either been established or lost. The NetworkInfo for the affected network is sent as an extra; it should be consulted to see what kind of connectivity event occurred.

This receiver works for both WiFi and cellular data connectivity, unlike PhoneStateListener.LISTEN_DATA_CONNECTION_STATE, which will only notify you for changes in cellular networks.

Glutamine answered 30/5, 2011 at 19:18 Comment(8)
I believe the correct receiver is ConnectivityManager.CONNECTIVITY_ACTION.Codi
Well, yeah, either works. That's a string constant that equals what I posted. I just couldn't remember the constant name.Glutamine
Ah yes, I now see that in the very link I posted. Then we're completely on the same page!Codi
@PaulLammertsma that link is now 404Logogriph
@dwnz Odd that Google took it offline. The video can still be found on YouTube. Slides are still online here (PDF warning).Codi
Imagine we have WiFi activated and running. How could we capture "Mobile Data" state changes? (enable/disable). In the way mentioned on the accepted answer it does not get anything, and neither with ConnectivityManager.CONNECTIVITY_ACTION broadcast listeners.Cobwebby
@Cobwebby I haven't tried that, but it sounds like a separate question. My reading of the OP was that they primarily wanted to know when they went from "data" to "no data", regardless of what protocol was used.Glutamine
this only works with wifi, but mobile data i tried to no avail.Aegyptus
R
16
myTelephonyManager=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

callStateListener = new PhoneStateListener(){
    public void onDataConnectionStateChanged(int state){
        switch(state){
        case TelephonyManager.DATA_DISCONNECTED:
            Log.i("State: ", "Offline");
            // String stateString = "Offline";
            // Toast.makeText(getApplicationContext(),
            // stateString, Toast.LENGTH_LONG).show();
            break;
        case TelephonyManager.DATA_SUSPENDED:
            Log.i("State: ", "IDLE");
            // stateString = "Idle";
            // Toast.makeText(getApplicationContext(),
            // stateString, Toast.LENGTH_LONG).show();
            break;
        }
    }       
};                      
myTelephonyManager.listen(callStateListener,
            PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); 
Rankin answered 15/8, 2011 at 11:57 Comment(3)
Note: You can stop listening by calling listen again passing "LISTEN_NONE"; see: groups.google.com/forum/?fromgroups=#!topic/android-beginners/…Chrysa
How is TelephonyManager connected with the Wifi status updates. Does this really work for wifi and other 3g internet too ?Optical
This didn't work for me on my tablet which was connected to WiFi. When I change to Airplane mode - I receive no notifications!Electroplate
E
9

The accepted answer didn't work for me (my tablet was connected to WiFi - no 3G). The following code worked for me:

public class ConnectivityChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("*** Action: " + intent.getAction());
        if(intent.getAction().equalsIgnoreCase("android.net.conn.CONNECTIVITY_CHANGE")) {
            Toast.makeText(context, "Connection changed", Toast.LENGTH_SHORT).show();
        }
    }
}

and the change to AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<receiver android:name=".custom.ConnectivityChangeReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
</receiver>
Electroplate answered 21/5, 2015 at 7:40 Comment(0)
G
1

Not sure if this will help but this looks similar...

Grin answered 30/5, 2011 at 19:18 Comment(2)
I think that question is on similar lines, just that I want to know when device goes from 'internet connection' to 'no internet connection'. It does not matter to me if its on WiFi or 3G network. But will look into it. ThanksWatt
Similar but not the same question.Durban
D
1

I implemented this feature by polling ConnectivityManager.

_connectivityManager = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);

Once we have a connectivity manager just poll it every now and then to see if you are still connected

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Runnable networkStatusChecker = new Runnable() {
    public void run() {
        NetworkInfo activeNetwork = _connectivityManager.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        if(!isConnected) {
            System.out.println("disconnected from network");
            networkCheckerHandle.cancel(true);
        }
    }
};
final ScheduledFuture networkCheckerHandle = scheduler.scheduleAtFixedRate(networkStatusChecker, 10, 10, SECONDS);
Dasher answered 17/2, 2016 at 2:43 Comment(2)
Why do you think using the ConnectivityManager.CONNECTIVITY_ACTION requires API level 21 or higher? According to the docs, this was added in API level 1.Dogface
Seems like you are correct, not sure where I got API level 21 from. Thank you for pointing it outDasher
H
0

If you are trying to do that in Kotlin. Use this

   val isInternetWorking: Boolean by lazy {
        var success = false
        try {
            val url = URL("https://google.com")
            val connection = url.openConnection() as HttpURLConnection
            connection.connectTimeout = 10000
            connection.connect()
            success = connection.responseCode === 200
        } catch (e: IOException) {
            e.printStackTrace()
        }

        return@lazy success
    }

Do this in a thread.

Higher answered 26/2, 2019 at 7:54 Comment(0)
K
0

You can easily use Merlin and his beard. Here you can also get a type of connection: mobile or wifi.

implementation 'com.novoda:merlin:1.2.0'

private MerlinsBeard merlinsBeard;

private NetworkChecker(Context context){

    Merlin merlin = new Merlin.Builder()
            .withConnectableCallbacks()
            .withDisconnectableCallbacks()
            .build(context);

    merlinsBeard = new MerlinsBeard.Builder().build(context);

    merlin.registerConnectable(() -> {
        Timber.d("Connection enabled");
    });

    merlin.registerDisconnectable(() -> {
        Timber.d("Connection disabled");
    });

    merlin.bind();
}


public boolean getConnected(){
    return merlinsBeard.isConnected();
}
Ky answered 2/7, 2019 at 13:54 Comment(1)
i want to check if internet is connected or not then shared pref used for this purpose how i can do it i am new i dont know all method and procedure about itAma

© 2022 - 2024 — McMap. All rights reserved.