Detect if Android device has Internet connection
Asked Answered
R

17

149

I need to tell if my device has Internet connection or not. I found many answers like:

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

(Taken from Detect whether there is an Internet connection available on Android.)

But this is not right, for example if I'm connected to a wireless network which doesn't have Internet access, this method will return true… Is there a way to tell if the device has Internet connection and not if it is only connected to something?

Recrystallize answered 27/6, 2011 at 13:23 Comment(3)
Hey you can go with [this][1] as well. That might help! [1]: #4239421Halvorsen
possible duplicate of How to check internet access on Android? InetAddress never timeouts...Amoebocyte
The isNetworkConnected function block contains code deprecated for all Build.VERSION.SDK_INT >= Build.VERSION_CODES.M. A more in-depth discussion on the matter & how to fix it can be found here #53532906Ferren
F
188

You are right. The code you've provided only checks if there is a network connection. The best way to check if there is an active Internet connection is to try and connect to a known server via http.

public static boolean hasActiveInternetConnection(Context context) {
    if (isNetworkAvailable(context)) {
        try {
            HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
            urlc.setRequestProperty("User-Agent", "Test");
            urlc.setRequestProperty("Connection", "close");
            urlc.setConnectTimeout(1500); 
            urlc.connect();
            return (urlc.getResponseCode() == 200);
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error checking internet connection", e);
        }
    } else {
        Log.d(LOG_TAG, "No network available!");
    }
    return false;
}

Of course you can substitute the http://www.google.com URL for any other server you want to connect to, or a server you know has a good uptime.

As Tony Cho also pointed out in this comment below, make sure you don't run this code on the main thread, otherwise you'll get a NetworkOnMainThread exception (in Android 3.0 or later). Use an AsyncTask or Runnable instead.

If you want to use google.com you should look at Jeshurun's modification. In his answer he modified my code and made it a bit more efficient. If you connect to

HttpURLConnection urlc = (HttpURLConnection) 
            (new URL("http://clients3.google.com/generate_204")
            .openConnection());

and then check the responsecode for 204

return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0);

then you don't have to fetch the entire google home page first.

Frisky answered 27/6, 2011 at 13:29 Comment(31)
@varunbhardwaj you can just take a different website (e.g. baidu.com when deploying your app in China), or you can try a second site if the first one fails to make sure there is no connection.Frisky
i +1 your answer and know using it in my app, but there is be a big corner case of dependency on some website and my question still remain unanswered. anyways great workaround thanx.Dental
@Frisky How long should one wait for the server response?Blagoveshchensk
@blackcrow Depends on how long you/the users are willing to wait. Personally I consider 1000ms to be the lower limit, 6000ms about average and 15000ms long. But if the check is running in the background and the user is not waiting for it you can use much longer timeouts.Frisky
@Frisky +1 for answer. Do you have any basis(report/analysis) for your personal consideration?Blagoveshchensk
@Frisky What do you think about the method requestRouteToHost? Can it be an alternative for checking a known server over Http.Blagoveshchensk
@blackcrow the problem with requestRouteToHost is that it doesn't always work (see #8322981)Frisky
@CommonsWare Can you comment about requestRouteToHost here?Blagoveshchensk
@varunbhardwaj There should be some URI you can hit from your web services. The first thing we request when our app starts up is a bootstrap file that contains various configuration information, that allows us to change various parameters server-side. Something like that can be used.Krummhorn
Does it require any permission except INTERNET? I am getting exception.Postmillennialism
@AdilMalik Only Internet permisison is required.Frisky
Using google.com for testing internet connectivity is making an assumption that Google's servers are invincible. Better approach will be using some URL of your own web service like Steve suggested above.Vin
This should also be down on a background thread (whereas checking the ConnectivityManager does not require this). Otherwise, on Android 4.x+ devices, you will get a NetworkOnMainThread exception.Doug
Amazingly, but it still works even now, for android 4.4. It difficult to imagine something better than old school "ping". As I understood,the last android API still haven't some class/methods to resolve this issue?Jeanejeanelle
@Jeanejeanelle If you want to use ping you can use something like this: Process p = Runtime.getRuntime().exec("ping -c 1 " + host);, but I don't know how reliable it is. AFAIK it doesn't work in the emulator. More info and example code hereFrisky
Yes, but I found a problem and couldn't to resolve it. If connected to network with no access to the internet the exception is throwed only 40 seconds left - setConnectTimeout(1500); is fully ignored. What's the problem can be? The same behavior for "ping" - 26 seconds for exception, and if I use .isReachable(timeout) - 13 seconds. But this is too much for waiting about result that device has no active internet connection. What's wrong? What I need to do to solve it?Jeanejeanelle
@Jeanejeanelle This is a known issue if you are running it on the emulator (see also this answer). If you encounter this on a device, then I don't know.Frisky
@THelper, thanks for your help, but unfortunately it is not a simulator, a real devices - HTC One, Nexus 5.... I don't know what to doJeanejeanelle
@Jeanejeanelle Try searching stackoverflow or the internet for posts with the same problem. If you don't find anything you can always ask it as a new questionFrisky
@THelper, I found the solution that works properly. I used socket to connect, you know, the connection's timeout property works great. If there is an active internet connection - response 250 ms, if network has no internet connection - 30..40 ms response. I'm happy )Jeanejeanelle
I am trying this method with a Panasonic toughpad JT-B1 and when I am connected to a Wifi without internet access the timeout is very long (about 1 minute) instead of the set 1,5 seconds. Why does this happen ? EDIT: I will try the above solution posted by Dimon, let's see if it worksIvied
@Frisky In regards to the timeout issue that blackcrow mentioned, if I set a timeout of 15000, does that mean it will always take 15000 milliseconds to do the test, or that it will just give up at 15000 milliseconds? By keeping the timeout at 1500 milliseconds, is that essentially screening out users with very slow internet connections?Jaundiced
my app is crashed i debug the app crashing at "urlc.connect();" Error is android.os.NetworkOnMainThreadExceptionMelancholic
Url class doesn't exist?Bobine
You should update this answer with @Vaunting response, it improves this method. Anyway, thanksPice
what's User-Agent for?Carpentaria
I recommend using a descriptive user-agent for your app, this way the server owner (or yours) will be able to determine which requests from your app, in case it's needed.Disused
@varun bhardwaj Then they won't reach this answerProvisional
What is google is banned your IP address due to frequent API hit through some pattern?Blende
@ascii_walker please see this comment: #6494017Frisky
Okay. What is second one website blocked my IP. Try third one? and so on?Blende
V
98

I have modified THelper's answer slightly, to use a known hack that Android already uses to check if the connected WiFi network has Internet access. This is a lot more efficient over grabbing the entire Google home page. See here and here for more info.

public static boolean hasInternetAccess(Context context) {
    if (isNetworkAvailable(context)) {
        try {
            HttpURLConnection urlc = (HttpURLConnection) 
                (new URL("http://clients3.google.com/generate_204")
                .openConnection());
            urlc.setRequestProperty("User-Agent", "Android");
            urlc.setRequestProperty("Connection", "close");
            urlc.setConnectTimeout(1500); 
            urlc.connect();
            return (urlc.getResponseCode() == 204 &&
                        urlc.getContentLength() == 0);
        } catch (IOException e) {
            Log.e(TAG, "Error checking internet connection", e);
        }
    } else {
        Log.d(TAG, "No network available!");
    }
    return false;
}
Vaunting answered 12/9, 2014 at 20:9 Comment(12)
Hello, is it OK to use this practice in current apps?Yawning
Is this efficient in implementing in our current app?Esquire
It would be way more efficient than the method in the answer above. Grabbing the Google home page is very inefficient, especially if they happen to have a doodle on it.Vaunting
How do I call it from my activity? Thanks.Inearth
I recommend using a descriptive user-agent for your app, this way the server owner (or yours) will be able to determine which requests from your app, in case it's needed.Disused
You might want to use g.cn/generate_204 instead of clients3.google.com/generate_204 if you want to test connectivity in China as wellHeaviness
from tutorial itworkslocal.ly/…Prototrophic
You can simply create an unconnected Socket, use the method with the timeout parameter and you can basically connect to any TCP endpoint without knowing or the need to implement its protocol. Then once connected, set a a bolean flag to true, disconnect and return the flag.Declivitous
@Declivitous How will that work when the device is connected to a network that has say a captive portal? I would assume you would still be able to open a socket, but without speaking the (preferably secure) protocol and verifying the returned status code, you would have no idea if you connected to the host you intended to connect to or some mitm.Vaunting
@Vaunting The goal is to check if we are able to create an Internet connection not talk to a server. So, as soon as the connection is established, you disconnect without sending or receiving any data. What you are doing is a waste of time anyway because if a network has a captive portal, they don't want you to connect to the internet without either paying or accepting some terms of service. I feel like the best solution is to use your own server, that way you're also checking its availability. Making HTTP requests is unnecessary and your method wouldn't work if Google were blocked.Declivitous
@Declivitous What's a waste of time creating an Internet connection without being able to talk to a server. If you have your own server, connecting to it directly is the best approach. However not everyone does, and what Google provides (for free) is the next best thing. The end user knows if someone 'wants' you to connect or not, but the app / background task doesn't and that's what the OP wanted to know. There is no panacea to the problem, but this is acceptable for the vast majority of use cases. The socket approach is no better than going by what ConnectivityManager reports.Vaunting
We can't forget to add android:usesCleartextTraffic="true" in AndroidManifest.xml. Otherwise we will get java.io.IOException: Cleartext HTTP traffic to clients3.google.com not permittedMarchpast
S
19
public boolean isInternetWorking() {
    boolean success = false;
    try {
        URL url = new URL("https://google.com");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(10000);
        connection.connect();
        success = connection.getResponseCode() == 200;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return success;
}

return true if internet is actually available, Must be called on background thread

Make sure you have these two permission

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

if http does not work its because of the new android security they donot allow plain text communication now. for now just to by pass it.

android:usesCleartextTraffic="true"

I would recommend to ping your own server. In this way you are more confident that you have internet and your web server is also working. (for cases like when you have internet but your server is down)

Separate answered 9/6, 2015 at 13:44 Comment(8)
This is the best, most complete answer: it's the shortest way of doing things (a ping doesn't access the whole website), it runs independantly of which connection you have and it runs in it's won process so it plays nice with android versions.Saritasarkaria
what do u mean ? here is another snippet which i am using in a current project checkInternetSeparate
what he meant is will this call block the UI and he needs to make this call in thread ??Nathalienathan
This doesn't work for me... Caused by: android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273) at java.net.InetAddress.lookupHostByName(InetAddress.java:431) atJataka
@HyosokaPoipo you should not invoke this on the main thread. Use a separate thread or AsyncTask.Phenoxide
wonder if there is new thing added to the comment or just the points. @PrameshBajracharyaSeparate
It does not work in some country, China, for example. :( And it also costs a very long time to detect, I want to get the result as soon as possible, let's say it, limited in 5 seconds.Dachy
@Dachy you can remove google.com and change with google.com.twSeparate
H
14

If you're targeting Android 6.0 - Marshmallow (API level 23) or higher it's possible to use the new NetworkCapabilities class, i.e:

public static boolean hasInternetConnection(final Context context) {
    final ConnectivityManager connectivityManager = (ConnectivityManager)context.
            getSystemService(Context.CONNECTIVITY_SERVICE);

    final Network network = connectivityManager.getActiveNetwork();
    final NetworkCapabilities capabilities = connectivityManager
            .getNetworkCapabilities(network);

    return capabilities != null
            && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
Huei answered 26/1, 2016 at 8:29 Comment(3)
connectivityManager.getActiveNetwork(); requires API lvl23 which is Marshmallow and not Lollipop.Inject
Should we also check for capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?Polky
Alex capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) seemed to do the trick for me!Kaete
S
8

You don't necessarily need to make a full HTTP connection. You could try just opening a TCP connection to a known host and if it succeeds you have internet connectivity.

public boolean hostAvailable(String host, int port) {
  try (Socket socket = new Socket()) {
    socket.connect(new InetSocketAddress(host, port), 2000);
    return true;
  } catch (IOException e) {
    // Either we have a timeout or unreachable host or failed DNS lookup
    System.out.println(e);
    return false;
  }
}

Then just check with:

boolean online = hostAvailable("www.google.com", 80);
Starlet answered 26/2, 2016 at 9:26 Comment(4)
is port 80 a safe port to use ?Bozcaada
As long as it's hosting a HTTP server, it should accept a TCP connection on Port 80.Starlet
Should this be used inside an AsyncTask or just called in the onCreate method of the MainActivity for example?Testamentary
@Vay anything that is network related shouldn't run on the main/ui-thread. So yes, this should be used inside an AsyncTaskTetartohedral
Y
5

Based on the accepted answers, I have built this class with a listener so you can use it in the main thread:

First: InterntCheck class which checks for internet connection in the background then call a listener method with the result.

public class InternetCheck extends AsyncTask<Void, Void, Void> {


    private Activity activity;
    private InternetCheckListener listener;

    public InternetCheck(Activity x){

        activity= x;

    }

    @Override
    protected Void doInBackground(Void... params) {


        boolean b = hasInternetAccess();
        listener.onComplete(b);

        return null;
    }


    public void isInternetConnectionAvailable(InternetCheckListener x){
        listener=x;
        execute();
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) activity.getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null;
    }
    private boolean hasInternetAccess() {
        if (isNetworkAvailable()) {
            try {
                HttpURLConnection urlc = (HttpURLConnection) (new URL("http://clients3.google.com/generate_204").openConnection());
                urlc.setRequestProperty("User-Agent", "Android");
                urlc.setRequestProperty("Connection", "close");
                urlc.setConnectTimeout(1500);
                urlc.connect();
                return (urlc.getResponseCode() == 204 &&
                        urlc.getContentLength() == 0);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            Log.d("TAG", "No network available!");
        }
        return false;
    }

    public interface InternetCheckListener{
        void onComplete(boolean connected);
    }

}

Second: instantiate an instance of the class in the main thread and wait for the response (if you have worked with Firebase api for android before this should be familiar to you!).

new InternetCheck(activity).isInternetConnectionAvailable(new InternetCheck.InternetCheckListener() {

        @Override
        public void onComplete(boolean connected) {
           //proceed!
        }
    });

Now inside onComplete method you will get whether the device is connected to the internet or not.

Yesima answered 3/2, 2017 at 7:29 Comment(0)
M
3

try this one

public class ConnectionDetector {
    private Context _context;

    public ConnectionDetector(Context context) {
        this._context = context;
    }

    public boolean isConnectingToInternet() {
        if (networkConnectivity()) {
            try {
                HttpURLConnection urlc = (HttpURLConnection) (new URL(
                        "http://www.google.com").openConnection());
                urlc.setRequestProperty("User-Agent", "Test");
                urlc.setRequestProperty("Connection", "close");
                urlc.setConnectTimeout(3000);
                urlc.setReadTimeout(4000);
                urlc.connect();
                // networkcode2 = urlc.getResponseCode();
                return (urlc.getResponseCode() == 200);
            } catch (IOException e) {
                return (false);
            }
        } else
            return false;

    }

    private boolean networkConnectivity() {
        ConnectivityManager cm = (ConnectivityManager) _context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            return true;
        }
        return false;
    }
}

you'll have to add the following permission to your manifest file:

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

Then call like that:

if((new ConnectionDetector(MyService.this)).isConnectingToInternet()){
    Log.d("internet status","Internet Access");
}else{
    Log.d("internet status","no Internet Access");
}
Marquess answered 10/7, 2015 at 0:5 Comment(6)
check this post #36234007Mnemonic
this gay uses try catch therefore error isn't shown please first add internet permission then try this. its work fineMarquess
Let me tell you how i called this method in my activity?Mnemonic
I tried you post and i got an error which i was post an error in my blogMnemonic
#36234007 check itMnemonic
Thanx for your appreciate but you code caused an error.Mnemonic
C
3

You can do this with very simple class.

class CheckInternet {
    fun isNetworkAvailable(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
        val activeNetworkInfo = connectivityManager!!.activeNetworkInfo
        return activeNetworkInfo != null && activeNetworkInfo.isConnected
    }
}

Now you can check this from any class.

if (CheckInternet().isNetworkAvailable(this)) {
  //connected with internet
}else{
  //Not connected with internet
}
Constance answered 26/8, 2020 at 20:7 Comment(1)
activeNetworkInfo is now deprecated.Bharal
O
1

You can do this using the ConnectivityManager API for android. It allows you to check whether you are connected to the internet and the type of internet connection you are connected to. Basically, Metered or Un-metered.

To check for internet connection.

ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

Documentation link: https://developer.android.com/training/monitoring-device-state/connectivity-status-type

Otiliaotina answered 9/1, 2020 at 6:21 Comment(1)
How do you check if mobile data has run out? This returns true even if mobile data is connected and has no data balance remaining on the account.Earwax
V
0
private static NetworkUtil mInstance;
private volatile boolean mIsOnline;

private NetworkUtil() {
    ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
    exec.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            boolean reachable = false;
            try {
                Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
                int returnVal = process.waitFor();
                reachable = (returnVal==0);
            } catch (Exception e) {
                e.printStackTrace();
            }
            mIsOnline = reachable;
        }
    }, 0, 5, TimeUnit.SECONDS);
}

public static NetworkUtil getInstance() {
    if (mInstance == null) {
        synchronized (NetworkUtil.class) {
            if (mInstance == null) {
                mInstance = new NetworkUtil();
            }
        }
    }
    return mInstance;
}

public boolean isOnline() {
    return mIsOnline;
}

Hope the above code helps you, also make sure you have internet permission in ur app.

Vivianviviana answered 14/2, 2017 at 15:36 Comment(0)
L
0

The latest way to do that from the documentation is to use the ConnectivityManager to query the active network and determine if it has Internet connectivity.

public boolean hasInternetConnectivity() {
    ConnectivityManager cm =
        (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return (activeNetwork != null &&
                      activeNetwork.isConnectedOrConnecting());
}

Add these two permissions to your AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Leucopoiesis answered 23/9, 2018 at 11:20 Comment(1)
Not works :( As @Buda Gavril says, if I'm connected to a wireless network which doesn't have Internet access, this method will still return true. Test on Xiaomi 4, Android 6.0.1.Dachy
C
0

Check wifi type in connectivity manager:

   //check network connection
    ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean hasNetworkConnection = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    System.out.println("Connection ? : " + hasNetworkConnection);
    //check wifi
    boolean hasWifiConnection = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    System.out.println("Wifi ? : " + hasWifiConnection);

Android Documentation describes 'TYPE_WIFI' as 'A WIFI data connection. Devices may support more than one.'

Chiseler answered 29/7, 2019 at 4:37 Comment(0)
V
0

A nice solution to check if the active network have internet connection:

public boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager
            = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        Network network = connectivityManager.getActiveNetwork();
        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
        return networkCapabilities != null && networkCapabilities
                .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    }
    return false;
}
Villanelle answered 4/11, 2019 at 8:55 Comment(0)
N
0

You can use ConnectivityManager.

val cm = getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
            val dialogBuilder = AlertDialog.Builder(this)

            if (activeNetwork!=null) // Some network is available
            {
                if (activeNetwork.isConnected) { // Network is connected to internet

    }else{ // Network is NOT connected to internet

    }

Check this and this

Niello answered 2/12, 2019 at 6:24 Comment(0)
C
0

Use the following class, updated to the last API level: 29.

// License: MIT
// http://opensource.org/licenses/MIT
package net.i2p.android.router.util;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Build;
import android.telephony.TelephonyManager;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.concurrent.CancellationException;



/**
 * Check device's network connectivity and speed.
 *
 * @author emil http://stackoverflow.com/users/220710/emil
 * @author str4d
 * @author rodrigo https://stackoverflow.com/users/5520417/rodrigo
 */
public class ConnectivityAndInternetAccessCheck {

    private static ArrayList < String > hosts = new ArrayList < String > () {
        {
            add("google.com");
            add("facebook.com");
            add("apple.com");
            add("amazon.com");
            add("twitter.com");
            add("linkedin.com");
            add("microsoft.com");
        }
    };
    /**
     * Get the network info.
     *
     * @param context the Context.
     * @return the active NetworkInfo.
     */
    private static NetworkInfo getNetworkInfo(Context context) {
        NetworkInfo networkInfo = null;
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm != null) {
            networkInfo = cm.getActiveNetworkInfo();
        }
        return networkInfo;
    }

    /**
     * Gets the info of all networks
     * @param context The context
     * @return an array of @code{{@link NetworkInfo}}
     */
    private static NetworkInfo[] getAllNetworkInfo(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getAllNetworkInfo();
    }

    /**
     * Gives the connectivity manager
     * @param context The context
     * @return the @code{{@link ConnectivityManager}}
     */
    private static ConnectivityManager getConnectivityManager(Context context) {
        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    /**
     * Check if there is any connectivity at all.
     *
     * @param context the Context.
     * @return true if we are connected to a network, false otherwise.
     */
    public static boolean isConnected(Context context) {
        boolean isConnected = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
            Network[] networks = connectivityManager.getAllNetworks();
            networksloop: for (Network network: networks) {
                if (network == null) {
                    isConnected = false;
                } else {
                    NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                    if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                        isConnected = true;
                        break networksloop;
                    }
                    else {
                        isConnected = false;
                    }
                }
            }

        } else {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkinfosloop: for (NetworkInfo info: networkInfos) {
                // Works on emulator and devices.
                // Note the use of isAvailable() - without this, isConnected() can
                // return true when Wifi is disabled.
                // http://stackoverflow.com/a/2937915
                isConnected = info != null && info.isAvailable() && info.isConnected();
                if (isConnected) {
                    break networkinfosloop;
                }
            }

        }
        return isConnected;
    }

    /**
     * Check if there is any connectivity to a Wifi network.
     *
     * @param context the Context.
     * @return true if we are connected to a Wifi network, false otherwise.
     */
    public static boolean isConnectedWifi(Context context) {
        boolean isConnectedWifi = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
            Network[] networks = connectivityManager.getAllNetworks();
            networksloop: for (Network network: networks) {
                if (network == null) {
                    isConnectedWifi = false;
                } else {
                    NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                    if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                            isConnectedWifi = true;
                            break networksloop;
                        } else {
                            isConnectedWifi = false;
                        }
                    }
                }

            }


        } else {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkinfosloop: for (NetworkInfo n: networkInfos) {
                isConnectedWifi = n != null && n.isAvailable() && n.isConnected() && n.getType() == ConnectivityManager.TYPE_WIFI;
                if (isConnectedWifi) {
                    break networkinfosloop;
                }

            }
        }
        return isConnectedWifi;
    }

    /**
     * Check if there is any connectivity to a mobile network.
     *
     * @param context the Context.
     * @return true if we are connected to a mobile network, false otherwise.
     */
    public static boolean isConnectedMobile(Context context) {
        boolean isConnectedMobile = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
            Network[] allNetworks = connectivityManager.getAllNetworks();
            networksloop: for (Network network: allNetworks) {
                if (network == null) {
                    isConnectedMobile = false;
                } else {
                    NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                    if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                            isConnectedMobile = true;
                            break networksloop;
                        } else {
                            isConnectedMobile = false;
                        }
                    }
                }

            }

        } else {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkinfosloop: for (NetworkInfo networkInfo: networkInfos) {
                isConnectedMobile = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected() && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
                if (isConnectedMobile) {
                    break networkinfosloop;
                }
            }
        }
        return isConnectedMobile;
    }

    /**
     * Check if there is fast connectivity.
     *
     * @param context the Context.
     * @return true if we have "fast" connectivity, false otherwise.
     */
    public static boolean isConnectedFast(Context context) {
        boolean isConnectedFast = false;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
            networkInfosloop:
            for (NetworkInfo networkInfo: networkInfos) {
                isConnectedFast = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected() && isConnectionFast(networkInfo.getType(), networkInfo.getSubtype());
                if (isConnectedFast) {
                    break networkInfosloop;
                }
            }
        } else {
            throw new UnsupportedOperationException();
        }
        return isConnectedFast;
    }

    /**
     * Check if the connection is fast.
     *
     * @param type the network type.
     * @param subType the network subtype.
     * @return true if the provided type/subtype combination is classified as fast.
     */
    private static boolean isConnectionFast(int type, int subType) {
        if (type == ConnectivityManager.TYPE_WIFI) {
            return true;
        } else if (type == ConnectivityManager.TYPE_MOBILE) {
            switch (subType) {
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                    return false; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_CDMA:
                    return false; // ~ 14-64 kbps
                case TelephonyManager.NETWORK_TYPE_EDGE:
                    return false; // ~ 50-100 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    return true; // ~ 400-1000 kbps
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    return true; // ~ 600-1400 kbps
                case TelephonyManager.NETWORK_TYPE_GPRS:
                    return false; // ~ 100 kbps
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                    return true; // ~ 2-14 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPA:
                    return true; // ~ 700-1700 kbps
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                    return true; // ~ 1-23 Mbps
                case TelephonyManager.NETWORK_TYPE_UMTS:
                    return true; // ~ 400-7000 kbps
                /*
                 * Above API level 7, make sure to set android:targetSdkVersion
                 * to appropriate level to use these
                 */
                case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
                    return true; // ~ 1-2 Mbps
                case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
                    return true; // ~ 5 Mbps
                case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
                    return true; // ~ 10-20 Mbps
                case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                    return false; // ~25 kbps
                case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
                    return true; // ~ 10+ Mbps
                // Unknown
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                default:
                    return false;
            }
        } else {
            return false;
        }
    }

    public ArrayList < String > getHosts() {
        return hosts;
    }

    public void setHosts(ArrayList < String > hosts) {
        this.hosts = hosts;
    }
    //TODO Debug on devices
    /**
     * Checks that Internet is available by pinging DNS servers.
     */
    private static class InternetConnectionCheckAsync extends AsyncTask < Void, Void, Boolean > {

        private Context context;

        /**
         * Creates an instance of this class
         * @param context The context
         */
        public InternetConnectionCheckAsync(Context context) {
            this.setContext(context);
        }

        /**
         * Cancels the activity if the device is not connected to a network.
         */
        @Override
        protected void onPreExecute() {
            if (!ConnectivityAndInternetAccessCheck.isConnected(getContext())) {
                cancel(true);
            }
        }

        /**
         * Tells whether there is Internet access
         * @param voids The list of arguments
         * @return True if Internet can be accessed
         */
        @Override
        protected Boolean doInBackground(Void...voids) {
            return isConnectedToInternet(getContext());
        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
        }

        /**
         * The context
         */
        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }
    } //network calls shouldn't be called from main thread otherwise it will throw //NetworkOnMainThreadException

    /**
     * Tells whether Internet is reachable
     * @return true if Internet is reachable, false otherwise
     * @param context The context
     */
    public static boolean isInternetReachable(Context context) {
        try {
            return new InternetConnectionCheckAsync(context).execute().get();
        } catch (CancellationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Tells whether there is Internet connection
     * @param context The context
     * @return @code {true} if there is Internet connection
     */
    private static boolean isConnectedToInternet(Context context) {
        boolean isAvailable = false;
        if (!ConnectivityAndInternetAccessCheck.isConnected(context)) {
            isAvailable = false;
        } else {
            try {
                foreachloop: for (String h: new ConnectivityAndInternetAccessCheck().getHosts()) {
                    if (isHostAvailable(h)) {
                        isAvailable = true;
                        break foreachloop;
                    }
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }

        return isAvailable;

    }

    /**
     * Checks if the host is available
     * @param hostName
     * @return
     * @throws IOException
     */
    private static boolean isHostAvailable(String hostName) throws IOException {
        try (Socket socket = new Socket()) {
            int port = 80;
            InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
            socket.connect(socketAddress, 3000);

            return true;
        } catch (UnknownHostException unknownHost) {
            return false;
        }
    }
}
Candidacandidacy answered 22/12, 2019 at 0:2 Comment(0)
S
0

If all above answers get you FATAL EXCEPTIONs like android.os.NetworkOnMainThreadException, this answer will really help you.
Because I got this error while trying to implement this.

The reason for this error is that the Network related codes cannot be on the main thread.
So, you need to create a new Thread as I shown below:

Thread thread = new Thread(new Runnable() {

@Override
public void run() {
    try  {
        //Your code goes here
    } catch (Exception e) {
        e.printStackTrace();
    }
}});


And put your code in the place I commented.

Snood answered 24/2, 2021 at 12:53 Comment(0)
M
0

Look at this function, it gives the actual internet connectivity status of the device.

 public boolean isActiveNetworkAvailable(Context context)
{
    try
    {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm!=null){
            Network network = cm.getActiveNetwork();
            if (network != null) {
                NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(network);
                if (networkCapabilities != null && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
                ){
                    Log.d(TAG,"Use both NET_CAPABILITY_INTERNET and NET_CAPABALITY_VALIDATED to check whether the device has active internet connection.")
                    Log.d(TAG,"Internet available");
                    return (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
                    );
                }else{
                    Log.d(TAG,"Internet not available");
                    return false;
                }
            }else {
                return false;
            }
        }else {
            return false;
        }
    }
    catch(Exception e)
    {
        Logcat.e(TAG, "isActiveNetworkAvailable", e);
        return false;
    }
}

Note: This function may not give the actual status instantly as the NET_CAPABILITY_VALIDATED flag gets updated by the System and it has the value of last checked status. Please see this screenshot below taken from here. enter image description here

Marivaux answered 19/2 at 6:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.