检测Android上是不是有可用的互联网连接[重复]

Posted

技术标签:

【中文标题】检测Android上是不是有可用的互联网连接[重复]【英文标题】:Detect whether there is an Internet connection available on Android [duplicate]检测Android上是否有可用的互联网连接[重复] 【发布时间】:2011-05-13 10:35:05 【问题描述】:

可能重复:How to check internet access on android? InetAddress never timeouts

我需要检测安卓设备是否连接到互联网。

NetworkInfo 类提供了一个听起来很完美的非静态方法isAvailable()

问题是:

NetworkInfo ni = new NetworkInfo();
if (!ni.isAvailable()) 
    // do something

抛出此错误:

The constructor NetworkInfo is not visible.

安全的赌注是有另一个类返回一个NetworkInfo 对象。但我不知道是哪个。

    如何让上面的sn-p代码工作? 我怎么能在在线文档中找到我需要的信息? 您能否为此类检测提出更好的方法?

【问题讨论】:

[This][1] 也可能有帮助 [1]:***.com/questions/6179906/… android.com上的文章:Determining and Monitoring the Connectivity Status 这里的答案都没有真正回答检查是否有连接到互联网的问题,只有当你完全连接到网络时。有关仅尝试建立传出 TCP 连接以对此进行测试的示例,请参见此答案:***.com/a/35647792/1820510 对于 2020 年关注此内容的任何人:teamtreehouse.com/community/… 【参考方案1】:

ConnectivityManagergetActiveNetworkInfo() 方法返回一个 NetworkInfo 实例,它表示它可以找到的第一个连接的网络接口,如果没有任何接口连接,则返回 null。检查此方法是否返回 null 应该足以判断 Internet 连接是否可用。

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

您还需要:

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

在您的 android 清单中。

编辑:

请注意,拥有活动的网络接口并不能保证特定的网络服务可用。网络问题、服务器停机、低信号、强制门户、内容过滤器等都会阻止您的应用程序到达服务器。例如,在您收到来自 Twitter 服务的有效响应之前,您无法确定您的应用是否可以访问 Twitter。

【讨论】:

如果有人(不必要地)在进行 http 调用之前尝试调用此函数,那么值得看看 connectiontimeout! :-) 为了安全起见我会return activeNetworkInfo != null &amp;&amp; activeNetworkInfo.isConnectedOrConnecting(); 如果你正在创建一个Utils 方法,即没有从Context 引用可用的地方访问它,你需要将Context 作为参数传递。 这不会检查手机是否连接到互联网。只是已经建立了网络连接。 @Mr.Hyde 不幸的是,没有。这种方式仅检查是否已建立网络连接,但不检查设备是否已连接到互联网。要真正了解活动的互联网连接,您应该使用 HttpURLConnection 到某个主机,ping 某个主机(例如 google.com)或尝试使用 InetAddress.getByName(hostName).isReachable(timeOut)【参考方案2】:

我检查 Wi-fi 和移动互联网如下...

private boolean haveNetworkConnection() 
    boolean haveConnectedWifi = false;
    boolean haveConnectedMobile = false;

    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo[] netInfo = cm.getAllNetworkInfo();
    for (NetworkInfo ni : netInfo) 
        if (ni.getTypeName().equalsIgnoreCase("WIFI"))
            if (ni.isConnected())
                haveConnectedWifi = true;
        if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
            if (ni.isConnected())
                haveConnectedMobile = true;
    
    return haveConnectedWifi || haveConnectedMobile;

显然,它可以很容易地修改以检查个别特定的连接类型,例如,如果您的应用需要潜在的更高速度的 Wi-fi 才能正常工作等。

【讨论】:

代码不错,我只是希望人们在编写java haveConnectedWifi,haveConnectedMobile时能坚持Java编码风格。我知道这是一件小事,但一致的代码更具可读性。 虽然在良好的实践中,最好将字符串放在左侧,如果不需要,最好不要使用 equalsIgnoreCase:if ("WIFI".equals(ni.getTypeName()))跨度> @Stuart Axon:哦,好吧,我想就是这样。自从我在 1970 年代后期开始编程以来,我编写的语言比我记得的要多,而且我显然已经养成了许多坏习惯。总的来说,我遵循的原则是,如果它有效,那么......好吧,它有效,这就是我所关心的。上面的代码 sn-p 是完全独立的,任何具有合理编程经验的人都可以轻松解决,并且(最重要的是)如果有人将其剪切并粘贴到他们自己的代码中,它会为他们工作。很抱歉成为 Android/Java 菜鸟。 不是在分数或任何东西之后(或者无论如何 SO 工作) - 我发现代码很有用,但我想我脾气暴躁的方式是试图提供一些半有用的反馈。 @BoD: getType() 提供了更精细的粒度(我相信)并且可能返回TYPE_MOBILETYPE_MOBILE_DUNTYPE_MOBILE_HIPRI 等等。我对可用的“移动”连接类型的细节不感兴趣,getTypeName() 只会为所有这些连接返回“移动”。【参考方案3】:

第 1 步:在您的项目中创建一个 AppStatus 类(您也可以提供任何其他名称)。 然后请将下面给出的行粘贴到您的代码中:

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;


public class AppStatus 

    private static AppStatus instance = new AppStatus();
    static Context context;
    ConnectivityManager connectivityManager;
    NetworkInfo wifiInfo, mobileInfo;
    boolean connected = false;

    public static AppStatus getInstance(Context ctx) 
        context = ctx.getApplicationContext();
        return instance;
    

    public boolean isOnline() 
        try 
            connectivityManager = (ConnectivityManager) context
                        .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        connected = networkInfo != null && networkInfo.isAvailable() &&
                networkInfo.isConnected();
        return connected;


         catch (Exception e) 
            System.out.println("CheckConnectivity Exception: " + e.getMessage());
            Log.v("connectivity", e.toString());
        
        return connected;
    

第 2 步:现在检查您的设备是否有网络连接,然后只需将此代码 sn-p 添加到您要检查的任何位置...

if (AppStatus.getInstance(this).isOnline()) 

    Toast.makeText(this,"You are online!!!!",8000).show();

 else 

    Toast.makeText(this,"You are not online!!!!",8000).show();
    Log.v("Home", "############################You are not online!!!!");    

【讨论】:

你真的需要检查isAvailable 吗?我认为isConnected 就足够了。 如果你将上下文传递给构造函数,为什么你需要在 isOnline 中这样做? 这会使我的手机崩溃。这在 2014 年 6 月仍然有效吗? @AlexanderMalakhov 实际上 isAvailable 应该是第一个检查。我发现如果有连接接口可用,那就是true。有时(例如,启用 '限制后台数据' 设置时)isConnected 可以是false 表示接口没有活动连接,但isAvailable 为 true 表示接口是可用,您可以建立连接(例如,传输前台数据)。 我做了一个简单的测试。我从路由器中拔出输入以太网电缆,然后调用此方法。因此设备已连接到 WI-Fi,但 Wifi 本身未连接到互联网。你猜怎么了!即便如此,它还是返回了真实。因此,如果我想确保该设备已连接到互联网,我会 ping 一个知名网站,而不是检查这个。【参考方案4】:

还有一个重要的注意事项。您必须在 AndroidManifest.xml 中设置 android.permission.ACCESS_NETWORK_STATE 才能使其正常工作。

_ 我怎么能在在线文档中找到我需要的信息?

您只需正确阅读这些类的文档,您就会找到您正在寻找的所有答案。查看ConnectivityManager 上的文档。描述告诉你该怎么做。

【讨论】:

ConnectivityManager 类的描述并没有告诉我如何使用该类,它只是方法签名和常量值的列表。此问题的答案中的信息比该文档中的信息更多。没有提到 getActiveNetworkInfo() 可以返回 null 的事实,没有提到需要拥有 ACCESS_NETWORK_STATE 权限等。除了 Android 源之外,您在哪里找到此信息? 好点 dfjacobs。由于缺乏像样的食谱示例,*** 似乎是这些天的首选来源。 Requires the ACCESS_NETWORK_STATE permission. 声明为here。【参考方案5】:

ConnectivityManager 的 getActiveNetworkInfo() 方法返回一个 代表第一个连接网络的 NetworkInfo 实例 如果接口已连接,则它可以找到接口,如果没有,则为 null。 检查此方法是否返回 null 应该足以判断一个 互联网连接可用。

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

您还需要:

在你的 安卓清单。

编辑:

请注意,拥有活动的网络接口并不能保证 提供特定的网络服务。网络问题,服务器 停机时间、低信号、强制门户、内容过滤器等 都可以阻止您的应用程序到达服务器。比如你 无法确定您的应用是否可以访问 Twitter,直到您收到 来自 Twitter 服务的有效响应。

getActiveNetworkInfo() 不应该永远给 null。我不知道他们提出这个想法时在想什么。它应该总是给你一个对象。

【讨论】:

如果没有单个活动连接,您为什么希望它返回一个对象?【参考方案6】:

也许我找到了自己:

ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
return connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting();

【讨论】:

期望getActiveNetworkInfo() 在没有活动网络的情况下可以返回 null 例如飞行模式 是的,它会返回 null,这是未记录的。 是的,所以先做空检查 activeNetwork != null && activeNetwork.isConnectedOrConnecting(); 我喜欢这一行: boolean isWifiConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting() && activeNetwork.getType() == ConnectivityManager.TYPE_WIFI; 谁能更详细地解释这一行对我来说看起来很奇怪:first activeNetwork != null

以上是关于检测Android上是不是有可用的互联网连接[重复]的主要内容,如果未能解决你的问题,请参考以下文章

检查互联网数据是不是接收(Android)[重复]

在具有互联网数据速度的android中检查网络可用[重复]

Android - 检查用户连接的连接是不是有互联网连接[重复]

如何在android中检查当前的互联网连接是不是可用

如果在android中打开了移动设备或wifi,如何检查互联网是不是可用[重复]

检查互联网连接是不是可用[重复]