如何在安卓设备上检查当前是否有可用的互联网连接

54

我希望能够在离线情况下运行我的应用程序,因此我需要检查当前是否有可用的互联网连接。有人能告诉我如何在Android中检查是否有可用的互联网连接吗?请提供示例代码。我尝试了下面的代码并使用模拟器进行了检查,但它不起作用。

public  boolean isInternetConnection() 
{ 

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

谢谢

31个回答

101

这段代码可以判断你是否已连接到网络:

ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        
boolean connected = (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED || 
            connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED);

警告:如果您连接的是没有互联网访问或需要基于浏览器的身份验证的WiFi网络,则connected仍将为true。

您需要在清单中添加此权限:

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

2
嗨,我在我的Android 4.0应用程序中使用了相同的代码,但它会出现空指针异常。 - Vijay Bagul
2
顺便提一下,你还应该检查connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) != null,否则在某些平板电脑上可能会出现NullPointer。 - uncle Lem
2
阅读Android文档,链接在此:http://developer.android.com/reference/android/net/ConnectivityManager.html,显示上面的getNetworkInfo用法已被弃用,但该方法仍然存在,只是采用了不同的参数(一个网络而不是一个int)。 - Fat Monk
不需要 else 部分。 - suvojit_007
有人能解释一下 connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED 和 getNetworkInfo(..).isConnected() 两者之间的区别吗? - thahgr
显示剩余5条评论

29
你可以使用两种方法:
1- 检查连接:

2 - to execute a query :

2- 执行查询:
   private boolean NetworkIsConnected() {
        ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo() != null;
    }

2 - 用于检查互联网:

  public boolean InternetIsConnected() {
        try {
            String command = "ping -c 1 google.com";
            return (Runtime.getRuntime().exec(command).waitFor() == 0);
        } catch (Exception e) {
            return false;
        }
    }

在清单文件中添加权限:
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

1
正在寻找第二个,以检查互联网是否可用。谢谢。 - Muhammad Rafique
6
我用模拟器测试了版本2(API 24,权限已开启),但是它没有工作:虽然有网络/互联网连接,但代码会冻结应用程序(因此不要在主线程上运行!),大约10秒后返回“false”(没有异常)。我是否缺少需要使其正常工作的任何内容? - Neph

17

此外,请注意有时用户会连接到Wi-Fi网络,但该网络可能需要基于浏览器的身份验证。 大多数机场和酒店热点都是这样的,因此您的应用程序可能会被欺骗以为您已经连接上了互联网,然后任何URL获取实际上将检索热点的登录页面而不是您正在寻找的页面。

根据执行此检查的重要性,在检查ConnectivityManager连接的同时,我建议包含代码来检查它是否是有效的互联网连接,而不仅仅是一种幻觉。 您可以通过尝试从您的站点获取已知地址/资源(如1x1 PNG图像或1字节文本文件)来实现这一点。


2
感谢您的帖子,欢迎来到Stackoverflow。顺便说一句,您不应该在这里的帖子中包含个人签名。 - dave.c

14

使用以下代码:

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

如果 isNetworkAvailable() 返回 true,则表示有可用的网络连接,否则表示没有可用的网络连接。

在您的应用程序清单文件中需要添加以下uses-permission

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

13

API 29已弃用。

getActiveNetworkInfo从API 29开始被弃用。因此,我们只能在29以下的版本中使用它。

Kotlin中的新代码适用于所有API

fun isNetworkAvailable(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
   
    // For 29 api or above
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) ?: return false
        return when {
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ->    true
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ->   true
            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ->   true
            else ->     false
         }
    }
    // For below 29 api
    else {
        if (connectivityManager.activeNetworkInfo != null && connectivityManager.activeNetworkInfo!!.isConnectedOrConnecting) {
            return true
        }
    }
    return false
}

当我再次启用WiFi按钮时,仍会出现“capabilities == null”的情况,需要大约30秒钟才能出现“capabilities!= null”。 - famfamfam

11
public boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
        return true;
    } else {
        return false;
    }
}

谷歌建议使用此代码块来检查互联网连接。因为设备可能即使连接到WiFi,也没有互联网连接。


6

代码:

    fun isInternetConnection(): Boolean {
    var returnVal = false
    thread {
        returnVal = try {
            khttp.get("https://www.google.com/")
            true
        }catch (e:Exception){
            false
        }
    }.join()
    return returnVal
}

Gradle:

implementation 'io.karn:khttp-android:0.1.0'

我使用khttp,因为它非常易于使用。

所以在上面的代码中,如果它成功连接到google.com,则返回true,否则返回false。


这可以在Java上运行吗? - Clinton Canarias
是的,必须这样做。由于这是Kotlin语言,语法上会有一些细微的差异。不要忘记在gradle中添加khttp库。 - Sumanth Perambuduri
你的方法最棒的地方就是不需要上下文。+1 - Alaa AbuZarifa

5
使用以下代码:
public static boolean isNetworkAvaliable(Context ctx) {
    ConnectivityManager connectivityManager = (ConnectivityManager) ctx
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    if ((connectivityManager
            .getNetworkInfo(ConnectivityManager.TYPE_MOBILE) != null && connectivityManager
            .getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED)
            || (connectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI) != null && connectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI)
                    .getState() == NetworkInfo.State.CONNECTED)) {
        return true;
    } else {
        return false;
    }
}

请记住,在您的清单中需要加入以下行:

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

5

以下代码可检查所有版本的Android设备的网络可用性,包括Android 9.0及以上版本:

public static boolean isNetworkConnected(Context  context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
    // For 29 api or above
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
        return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ||
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
    } else return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

不要忘记在您的清单文件中添加网络状态权限。

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

另外,在该方法前添加 @SuppressWarnings( "deprecation" ) 可以避免 Android Studio 中的过时警告。


4
您可以尝试与远程主机建立TCP连接:
public boolean hostAvailable(String host, int port) {
  try (Socket socket = new Socket()) {
    socket.connect(new InetSocketAddress(host, port), 2000);
    return true;
  } catch (IOException e) {
    // Either we have a timeout or unreachable host or failed DNS lookup
    System.out.println(e);
    return false;
  }
}

然后:

boolean online = hostAvailable("www.google.com", 80);

需要API 19级才能使用此方法。 - Nagaraj Alagusundaram
这个不起作用。连接到没有互联网的WiFi网络时,它仍然返回true。 - Gayal Rupasinghe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接