在 Android 中检测有限的网络连接?

Posted

技术标签:

【中文标题】在 Android 中检测有限的网络连接?【英文标题】:Detecting limited network connectivity in Android? 【发布时间】:2013-07-23 05:01:55 【问题描述】:

关于如何在 android 中检测网络连接存在许多问题。 https://***.com/a/4239019/90236 提供了非常详细的答案,https://***.com/a/8548926/90236 显示了识别所连接网络类型的方法。

我们使用类似于以下答案的代码检测网络连接:

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

这让我们可以在用户离线时向他们发出警告。但是,它并不能帮助我们确定用户的连接是否受限。有些连接受限的情况会导致用户抱怨。其中包括:

    用户已连接到家庭 wifi 网络,但电缆调制解调器或 Internet 服务不可用。

    用户在酒店或咖啡店并成功连接到 wifi 网络,但该网络要求他们登录或同意服务条款才能获得完整的网络访问权限。

在这两种情况下,我们的 isNetworkAvailable() 测试都返回 true。操作系统告诉我们我们已连接到网络。但是,用户没有可用的 Internet 连接。

是否有确定用户具有功能齐全的网络连接的好方法?

我正在考虑调用一个轻量级 Web 服务来验证它们的连接性,并在应用程序没有从服务中获得有效返回时警告用户。这是矫枉过正吗?还是其他人不得不求助于类似的技术?

【问题讨论】:

【参考方案1】:

是否有确定用户是否拥有功能齐全的网络连接的好方法?

尝试从某个地方下载一些东西。理想情况下,“某处”是您自己的服务器,用于测试设备与服务器之间的连接性。

唉,ConnectivityManager 上没有 doesTehConnexionSuck()iCanHazBandwidth() 方法。 :-)

这是不是矫枉过正?

本着“金发姑娘和三只熊”的精神,我将其描述为justrightkill。

我们也必须做the same sorts of shenanigans in Web apps。

【讨论】:

我喜欢“justrightkill”的想法,但它没有相同的戒指 - youtube.com/watch?v=YjETcbEDmoQ【参考方案2】:

为了完整起见,让我发布一些我添加的代码。我认为发出 Http 请求并在请求成功时返回 true 是相当通用的 HttpClient 代码。我使用 HttpHead 是因为我不关心响应中的实体,这应该使它更快。此方法位于名为 ConnectivityHelper 的类中,而 DefaultSettings 是一个定义了许多有用常量的类。

public static boolean isNetworkAvailable() 
    ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo;

    try 
        netInfo = manager.getActiveNetworkInfo();
     catch (Exception e) 
        netInfo = null;
    

    return netInfo != null && netInfo.isConnected() && testConnection(DefaultSettings.TEST_CONNECTION_URL);



private static boolean testConnection(String url) 
    HttpClient httpClient = null;
    HttpHead request = null;
    HttpResponse response = null;
    int statusCode = 0;

    try 
        HttpParams myParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(myParams, DefaultSettings.CONNECTION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(myParams, DefaultSettings.SO_TIMEOUT);

        httpClient = new DefaultHttpClient(myParams);

        request = new HttpHead(url);
        response = httpClient.execute(request);
        statusCode = response.getStatusLine().getStatusCode();

        if (statusCode != 200)
        
            Log.e(ConnectivityHelper.class.getName(), String.format("testConnection not successful. For %s - Status code = %d", url, statusCode));
            return false;
        
        return true;

     catch(ClientProtocolException e) 
        Log.e(ConnectivityHelper.class.getName(), String.format("testConnection failure. For %s - Exception: %s.", url, e.toString()));

        if (request != null && !request.isAborted()) 
            request.abort();
        

        return false;
     catch(IOException e) 
        if (statusCode == 401) 
            Log.e(ConnectivityHelper.class.getName(), String.format("testConnection access denied. For %s - Status code = %d", url, statusCode));               
         else 
            Log.e(ConnectivityHelper.class.getName(), String.format("testConnection failure. For %s - Exception: %s.", url, e.toString()));
        

        if (request != null && !request.isAborted()) 
            request.abort();
        

        return false;
     finally 
        if (httpClient != null) 
            httpClient.getConnectionManager().shutdown();
        
               

【讨论】:

嗯,正是@CommonsWare 发布的答案促使我编写了上面的代码,所以他的答案是第一位的,而且真的很有帮助。正如他们所说,其余的只是一个练习。 HttpClient 在 API 级别 22 中已被弃用并在 API 级别 23 中被删除。您可以尝试更新代码吗?

以上是关于在 Android 中检测有限的网络连接?的主要内容,如果未能解决你的问题,请参考以下文章

未连接蜂窝网络时,Android 仍会检测蜂窝信号强度

windows如何检测附近连接wifi的网络打印机?

Android 通过广播获取网络状态

有没有办法在Ionic 3中检测网络速度或强度?

linux中怎么检测TCP网络连接是不是正常

如何在 Firebase 作业调度程序中检测网络断开连接?