Detect whether there is an Internet connection available on Android [duplicate]
Asked Answered
G

6

746

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?
Gera answered 21/11, 2010 at 16:35 Comment(5)
[This][1] might help as well [1]: #6180406Berkelium
Article on android.com: Determining and Monitoring the Connectivity StatusGramicidin
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: https://mcmap.net/q/11827/-preferred-java-way-to-ping-an-http-url-for-availabilityEviscerate
For anyone looking at this in 2020: teamtreehouse.com/community/…Adit
https://mcmap.net/q/11456/-helper-class-best-approach-androidUnsuspecting
E
1492

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.

Elga answered 21/11, 2010 at 16:53 Comment(28)
It it worth to take a look at connectiontimeout if somebody (unnecessarily) try call this function before making http call! :-)Ricebird
To be safe I would return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();Revision
From the documentation of 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().Growth
I'm getting the error "connectivityManager cannot be resolved". Any idea of how should I fix this?Dkl
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.Vulturine
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.Mellow
@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.Courante
This does not check if the phone is connected to the internet. Only that a network connection has been made.Suffolk
this crashes my phone. does this still works in June 2014 ?Ethicize
@AlexandreJasmin Does it checking 3G, GPRS,EDGE,... too?Sarette
@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)Trimaran
does it work for wifi?Lutanist
it returns true even there is no connection availableDoreendorelia
This code is good everywhere except 4.3. You need to do an actual ping for 4.3 as this always returns true.Acanthus
@Acanthus Using a samsung galaxy s3 on 4.3 I do not have this issueSynonymy
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.Outspeak
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.Dolhenty
But it returns connected even though there is no internet connection from the wifi, Is it really need to ping the web site ??Atal
connectivityManager is not enough, to know if you have internet access, you have to test it ! The best answer for that is : https://mcmap.net/q/11339/-how-to-check-internet-access-on-android-inetaddress-never-times-outFlintlock
@JeffAxelrod isConnectedOrConnecting() is deprecated in API level 28.Eponymy
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 trueUnwritten
It does not answer, what is asked in the question. I wonder why it has so many upvotes.Longsuffering
Deprecated in API 29Botel
Deprecated in API 29Alethaalethea
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 } }Duplicator
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.Torchier
@daveogrady All that does is suppress the warning.Zitvaa
In case of Kotlin now I need to call val connectivityManager = getSystemService(requireContext(), ConnectivityManager::class.java) as ConnectivityManager Functionalism
C
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.

Christmastide answered 21/11, 2010 at 18:12 Comment(18)
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.Succubus
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()))Succubus
@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.Christmastide
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.Succubus
Why not using getType() instead of getTypeName()?Understandable
@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.Christmastide
This code cause error on tablets without sim. Is there any alternative code which tell us type of connection.Adamina
@AhmedNawaz : It works fine on my Nexus 7 tablet and that doesn't have a SIM.Christmastide
this crashes my phone. does this still works in June 2014 ?Ethicize
@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.Christmastide
I had to add the Context, in context.getSystemService or it doesn't work. I got my clue here androidhive.info/2012/07/…Ethicize
So the accepted answer won't detect mobile internet access?Hieratic
@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.Christmastide
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?Empathic
dose it check for internet connection or just network connection.Sensitometer
getAllNetworkInfo has been depricatedOttavia
Yes, it's deprecated - updated code is here -> https://mcmap.net/q/11760/-connectivitymanager-getnetworkinfo-int-deprecated .Tonsillectomy
Device connected to a WIFI network doesn't mean it has internet access!!! Same applies to mobile network.Cementite
M
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!!!!");    
}
Messenia answered 8/8, 2011 at 19:30 Comment(6)
do you really need to check isAvailable ? I would think isConnected is enough.Gramicidin
also if you pass the Context to the constructor why do you need to do that in isOnline?Saccharometer
this crashes my phone. does this still works in June 2014 ?Ethicize
@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).Spragens
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.Outspeak
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.Opponent
P
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.

Pokeberry answered 21/11, 2010 at 17:1 Comment(3)
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?Siu
Good point dfjacobs. Stackoverflow seems to be the goto source these days for lack of decent cookbook examples.Laic
Requires the ACCESS_NETWORK_STATE permission. is stated here.Maggs
L
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.

Lowell answered 20/8, 2011 at 14:3 Comment(1)
Why would you ever want it to return an object if there isn't a single active connection?Desiraedesire
G
10

Probably I have found myself:

ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
return connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting();
Gera answered 21/11, 2010 at 16:57 Comment(5)
Expect that getActiveNetworkInfo() can return null if there is no active network e.g. Airplane ModeElga
Yes it will return null and this is undocumented.Extremism
yes, so do a null check first activeNetwork != null && activeNetwork.isConnectedOrConnecting();Knowhow
I like this line: boolean isWifiConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting() && activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;Soberminded
Can anyone explain this line in more detail looks strange to me: first activeNetwork != nullAndra

© 2022 - 2024 — McMap. All rights reserved.