在Android开发中,判断网络状态是应用实现网络功能的基础步骤,开发者需要准确获取当前网络的连接情况(如是否可用、网络类型等),以优化用户体验并避免因网络问题导致的异常,Android系统提供了多种方式来实现网络状态判断,主要涉及ConnectivityManager、NetworkRequest、NetworkCallback等API,同时需注意适配不同Android版本(尤其是Android 6.0以上权限变更)。

传统方式:使用ConnectivityManager
ConnectivityManager是Android中管理网络连接的核心服务,通过它可以查询当前活动的网络信息,基本使用步骤如下:
- 获取ConnectivityManager实例:
通过getSystemService(Context.CONNECTIVITY_SERVICE)获取系统服务。 - 检查网络是否可用:
调用getActiveNetwork()获取当前活动的网络对象,若返回null则表示无网络连接;进一步通过getNetworkCapabilities()获取网络能力(如是否可连接、是否支持WiFi/移动数据等)。 - 判断网络类型:
通过NetworkCapabilities.hasTransport(int transport)判断具体网络类型,如TRANSPORT_WIFI(WiFi)、TRANSPORT_CELLULAR(移动数据)、TRANSPORT_ETHERNET(有线网络)等。
示例代码片段:
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network network = cm.getActiveNetwork();
if (network != null) {
NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);
if (capabilities != null) {
boolean isWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
boolean isCellular = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
Log.d("NetworkState", "WiFi: " + isWifi + ", Cellular: " + isCellular);
}
} else {
Log.d("NetworkState", "No network available");
}
监听网络状态变化
除了主动查询,应用还需实时监听网络状态变化,以便及时响应,传统方式是通过BroadcastReceiver监听CONNECTIVITY_ACTION广播,但Android 7.0以上系统限制了静态注册广播的使用,推荐动态注册或使用更现代的NetworkCallback。
动态注册BroadcastReceiver
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 重新调用ConnectivityManager查询网络状态
}
}, filter);
使用NetworkCallback(推荐,Android 21+)
NetworkCallback是API 21引入的回调机制,支持更精细的网络状态监听,包括网络可用、丢失、能力变化等,需通过registerNetworkRequest()注册网络请求,系统会通过回调通知状态变化。

示例代码:
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build();
cm.registerNetworkCallback(request, new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
Log.d("NetworkCallback", "Network available");
}
@Override
public void onLost(Network network) {
Log.d("NetworkCallback", "Network lost");
}
});
网络状态判断的注意事项
- 权限申请:
Android 6.0以上需动态申请ACCESS_NETWORK_STATE权限(查询网络状态),若需访问具体网络信息(如MAC地址)可能需要ACCESS_WIFI_STATE权限。 - 网络类型区分:
移动数据可能包含2G/3G/4G/5G,需通过TelephonyManager进一步判断;WiFi需注意是否连接到热点。 - 无网络与网络不可用:
“无网络”指无物理连接(如关闭WiFi和移动数据),“网络不可用”指有连接但无法访问互联网(如 captive portal),需结合NetworkCapabilities.NET_CAPABILITY_VALIDATED判断网络是否可用。
常见网络状态判断场景对比
| 场景 | 判断方法 |
|---|---|
| 检查是否有网络连接 | ConnectivityManager.getActiveNetwork() != null |
| 判断是否为WiFi | NetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) |
| 判断是否为移动数据 | NetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) |
| 判断网络是否可访问互联网 | NetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) |
相关问答FAQs
Q1:为什么在Android 10以上设备上,ConnectivityManager.getActiveNetwork()总是返回null?
A:可能原因有两个:一是应用未声明INTERNET权限或权限被拒绝;二是Android 10以上系统对后台网络访问进行了限制,若应用在后台运行且未满足条件(如未开启“后台数据”权限),系统可能限制网络访问,需确保权限正常,且在清单文件中声明INTERNET权限。
Q2:如何区分WiFi和移动数据网络,并在切换时执行不同逻辑?
A:可通过NetworkCallback监听网络变化,在onAvailable()回调中通过NetworkCapabilities的hasTransport()方法判断网络类型。
@Override
public void onAvailable(Network network) {
NetworkCapabilities caps = cm.getNetworkCapabilities(network);
if (caps != null) {
if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
// 执行WiFi相关逻辑
} else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
// 执行移动数据相关逻辑
}
}
}
