Android Internet 连接检查更好的方法

Android Internet connectivity check better method

根据 Android 开发者网站,Determining and Monitoring the Connectivity Status,我们可以检查是否存在活动的互联网连接。但是,如果仅连接了 Wi-Fi 而没有可用的互联网(它会通知有互联网连接),这将不起作用。

现在我 ping 一个网站,检查 Internet 连接是否可用。而且这种方法需要更多的处理时间。有没有比这更好的检查 Internet 连接的方法来避免 ping 地址的时间延迟?

试试这个:

确实简单快捷:

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; }
}

然后无论你想检查哪里,只要使用这个:

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

尝试以下操作:

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

不要忘记访问权限:

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

其他:

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

也许这可以帮到你:

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;
    }
}

试试这个方法,这对你有帮助:

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;
}

您可以试试这个来检查 Internet 连接:

/**
 * 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;
    }
}

在你的 activity 中你这样调用这个函数。

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

不要忘记添加 ACCESS_NETWORK_STATE 权限:

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

如果你只想 ping 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;
}

ConnectivityManager 将无法告诉您您的 WIFI 连接是否有效。

检查我们是否有活动的 Internet 连接的唯一选项是 ping URL。但是您不需要对从应用程序发出的每个 HTTP 请求都这样做。

你可以做什么:

  1. 使用下面的代码检查连通性

    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. 并且在使用 HTTP 客户端设置超时(如 10 秒)进行休息呼叫时。如果您在 10 秒内没有得到响应,则意味着您没有活动的互联网连接并且将抛出异常(大多数情况下您会在 10 秒内得到响应)。无需每次都通过 ping 来检查活动连接(如果您没有制作聊天或 VOIP 应用程序)

首先要弄清楚的问题是whether internet is available是什么意思?

  • 未连接到 wifi 或蜂窝网络;
  • 连接到有限的 wifi:例如在学校网络中,如果连接学校wifi,就可以直接访问内网。但是您必须使用学校帐户登录才能访问外网。在这种情况下,如果您 p​​ing 外网网站,您可能会收到响应,因为某些内网会自动重定向到登录页面;
  • 已连接无限 wifi:您可以自由访问大多数网站;

第二个问题是你想达到什么目的?

据我了解你的描述,你似乎想测试网络连接,并在失败时提醒用户。所以我建议您只对您的服务器执行 ping 操作,如果您想与其交换数据,这总是可以的。


您想知道是否有更好的方法来测试连通性,答案是否定的。

当前的TCP/IP网络是虚电路,分组交换网络,也就是说没有固定的'path'数据到运行,即不像电话,我们在两个用户之间有一个真正的连接,我们可以在电路断开后立即知道连接丢失。我们必须向目的地发送一个数据包,但发现没有响应,然后我们知道,我们失去了连接(这就是 ping —— ICMP 协议 —— 所做的)。

总之,除了 ping 主机之外,我们没有更好的方法来测试与主机的连接,这就是为什么在服务管理中使用 heartbeat 的原因。

检查此问题后发现,我们无法使用开发者网站中指定的方法确定是否存在活动的互联网连接: https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html

这只会检查 wifi 是否有效连接。

所以我找到了 2 种方法来检查是否有活动的互联网连接

1.Ping 使用以下方法的网站

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 Google DNS 使用套接字的可用性

  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;
} 

第二种方法比第二种方法快一点(适合我的要求)

感谢大家的回答和支持。

我想发表评论,但没有足够的声誉:/

无论如何,已接受答案的一个问题是它没有捕捉到 SocketTimeoutException,我在野外看到过这种情况 (Android) 会导致崩溃。

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;
    }
}

//***验证互联网访问

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://whosebug.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;
    }
}