睿诚科技协会

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

在Android开发中,判断网络状态是应用开发中的常见需求,例如确保应用在有网络连接时才能加载数据,或者在网络切换时提示用户,Android系统提供了多种方式来检测网络状态,包括使用ConnectivityManager、NetworkCallback、TelephonyManager等API,同时还需要考虑网络权限、不同Android版本的兼容性以及网络类型(如Wi-Fi、移动数据)的区分,以下将详细介绍Android中判断网络状态的方法及实现细节。

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

使用ConnectivityManager判断网络状态

ConnectivityManager是Android系统中管理网络连接的核心类,通过它可以获取当前网络的状态、类型以及是否可用等信息,在Android 6.0(API 23)之前,可以通过getNetworkInfo()方法直接获取NetworkInfo对象来判断网络状态;但在Android 6.0及之后,该方法已被废弃,推荐使用getActiveNetwork()和getNetworkCapabilities()来获取网络信息。

基本网络状态检查

需要在AndroidManifest.xml中添加网络权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

在代码中通过ConnectivityManager获取网络状态:

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
    // 获取当前活动的网络
    Network network = connectivityManager.getActiveNetwork();
    if (network != null) {
        // 获取网络能力
        NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
        if (capabilities != null) {
            // 检查是否有网络连接
            boolean isConnected = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                                  capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
            // 检查网络类型
            boolean isWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
            boolean isMobile = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
            // 根据需求处理网络状态
        }
    }
}

兼容旧版本的实现

对于Android 6.0以下的版本,可以使用getNetworkInfo()方法:

Android如何判断当前网络状态?-图2
(图片来源网络,侵删)
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        // 网络可用
    }
}

网络状态变化监听

为了实时监听网络状态的变化,可以使用ConnectivityManager.NetworkCallback,在Android 7.0(API 24)及以上,可以通过registerNetworkCallback()方法注册回调:

ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        // 网络可用
    }
    @Override
    public void onLost(Network network) {
        // 网络丢失
    }
    @Override
    public void onCapabilitiesChanged(Network network, NetworkCapabilities capabilities) {
        // 网络能力变化
    }
};
// 注册回调
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest request = new NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .build();
connectivityManager.registerNetworkCallback(request, networkCallback);
// 在不需要时注销回调
connectivityManager.unregisterNetworkCallback(networkCallback);

使用TelephonyManager判断移动网络状态

如果需要判断移动数据网络的状态(如是否开启、当前网络类型等),可以使用TelephonyManager,需要注意的是,从Android 6.0开始,访问TelephonyManager需要申请READ_PHONE_STATE权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

示例代码:

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
    // 检查移动数据是否开启(需要Android 6.0及以上)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        Network activeNetwork = connectivityManager.getActiveNetwork();
        NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
        boolean isMobileData = capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
    }
    // 获取当前网络类型(2G/3G/4G/5G)
    int networkType = telephonyManager.getNetworkType();
    // 可以通过TelephonyManager.NetworkType判断具体网络类型
}

网络状态判断的注意事项

  1. 权限处理:从Android 6.0开始,部分网络权限需要动态申请,如ACCESS_NETWORK_STATE是普通权限,而READ_PHONE_STATE是危险权限,需要运行时申请。
  2. 多网络适配:Android设备可能同时连接多个网络(如Wi-Fi和移动数据),需要明确判断当前活跃的网络。
  3. 后台网络限制:Android系统对后台网络访问有限制,尤其是Android 10(API 29)及以上版本,需要在后台执行网络任务时考虑使用WorkManager或JobScheduler。
  4. 网络类型区分:区分Wi-Fi、移动数据、VPN等网络类型,可以通过NetworkCapabilities的TRANSPORT常量判断。

网络状态判断的常见场景与代码示例

检查是否有网络连接

public boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        Network network = connectivityManager.getActiveNetwork();
        NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
        return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    }
    return false;
}

检查当前是否为Wi-Fi连接

public boolean isWifiConnected(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        Network network = connectivityManager.getActiveNetwork();
        NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
        return capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
    }
    return false;
}

网络状态变化监听(兼容旧版本)

对于Android 6.0以下的版本,可以使用BroadcastReceiver监听网络变化:

Android如何判断当前网络状态?-图3
(图片来源网络,侵删)
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 处理网络状态变化
    }
}, filter);

网络状态判断的表格总结

方法 适用版本 功能 注意事项
ConnectivityManager.getActiveNetwork() Android 6.0+ 获取当前活跃网络 需要ACCESS_NETWORK_STATE权限
ConnectivityManager.getNetworkCapabilities() Android 6.0+ 获取网络能力(如是否可上网、网络类型) 配合getActiveNetwork()使用
ConnectivityManager.NetworkCallback Android 7.0+ 监听网络状态变化 需要动态注册和注销
TelephonyManager.getNetworkType() Android 1.0+ 获取移动网络类型 需要READ_PHONE_STATE权限
BroadcastReceiver(监听CONNECTIVITY_ACTION) Android 1.0+ 兼容旧版本的监听方式 在Android 7.0后可能不准确

相关问答FAQs

Q1: 为什么在Android 6.0及以上版本中getNetworkInfo()方法被废弃?
A1: 因为getNetworkInfo()方法无法提供更详细的网络能力信息(如网络类型、是否可上网等),而NetworkCapabilities可以更精确地描述网络状态,同时支持IPv6、VPN等新型网络场景,因此推荐使用新的API。

Q2: 如何在Android应用中判断移动数据是否开启?
A2: 可以通过ConnectivityManager获取当前网络,然后检查NetworkCapabilities的TRANSPORT_CELLULAR是否可用,结合TelephonyManager的getNetworkType()可以进一步判断移动数据的具体类型(如4G、5G),需要注意的是,从Android 6.0开始,访问TelephonyManager需要申请READ_PHONE_STATE权限。

分享:
扫描分享到社交APP
上一篇
下一篇