检测Android上是否有可用的Internet连接

dan*_*dan 667 android internet-connection android-internet

我需要检测Android设备是否已连接到Internet.

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

问题是:

NetworkInfo ni = new NetworkInfo();
if (!ni.isAvailable()) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

抛出此错误:

The constructor NetworkInfo is not visible.
Run Code Online (Sandbox Code Playgroud)

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

  1. 如何让上面的代码段工作?
  2. 我怎么能找到自己在在线文档中需要的信息?
  3. 你能为这种类型的检测提出更好的方法吗?

Ale*_*min 1383

返回表示它可以找到的第一个连接的网络接口的实例的getActiveNetworkInfo()方法,或者没有连接任何接口的方法.检查此方法是否返回应足以判断是否有可用的Internet连接.ConnectivityManagerNetworkInfonullnull

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
          = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
Run Code Online (Sandbox Code Playgroud)

您还需要:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Run Code Online (Sandbox Code Playgroud)

在你的Android清单中.

编辑:

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

  • 为了安全起见,我将`返回activeNetworkInfo!= null && activeNetworkInfo.isConnectedOrConnecting();` (133认同)
  • 这不会检查手机是否已连接到互联网.只有网络连接已经完成. (35认同)
  • @ Mr.Hyde不幸的是,没有.这种方式只检查是否已建立网络连接,但不检查该设备是否已连接到互联网.要真正了解有效的互联网连接,您应该将HttpURLConnection用于某些主机,ping某些主机(例如google.com)或尝试使用InetAddress.getByName(hostName).isReachable(timeOut) (21认同)
  • 如果你正在创建一个`Utils`方法,即不从`Context`引用可用的地方访问它,你需要传递`Context`作为参数. (17认同)
  • 如果有人(不必要的话)值得一看[connectiontimeout](http://stackoverflow.com/questions/693997/how-to-set-httpresponse-timeout-for-android-in-java/1565243#1565243) )在进行http调用之前尝试调用此函数!:-) (6认同)
  • 我测试了这个,如果你有wifi但没有互联网连接会产生误报.这个答案似乎有误导性. (6认同)
  • 即使没有可用的连接,它也会返回"true" (4认同)
  • 我做了一个简单的测试.我从路由器中取出输入以太网电缆,然后调用此方法.因此该设备已连接到WI-Fi,但Wifi本身未连接到互联网.你猜怎么着!即便如此,它仍然是真的.因此,如果我想确保设备连接到互联网,我会ping一个知名网站,而不是检查这个. (4认同)
  • @daveogrady 所做的就是抑制警告。 (3认同)
  • @JeffAxelrod,我猜你添加了"!= null","isConnectedOrConnecting"不正确,因为我们想知道我们是否有互联网连接,而在连接时,我们没有互联网连接. (2认同)
  • ConnectivityManager还不够,要知道您是否可以访问互联网,就必须对其进行测试!最好的答案是:/sf/answers/1911874611/ (2认同)
  • @JeffAxelrod`isConnectedOrConnecting()`在API级别28中已弃用. (2认同)
  • 在 API 29 中已弃用 (2认同)

Squ*_*onk 241

我检查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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Stuart Axon:噢,这就是我想的.自从我在1970年代后期开始以来,我编写了比我记忆中更多的语言,我显然已经养成了许多不良习惯.总的来说,我坚持的原则是,如果它有效,那么......好吧,它有效,这就是我所关心的.上面的代码片段是完全独立的,任何具有合理编程经验的人都可以轻松地完成工作,并且(最重要的是)如果有人将其剪切并粘贴到他们自己的代码中,那么它们将适用于他们.很抱歉成为Android/Java菜鸟. (71认同)
  • 代码很好,我只是希望人们在编写java hasConnectedWifi,hasConnectedMobile时坚持Java编码风格.我知道这是一件小事,但一致的代码更具可读性. (25认同)
  • 虽然在良好的实践中最好让左边的String,如果你不需要使用equalsIgnoreCase:if("WIFI".equals(ni.getTypeName())) (6认同)
  • @BoD:`getType()`提供更精细的粒度级别(我相信)并且可能返回`TYPE_MOBILE`,`TYPE_MOBILE_DUN`,`TYPE_MOBILE_HIPRI`等等.我对什么类型的"移动"连接可用的细节不感兴趣,而`getTypeName()`只会为所有这些连接返回'MOBILE'. (4认同)
  • 不是点数或任何东西(或SO工作) - 我发现代码有用,但我想我的脾气暴躁的方式是试图提供一些半有用的反馈. (2认同)

Viv*_*har 73

第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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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!!!!");    
}
Run Code Online (Sandbox Code Playgroud)

  • 你真的需要检查`isAvailable`吗?我认为`isConnected`就足够了. (6认同)
  • @AlexanderMalakhov实际上`isAvailable`应该是第一次检查.我发现如果连接接口可用,则为"true".有时(例如,当*'限制后台数据'*设置被启用时)`isConnected`可以是'false`表示接口没有活动连接但是`isAvailable`为真意味着接口可用并且您可以建立连接(例如,传输前景数据). (4认同)
  • 我做了一个简单的测试.我从路由器中取出输入以太网电缆,然后调用此方法.因此该设备已连接到WI-Fi,但Wifi本身未连接到互联网.你猜怎么着!即便如此,它仍然是真的.因此,如果我想确保设备连接到互联网,我会ping一个知名网站,而不是检查这个. (2认同)

Oct*_*ean 14

另一个重要的说明.您必须android.permission.ACCESS_NETWORK_STATE在AndroidManifest.xml中设置才能使用此功能.

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

您只需要正确阅读课程文档,您就可以找到所需的所有答案.查看ConnectivityManager上的文档.说明会告诉您该怎么做.

  • ConnectivityManager类的描述告诉我如何使用该类,它只是方法签名和常量值的列表.这个问题的答案中的信息比该文档中的信息更多.没有提到getActiveNetworkInfo()可以返回null的事实,没有提到需要ACCESS_NETWORK_STATE权限等等.除了Android源之外,你究竟在哪里找到这个信息? (11认同)
  • 好点dfjacobs.Stackoverflow似乎是缺乏正确的食谱示例的goto源. (3认同)

小智 10

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

private boolean isNetworkAvailable() {
     ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
     return activeNetworkInfo != null; 
}
Run Code Online (Sandbox Code Playgroud)

您还需要:

在你的Android清单中.

编辑:

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

getActiveNetworkInfo()不应该永远不会给null.当他们提出这个问题时,我不知道他们在想什么.它应该总是给你一个对象.


dan*_*dan 8

可能我发现自己:

ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
return connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting();
Run Code Online (Sandbox Code Playgroud)

  • 如果没有活动网络,例如飞行模式,则期望`getActiveNetworkInfo()`可以返回null (10认同)
  • 是的,它将返回null,这是没有记录的. (3认同)