744

Possible Duplicate:
How to check internet access on Android? InetAddress never timeouts

I need to detect whether the Android device is connected to the Internet.

The NetworkInfo class provides a non-static method isAvailable() that sounds perfect.

Problem is that:

NetworkInfo ni = new NetworkInfo();
if (!ni.isAvailable()) {
    // do something
}

throws this error:

The constructor NetworkInfo is not visible.

Safe bet is there is another class that returns a NetworkInfo object. But I don't know which.

  1. How to get the above snippet of code to work?
  2. How could I have found myself the information I needed in the online documentation?
  3. Can you suggest a better way for this type of detection?
Ryan M
  • 18,333
  • 31
  • 67
  • 74
Dan
  • 15,948
  • 20
  • 63
  • 92
  • 6
    [This][1] might help as well [1]: http://stackoverflow.com/questions/6179906/detecting-when-device-goes-from-network-to-no-network – anargund Jul 15 '11 at 21:58
  • 2
    Article on android.com: [Determining and Monitoring the Connectivity Status](http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html) – Alexander Malakhov Oct 15 '13 at 06:17
  • 2
    None of the answers here actually answer the question of checking if there is a connection to the internet, only if you are connected to a network at all. See this answer for an example of just trying to make an outgoing TCP connection to test this: http://stackoverflow.com/a/35647792/1820510 – Xiv Feb 26 '16 at 09:33
  • For anyone looking at this in 2020: https://teamtreehouse.com/community/what-can-getactivenetworkinfo-be-replaced-with-since-it-was-deprecated-in-api-29 – VladimirVip Jun 10 '20 at 12:07
  • https://stackoverflow.com/a/54957599/10632772 – Asfar Hussain Siddiqui Dec 09 '22 at 10:25

6 Answers6

1491

The getActiveNetworkInfo() method of ConnectivityManager returns a NetworkInfo instance representing the first connected network interface it can find or null if none of the interfaces are connected. Checking if this method returns null should be enough to tell if an internet connection is available or not.

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
          = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager != null ? connectivityManager.getActiveNetworkInfo() : null;
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

You will also need:

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

in your android manifest.

Edit:

Note that having an active network interface doesn't guarantee that a particular networked service is available. Network issues, server downtime, low signal, captive portals, content filters and the like can all prevent your app from reaching a server. For instance you can't tell for sure if your app can reach Twitter until you receive a valid response from the Twitter service.

m.sajjad.s
  • 711
  • 7
  • 19
Alex Jasmin
  • 39,094
  • 7
  • 77
  • 67
  • 7
    It it worth to take a look at [connectiontimeout](http://stackoverflow.com/questions/693997/how-to-set-httpresponse-timeout-for-android-in-java/1565243#1565243) if somebody (unnecessarily) try call this function before making http call! :-) – Vikas Aug 04 '11 at 06:19
  • 144
    To be safe I would `return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();` – Jeff Axelrod May 26 '12 at 16:38
  • 1
    From [the documentation of getActiveNetworkInfo()](http://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()): `When connected, this network is the default route for outgoing connections. You should always check isConnected() before initiating network traffic.`, so do as @JeffAxelrod suggests, perhaps using `isConnected()` instead of `isConnectedOrConnecting()`. – Eric Simonton Feb 14 '13 at 22:05
  • I'm getting the error "connectivityManager cannot be resolved". Any idea of how should I fix this? – arod Jun 10 '13 at 02:58
  • 20
    If you are creating a `Utils` method i.e. not accessing this from where `Context` reference is available, you'll need to pass `Context` as an argument. – Mahendra Liya Jun 11 '13 at 09:19
  • 1
    Note: If you don't have the required permission, this seems to block your code instead of throwing an error. At least, I never saw an error, and the code never advanced beyond what was requested. – PearsonArtPhoto Oct 24 '13 at 21:39
  • 2
    @JeffAxelrod, I guess you added the "!= null", the "isConnectedOrConnecting" is not correct, as we want to know if we've internet connection, and while connecting, we do not have internet connection. – Reinherd Jan 29 '14 at 09:09
  • 39
    This does not check if the phone is connected to the internet. Only that a network connection has been made. – miguel Jan 31 '14 at 02:02
  • this crashes my phone. does this still works in June 2014 ? – Francisco Corrales Morales Jun 03 '14 at 23:41
  • @AlexandreJasmin Does it checking 3G, GPRS,EDGE,... too? – Dr.jacky Jul 07 '14 at 12:33
  • 28
    @Mr.Hyde Unfortunately, no. This way is checking only if a network connection has been made, but does not check that device is connected to the internet. To really know about active internet connection, you should to use HttpURLConnection to some host, ping some host (e.g. google.com) or try to use InetAddress.getByName(hostName).isReachable(timeOut) – Dimon Aug 13 '14 at 14:10
  • does it work for wifi? – Muhammad Babar Nov 24 '14 at 11:28
  • 4
    it returns `true` even there is no connection available – Thamaraiselvam Feb 08 '15 at 15:26
  • This code is good everywhere except 4.3. You need to do an actual ping for 4.3 as this always returns true. – ngatirauks Feb 11 '15 at 01:24
  • @ngatirauks Using a samsung galaxy s3 on 4.3 I do not have this issue – Jacob Raihle Apr 16 '15 at 18:55
  • 4
    I did a simple test. I pulled out the input ethernet cable from my router and then called this method. So the device was connected to WI-Fi but the Wifi itself was not connected to internet. Guess what! Even then it returned true. So if I want to make sure that device is connected to internet I would ping a well known website rather than checking this. – shshnk Mar 15 '16 at 07:40
  • 6
    i tested this and it will give a false positive in case you have wifi but no internet connection. this answer seems to be misleading. – tony gil Oct 03 '16 at 21:05
  • But it returns connected even though there is no internet connection from the wifi, Is it really need to ping the web site ?? – Rohith Krishnan Jul 05 '17 at 05:26
  • 3
    connectivityManager is not enough, to know if you have internet access, you have to test it ! The best answer for that is : https://stackoverflow.com/a/27312494/968538 – Christian Oct 11 '17 at 10:02
  • 2
    @JeffAxelrod `isConnectedOrConnecting()` is deprecated in API level 28. – amrezzd Aug 27 '18 at 07:09
  • this is bad, it returns false when turned off my wifi but had mobile net enabled, only after a couple of seconds if started to return true – user155 Mar 24 '19 at 19:07
  • It does not answer, what is asked in the question. I wonder why it has so many upvotes. – Wajid Nov 04 '19 at 12:54
  • Deprecated in API 29 – Karol Wasowski Nov 06 '19 at 09:48
  • 2
    Deprecated in API 29 – Alok Gupta Jan 09 '20 at 08:39
  • For anyone getting deprecation issues in API 29 use the following code that is in Kotlin `class NetworkAvailability { @Suppress("DEPRECATION") fun isInternetAvailable(context: Context): Boolean { var result = false val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager? val activeNetworkInfo: NetworkInfo = cm!!.getActiveNetworkInfo() return activeNetworkInfo != null && activeNetworkInfo.isConnected } }` – dave o grady Jan 15 '20 at 01:48
  • Pixel 3, API 30: if I set device language to simplified mandarin (mainland China), often connectivityManager.getActiveNetwork will never return when airplane mode is on. Changing to English and rerunning may see that resolve and afterwards one can see it return even when back on that mainland China setting. – straya Dec 16 '20 at 09:51
  • 3
    @daveogrady All that does is suppress the warning. – paul_f Apr 16 '21 at 16:18
261

I check for both Wi-fi and Mobile internet as follows...

private boolean haveNetworkConnection() {
    boolean haveConnectedWifi = false;
    boolean haveConnectedMobile = false;

    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo[] netInfo = cm.getAllNetworkInfo();
    for (NetworkInfo ni : netInfo) {
        if (ni.getTypeName().equalsIgnoreCase("WIFI"))
            if (ni.isConnected())
                haveConnectedWifi = true;
        if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
            if (ni.isConnected())
                haveConnectedMobile = true;
    }
    return haveConnectedWifi || haveConnectedMobile;
}

Obviously, It could easily be modified to check for individual specific connection types, e.g., if your app needs the potentially higher speeds of Wi-fi to work correctly etc.

Squonk
  • 48,735
  • 19
  • 103
  • 135
  • 28
    The code is good, I just wish people would stick to Java coding style when writing java haveConnectedWifi, haveConnectedMobile. I know it's a small thing, but consistent code is more readable. – Stuart Axon Dec 09 '10 at 16:37
  • 6
    While on good practice it's better to have the String on the left and not use equalsIgnoreCase if you don't have to: if ("WIFI".equals(ni.getTypeName())) – Stuart Axon Dec 09 '10 at 16:45
  • 80
    @Stuart Axon: Oh well, that's just how it goes I suppose. I've programmed more languages than I can remember since I started back in the late 1970's and I've obviously picked up many bad habits. In general I go on the principle that if it works then...well, it works and that's all I care about. The code snippet above is completely self-contained and it's easy for anybody with reasonable programming experience to work out and (most importantly) if someone were to cut and paste it into their own code it would work for them. Sorry for being an Android/Java noob. – Squonk Dec 10 '10 at 07:09
  • 3
    Wasn't after points or anything (or however SO works) - I found the code useful, but I guess in my grumpy way was trying to give some semi helpful feedback. – Stuart Axon Dec 13 '10 at 14:58
  • Why not using getType() instead of getTypeName()? – BoD Dec 15 '11 at 16:16
  • 4
    @BoD: `getType()` provides a finer level of granularity (I believe) and might return `TYPE_MOBILE`, `TYPE_MOBILE_DUN`, `TYPE_MOBILE_HIPRI` and so on. I'm not interested in the specifics of what type of 'mobile' connection is available and `getTypeName()` will simply return 'MOBILE' for all of them. – Squonk Dec 15 '11 at 18:20
  • This code cause error on tablets without sim. Is there any alternative code which tell us type of connection. – Ahmed Nawaz Nov 11 '13 at 05:14
  • @AhmedNawaz : It works fine on my Nexus 7 tablet and that doesn't have a SIM. – Squonk Nov 11 '13 at 07:27
  • 1
    this crashes my phone. does this still works in June 2014 ? – Francisco Corrales Morales Jun 03 '14 at 23:41
  • @FranciscoCorralesMorales : Yes. As it was working for me on my Nexus 7 in November 2013, what makes you think it wouldn't still be working now. If you have a problem, post your own Stack Overflow question with code and the logcat showing the crash stacktrace. Somebody will help you to find an answer. – Squonk Jun 04 '14 at 10:44
  • I had to add the Context, in `context.getSystemService` or it doesn't work. I got my clue here http://www.androidhive.info/2012/07/android-detect-internet-connection-status/ – Francisco Corrales Morales Jun 04 '14 at 15:52
  • So the accepted answer won't detect mobile internet access? – Ogen Jul 08 '14 at 08:37
  • @ogen : Yes it will but doesn't differentiate between different network types. In saying that, neither does my code and simply checks for mobile OR wifi - as long as one or other is connected then it returns true. I've since rewritten my code to include wired ethernet and also separated methods to allow checking for each type of network separately. – Squonk Jul 08 '14 at 09:12
  • This solution might be helpful, but what i missed there is when to run it. In other words, how to detect programmatically this state, where wifi is connected, but mobile data for internet is being used? – Mehmed Mert Jul 07 '15 at 15:51
  • dose it check for internet connection or just network connection. – shareef Dec 25 '15 at 19:57
  • 1
    `getAllNetworkInfo` has been depricated – Fizzix Mar 04 '16 at 23:37
  • Yes, it's deprecated - updated code is here -> http://stackoverflow.com/a/32771164/1012435 . – Xdg Jan 02 '17 at 14:52
80

Step 1: Create a class AppStatus in your project(you can give any other name also). Then please paste the given below lines into your code:

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;


public class AppStatus {

    private static AppStatus instance = new AppStatus();
    static Context context;
    ConnectivityManager connectivityManager;
    NetworkInfo wifiInfo, mobileInfo;
    boolean connected = false;

    public static AppStatus getInstance(Context ctx) {
        context = ctx.getApplicationContext();
        return instance;
    }

    public boolean isOnline() {
        try {
            connectivityManager = (ConnectivityManager) context
                        .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        connected = networkInfo != null && networkInfo.isAvailable() &&
                networkInfo.isConnected();
        return connected;


        } catch (Exception e) {
            System.out.println("CheckConnectivity Exception: " + e.getMessage());
            Log.v("connectivity", e.toString());
        }
        return connected;
    }
}

Step 2: Now to check if the your device has network connectivity then just add this code snippet where ever you want to check ...

if (AppStatus.getInstance(this).isOnline()) {

    Toast.makeText(this,"You are online!!!!",8000).show();

} else {

    Toast.makeText(this,"You are not online!!!!",8000).show();
    Log.v("Home", "############################You are not online!!!!");    
}
sagar
  • 379
  • 4
  • 13
Vivek Parihar
  • 2,318
  • 18
  • 18
  • 7
    do you really need to check `isAvailable` ? I would think `isConnected` is enough. – Alexander Malakhov Oct 19 '13 at 09:18
  • 1
    also if you pass the Context to the constructor why do you need to do that in isOnline? – Svetoslav Marinov Mar 30 '14 at 06:42
  • this crashes my phone. does this still works in June 2014 ? – Francisco Corrales Morales Jun 03 '14 at 23:42
  • 5
    @AlexanderMalakhov actually `isAvailable` should be the first check. I have found that if a connection interface is available, this is `true`. Sometimes (for example, when *'Restrict background data'* setting is enabled) `isConnected` can be `false` to mean that the interface has no active connection but `isAvailable` is true to mean the interface is available and you can establish a connection (for example, to transmit foreground data). – ADTC Aug 10 '14 at 14:18
  • 5
    I did a simple test. I pulled out the input ethernet cable from my router and then called this method. So the device was connected to WI-Fi but the Wifi itself was not connected to internet. Guess what! Even then it returned true. So if I want to make sure that device is connected to internet I would ping a well known website rather than checking this. – shshnk Mar 15 '16 at 07:51
  • I'm guessing the same would happen if the device is connected to mobile data network, but the provider just allows you to facebook, whatsapp, etc. but not other sites. These kind of validations just allow you to quickly tell the user he is not connected, rather than making he/she wait for a timeout. I say, both checks must be made: Data Connection Availability plus "Internet" availability. – Jahaziel Jul 07 '16 at 14:54
14

Also another important note. You have to set android.permission.ACCESS_NETWORK_STATE in your AndroidManifest.xml for this to work.

_ how could I have found myself the information I needed in the online documentation?

You just have to read the documentation the the classes properly enough and you'll find all answers you are looking for. Check out the documentation on ConnectivityManager. The description tells you what to do.

Octavian Helm
  • 39,405
  • 19
  • 98
  • 102
  • 12
    The description of the ConnectivityManager class tells me nothing about how to use the class, it's just a listing of method signatures and constant values. There's more info in the answers to this question than there is in that documentation. No mention of the fact that getActiveNetworkInfo() can return null, no mention of the need to have ACCESS_NETWORK_STATE permission, etc. Where exactly did you find this info, other than the Android source? – dfjacobs Dec 27 '10 at 05:32
  • 3
    Good point dfjacobs. Stackoverflow seems to be the goto source these days for lack of decent cookbook examples. – Steven Jan 04 '12 at 05:13
  • `Requires the ACCESS_NETWORK_STATE permission.` is stated [here](https://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()). – jk7 Aug 25 '17 at 17:47
12

The getActiveNetworkInfo() method of ConnectivityManager returns a NetworkInfo instance representing the first connected network interface it can find or null if none if the interfaces are connected. Checking if this method returns null should be enough to tell if an internet connection is available.

private boolean isNetworkAvailable() {
     ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
     return activeNetworkInfo != null; 
}

You will also need:

in your android manifest.

Edit:

Note that having an active network interface doesn't guarantee that a particular networked service is available. Networks issues, server downtime, low signal, captive portals, content filters and the like can all prevent your app from reaching a server. For instance you can't tell for sure if your app can reach Twitter until you receive a valid response from the Twitter service.

getActiveNetworkInfo() shouldn't never give null. I don't know what they were thinking when they came up with that. It should give you an object always.

Hanry
  • 5,481
  • 2
  • 40
  • 53
axllaruse
  • 139
  • 1
  • 2
10

Probably I have found myself:

ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
return connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting();
Ziem
  • 6,579
  • 8
  • 53
  • 86
Dan
  • 15,948
  • 20
  • 63
  • 92