Android Internet连接检查更好的方法

时间:2017-07-05 06:12:51

标签: android android-7.0-nougat internet-connection

根据Android开发者网站 Determining and Monitoring the Connectivity Status ,我们可以检查是否存在活动的Internet连接。但即使只连接了Wi-Fi而没有互联网可用(它通知有互联网连接),这也无效。

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

10 个答案:

答案 0 :(得分:9)

试试这个:

它非常简单快速:

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
}

答案 1 :(得分:4)

尝试以下方法:

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

答案 2 :(得分:4)

您应该明确指出的第一个问题是whether internet is available是什么意思?

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

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

据我了解您的描述,您似乎想测试网络连接并提醒用户是否失败。所以我建议你只需ping你的服务器,如果你想与它交换数据,这总是很好。

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

当前的TCP / IP网络是虚拟电路,数据包交换网络,这意味着没有固定的“路径”来运行数据,即不像电话,我们有一个两个用户之间真正的连接,我们可以知道电路断开后连接立即丢失。我们必须发送一个数据包到目的地,并找不到响应,然后我们知道,我们失去了连接(这是ping-ICMP协议 - 的作用)。

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

答案 3 :(得分:2)

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

这只会检查wifi的有效连接。

所以我找到了两种方法来检查是否存在有效的互联网连接

1.使用以下方法建立网站

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.使用套接字检查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;
} 

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

感谢大家的回答和支持。

答案 4 :(得分: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;
    }
}

答案 5 :(得分:1)

尝试这种方法,这将对您有所帮助:

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

答案 6 :(得分:1)

您可以尝试检查互联网连接:

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

在您的活动中,您可以像这样调用此函数。

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

不要忘记添加ACCESS_NETWORK_STATE PERMISSION:

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

如果您只想ping网址,请尝试此操作:

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

答案 7 :(得分:1)

如果您在WIFI上有活动连接,ConnectivityManager将无法告诉您。

检查我们是否具有活动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应用程序)

答案 8 :(得分:1)

我想发表评论,但声誉不够:/

无论如何,可接受答案的一个问题是它没有捕获到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;
    }
}

答案 9 :(得分:1)

// ***要验证互联网访问权限

let downloadUsingCache url = async {
  let! res = downloadCache.PostAndAsyncReply(fun ch -> Download(url, ch))
  return! res }