Android如何检测真实可用的互联网连接,识别流量过期等无网场景?
Android 真实互联网可用性检测解决方案
你原来使用的ConnectivityManager判断方案仅能检测设备是否接入了网络节点(如WiFi热点、运营商基站),无法判断上层网络是否真的具备互联网访问能力,属于Android网络开发的常见场景问题,可通过以下两种方案解决:
方案1:主动探测公共可靠服务节点(全版本兼容,准确率最高)
主动发起一个超轻量的HTTP HEAD/GET请求,访问行业通用的探测地址,这类地址设计为返回空内容、响应速度极快,仅消耗不到1KB流量,探测超时设置为2秒即可,不会增加过多等待时间。
通用探测地址可选:
- 国内环境:
http://223.5.5.5/generate_204(阿里公共DNS探测地址)、http://www.baidu.com/robots.txt - 海外环境:
http://clients3.google.com/generate_204
参考代码:
// 必须在子线程调用 public boolean isInternetAvailable() { try { // 可根据业务需要调整超时时间 int timeoutMs = 2000; Socket socket = new Socket(); socket.connect(new InetSocketAddress("223.5.5.5", 80), timeoutMs); socket.close(); return true; } catch (IOException e) { return false; } }
如果需要更精准的HTTP层探测,可以替换为发送HEAD请求检测204/200状态码。
方案2:使用系统自带网络校验能力(Android 6.0+ 支持,无需额外发请求)
Android 6.0及以上版本系统会自动对当前活跃网络做互联网可用性校验,你可以直接读取系统校验结果,不需要自己发起请求:
public boolean isInternetAvailable(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { Network activeNetwork = cm.getActiveNetwork(); NetworkCapabilities capabilities = cm.getNetworkCapabilities(activeNetwork); return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); } else { // 低版本降级使用旧方案或者走方案1的主动探测 NetworkInfo nInfo = cm.getActiveNetworkInfo(); return nInfo != null && nInfo.isAvailable() && nInfo.isConnected(); } }
注意事项
- 所有网络相关操作必须在子线程执行,禁止在主线程调用否则会触发ANR错误
- 主动探测的超时时间不要设置过长,1~3秒即可,避免影响业务请求的发起效率
- 不要高频重复探测,建议仅在业务请求发起前执行一次,或者网络状态切换时才重新探测
内容的提问来源于stack exchange,提问作者Yo Daniel
相关产品推荐
相关产品推荐

