如何通过编程检测WiFi/移动数据已开启但无互联网连接?
我来帮你搞定这个问题!你现在的代码只能检测到WiFi是否连接、移动数据开关是否打开,但没法判断「连接上了但实际没网」的情况——这确实是个常见的坑,下面给你分版本讲Android官方的解决方案:
解决方案分版本说明
Android 10(API 29)及以上:官方推荐方案
从这个版本开始,旧的NetworkInfo类已被标记为废弃,官方建议用ConnectivityManager结合NetworkCapabilities来判断真实的互联网连接。核心是检查两个关键能力:
NET_CAPABILITY_INTERNET:网络是否具备互联网访问能力NET_CAPABILITY_VALIDATED:网络是否已通过验证(比如WiFi完成了网页认证,不会出现连接后仍需登录的情况)
代码示例:
public static boolean hasValidInternet(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (cm == null) return false; Network activeNetwork = cm.getActiveNetwork(); if (activeNetwork == null) return false; NetworkCapabilities capabilities = cm.getNetworkCapabilities(activeNetwork); return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); }
Android 7.0(API 24)到API 28
这个区间可以用getNetworkCapabilities检测网络能力,虽然没有VALIDATED那么精准,但也能有效判断是否具备互联网访问权限:
public static boolean hasInternetAccess(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (cm == null) return false; NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); if (activeNetwork == null || !activeNetwork.isConnected()) return false; Network network = cm.getActiveNetwork(); NetworkCapabilities capabilities = cm.getNetworkCapabilities(network); return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); }
Android 6.0(API 23)及以下:Ping检测
对于更低版本,官方没有直接API判断真实联网状态,只能通过ping一个可靠的公共服务器(比如谷歌DNS 8.8.8.8,国内可选114.114.114.114)来验证。注意必须在子线程执行,避免阻塞主线程触发ANR:
public static boolean isInternetAvailable() { try { // 发送1次ping,超时1秒 Process pingProcess = Runtime.getRuntime().exec("ping -c 1 -W 1 8.8.8.8"); int exitCode = pingProcess.waitFor(); // exitCode为0表示ping成功,网络可达 return exitCode == 0; } catch (IOException | InterruptedException e) { e.printStackTrace(); } return false; }
必要权限
不管用哪种方案,都需要在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
补充说明
NET_CAPABILITY_VALIDATED是API 23引入的,它能排除「连接了WiFi但需网页认证才能上网」的场景,比单纯判断INTERNET更准确。- 执行ping操作时一定要放在子线程,比如用AsyncTask、Coroutine(Kotlin)或者线程池处理,绝对不能在主线程运行。
内容的提问来源于stack exchange,提问作者Gajanand Swamy
相关产品推荐
相关产品推荐

