睿诚科技协会

Android如何判断当前网络状态?

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

Android如何判断当前网络状态?-图1
(图片来源网络,侵删)

传统方式:使用ConnectivityManager

ConnectivityManager是Android中管理网络连接的核心服务,通过它可以查询当前活动的网络信息,基本使用步骤如下:

  1. 获取ConnectivityManager实例
    通过getSystemService(Context.CONNECTIVITY_SERVICE)获取系统服务。
  2. 检查网络是否可用
    调用getActiveNetwork()获取当前活动的网络对象,若返回null则表示无网络连接;进一步通过getNetworkCapabilities()获取网络能力(如是否可连接、是否支持WiFi/移动数据等)。
  3. 判断网络类型
    通过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()注册网络请求,系统会通过回调通知状态变化。

Android如何判断当前网络状态?-图2
(图片来源网络,侵删)

示例代码

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");
    }
});

网络状态判断的注意事项

  1. 权限申请
    Android 6.0以上需动态申请ACCESS_NETWORK_STATE权限(查询网络状态),若需访问具体网络信息(如MAC地址)可能需要ACCESS_WIFI_STATE权限。
  2. 网络类型区分
    移动数据可能包含2G/3G/4G/5G,需通过TelephonyManager进一步判断;WiFi需注意是否连接到热点。
  3. 无网络与网络不可用
    “无网络”指无物理连接(如关闭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()回调中通过NetworkCapabilitieshasTransport()方法判断网络类型。

@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)) {
            // 执行移动数据相关逻辑
        }
    }
}
Android如何判断当前网络状态?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇