Android Internet connectivity check better method

家住魔仙堡 提交于 2019-12-03 05:53:25

问题


According to the Android developer site, Determining and Monitoring the Connectivity Status, we can check there is an active Internet connection. But this is not working if even only Wi-Fi is connected and not Internet available (it notifies there is an Internet connection).

Now I ping a website and check whether Internet connections are available or not. And this method needs some more processing time. Is there a better method for checking Internet connectivity than this to avoid the time delay in ping the address?


回答1:


Try this:

It's really simple and fast:

public boolean isInternetAvailable(String address, int port, int timeoutMs) {
    try {
        Socket sock = new Socket();
        SocketAddress sockaddr = new InetSocketAddress(address, port);

        sock.connect(sockaddr, timeoutMs); // This will block no more than timeoutMs
        sock.close();

        return true;

    } catch (IOException e) { return false; }
}

Then wherever you want to check just use this:

if (isInternetAvailable("8.8.8.8", 53, 1000)) {
     // Internet available, do something
} else {
     // Internet not available
}



回答2:


The first problem you should make it clear is what do you mean by whether internet is available?

  • Not connected to wifi or cellular network;
  • Connected to a limited wifi: e.g. In a school network, if you connect to school wifi, you can access intranet directly. But you have to log in with school account to access extranet. In this case, if you ping extranet website, you may receive response because some intranet made auto redirect to login page;
  • Connected to unlimited wifi: you are free to access most websites;

The second problem is what do you want to achieve?

As far as I understand your description, you seems want to test the connection of network and remind user if it fails. So I recommend you just ping your server, which is always fine if you want to exchange data with it.


You wonder whether there is a better way to test connectivity, and the answer is no.

The current TCP/IP network is virtual circuit, packet-switched network, which means there is no a fixed 'path' for the data to run, i.e. not like a telephone, we have a real connection between two users, we can know the connection is lost immediately after circuit is broken. We have to send a packet to the destination, and find no response, then we know, we lose the connection (which is what ping -- ICMP protocol -- does).

In conclusion, we have no better way to test the connectivity to a host other than ping it, that is why heartbeat is used in service management.




回答3:


Try the following:

public boolean checkOnlineState() {
    ConnectivityManager CManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo NInfo = CManager.getActiveNetworkInfo();
    if (NInfo != null && NInfo.isConnectedOrConnecting()) {
        return true;
    }
    return false;
}

Don't forget the access:

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

Else:

if (InetAddress.getByName("www.google.com").isReachable(timeout))
{    }
else
{    }



回答4:


On checking this issue it found that We cannot determine whether an active internet connection is there, by using the method specified in the developer site: https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html

This will only check whther ther active connection of wifi.

So I found 2 methods which will check whether there is an active internet connection

1.Ping a website using below method

URL url = new URL(myUrl);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        // 30 second time out.
        httpURLConnection.setConnectTimeout(30000);
        httpURLConnection.connect();
        if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            isAvailable = true;
        }

2.Check the availability of Google DNS using socket

  try {
        Socket sock = new Socket();
        SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);

        sock.connect(sockaddr, 1000); // this will block no more than timeoutMs
        sock.close();

        return true;
} 

The second method is little faster than 2nd method (Which suits for my requirement)

Thanks all for the answers and support.




回答5:


//***To verify internet access

public static Boolean isOnline(){

    boolean isAvailable = false;
    try {

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        URL url = new URL("https://stackoverflow.com/");
        HttpURLConnection httpURLConnection = null;
        httpURLConnection = (HttpURLConnection) url.openConnection();

        // 2 second time out.
        httpURLConnection.setConnectTimeout(2000);
        httpURLConnection.connect();
        if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            isAvailable = true;
        } else {
            isAvailable = false;
        }
    } catch (IOException e) {
        e.printStackTrace();
        isAvailable = false;
    }

    if (isAvailable){
        return true;
    }else {
        return false;
    }
}



回答6:


ConnectivityManager will not be able to tell you if you have active connection on WIFI.

The only option to check if we have active Internet connection is to ping the URL. But you don't need to do that with every HTTP request you made from your App.

What you can do:

  1. Use below code to check connectivity

    private boolean checkInternetConnection()
    {
        ConnectivityManager cm = (ConnectivityManager) 
        getSystemService(Context.CONNECTIVITY_SERVICE);
        // test for connection
        if (cm.getActiveNetworkInfo() != null
            && cm.getActiveNetworkInfo().isAvailable()
            && cm.getActiveNetworkInfo().isConnected())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
  2. And while making rest call using HTTP client set timeout like 10 seconds. If you don't get response in 10 seconds means you donot have active internet connection and exception will be thrown (Mostly you get response within 10 seconds). No need to check active connection by pinging everytime (if you are not making Chat or VOIP app)




回答7:


Maybe this can help you:

private boolean checkInternetConnection() {
        ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
        // Test for connection
        if (cm.getActiveNetworkInfo() != null
            && cm.getActiveNetworkInfo().isAvailable()
            && cm.getActiveNetworkInfo().isConnected()) {
        return true;
    } 
    else {
        return false;
    }
}



回答8:


Try this method, this will help you:

public static boolean isNetworkConnected(Context context)
{
    ConnectivityManager connectivityManager = (ConnectivityManager)
            context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null)
    {
        NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnected())
        {
            return true;
        }
    }
    return false;
}



回答9:


You can try this for check Internet connectivity:

/**
 * Check Connectivity of network.
 */
public static boolean isOnline(Context context) {
    try {
        if (context == null)
            return false;

        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        if (cm != null) {
            if (cm.getActiveNetworkInfo() != null) {
                return cm.getActiveNetworkInfo().isConnected();
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    catch (Exception e) {
        Log.error("Exception", e);
        return false;
    }
}

In your activity you call this function like this.

if(YourClass.isOnline(context))
{
  // Do your stuff here.
}
else
{
  // Show alert, no Internet connection.
}

Don't forget to add ACCESS_NETWORK_STATE PERMISSION:

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

Try this if you want to just ping the URL:

public static boolean isPingAvailable(String myUrl) {
    boolean isAvailable = false;
    try {
        URL url = new URL(myUrl);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        // 30 second time out.
        httpURLConnection.setConnectTimeout(30000);
        httpURLConnection.connect();
        if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            isAvailable = true;
        }
    } catch (Exception e) {
        isAvailable = false;
        e.printStackTrace();
    }
    return isAvailable;
}



回答10:


I wanted to comment, but not enough reputation :/

Anyways, an issue with the accepted answer is it doesn't catch a SocketTimeoutException, which I've seen in the wild (Android) that causes crashes.

public boolean isInternetAvailable(String address, int port, int timeoutMs) {
    try {
        Socket sock = new Socket();
        SocketAddress sockaddr = new InetSocketAddress(address, port);

        sock.connect(sockaddr, timeoutMs); // This will block no more than timeoutMs
        sock.close();

        return true;

    } catch (IOException e) { 
        return false; 
    } catch (SocketTimeoutException e) {
        return false;
    }
}


来源:https://stackoverflow.com/questions/44918248/android-internet-connectivity-check-better-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!