在 Android 中判断网络是否连接可以通过以下几种方法,涵盖不同场景和需求:
1. ConnectivityManager 基础检测
使用 `ConnectivityManager` 获取当前网络状态:
java
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnected();
注意:`NetworkInfo` 在 API 29 中已被标记为废弃,推荐使用 `NetworkCapabilities`。
2. 基于 NetworkCapabilities(推荐 API 21+)
java
NetworkCapabilities nc = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean isConnected = nc != null &&
(nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR));
此方法能区分具体网络类型(Wi-Fi、蜂窝等),并支持 VPN 检测。
3. 网络变化广播
动态注册 `CONNECTIVITY_ACTION` 广播(需适配 Android 7.0+ 限制):
xml
广播接收器中通过 `ConnectivityManager` 获取最新状态。
4. 使用 LiveData 或 RxJava 实时监控
通过 `ProcessLifecycleOwner` 或其他生命周期组件观察网络状态变化,适用于 MVVM 架构:
kotlin
class NetworkLiveData : LiveData
private val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) { postValue(true) }
override fun onLost(network: Network) { postValue(false) }
}
}
5. 检查实际网络可达性
仅连接 Wi-Fi 但无外网访问时,可通过以下方式验证:
java
boolean isInternetAvailable() {
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress("8.8.8.8", 53), 1500);
socket.close();
return true;
} catch (IOException e) {
return false;
}
}
注意需在子线程执行,或使用 `OkHttp` 等库的异步请求。
扩展知识:
Android 10+ 限制:后台应用无法直接获取网络状态,需使用前台服务或 JobScheduler。
WorkManager 适配:在后台任务中通过 `Constraints.Builder.setRequiredNetworkType()` 指定网络条件。
隐私权限:从 Android 6.0 开始,检测网络状态不需要显式权限,但访问敏感信息(如 SSID)需 `ACCESS_FINE_LOCATION`。
常见误区:
仅检测 Wi-Fi 或蜂窝可能导致遗漏 VPN 或以太网连接。
未处理 `getActiveNetworkInfo` 返回 null 的情况会导致崩溃。
忽略 Android 版本差异,尤其是 API 23+ 的运行时权限和 API 29+ 的废弃方法。
实际开发中应根据业务需求综合使用上述方法,例如在应用启动时检测即时状态,同时注册响应动态变化。