睿诚科技协会

android判断网络连接

在Android开发中,判断网络连接状态是常见的需求,无论是实时监控网络变化还是在执行网络请求前检查可用性,都涉及到网络连接的判断,Android系统提供了多种方式来实现这一功能,开发者可以根据具体需求选择合适的方案,以下是关于Android判断网络连接的详细说明。

android判断网络连接-图1
(图片来源网络,侵删)

使用ConnectivityManager检查网络状态

ConnectivityManager是Android系统中管理网络连接的核心类,通过它可以获取当前设备的网络状态信息,要使用ConnectivityManager,首先需要获取系统的网络服务,然后调用其方法来判断网络类型和可用性,需要注意的是,从Android 6.0(API 23)开始,获取网络状态需要申请ACCESS_NETWORK_STATE权限,并且在Android 9.0(API 28)以上,明流量(HTTP)被限制,建议使用HTTPS。

获取ConnectivityManager实例

在Activity或Service中,可以通过以下代码获取ConnectivityManager:

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

检查网络是否可用

使用getNetworkCapabilities方法(推荐,API 21及以上)或getActiveNetworkInfo方法(已废弃,但兼容性更好)来获取当前活动的网络信息,以下是两种方式的示例:

  • 使用getNetworkCapabilities(推荐)

    android判断网络连接-图2
    (图片来源网络,侵删)
    if (connectivityManager != null) {
      Network network = connectivityManager.getActiveNetwork();
      NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
      if (capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || 
          capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || 
          capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))) {
          // 网络可用
      } else {
          // 网络不可用
      }
    }
  • 使用getActiveNetworkInfo(兼容旧版本)

    if (connectivityManager != null) {
      NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
      if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
          // 网络可用
      } else {
          // 网络不可用
      }
    }

监听网络状态变化

除了手动检查网络状态,还可以通过监听网络变化来实现实时更新,Android提供了ConnectivityManager.NetworkCallback类来注册网络状态监听器,这种方式在API 21及以上版本中推荐使用。

注册网络监听器

ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        // 网络可用
    }
    @Override
    public void onLost(Network network) {
        // 网络丢失
    }
};
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest networkRequest = new NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
        .build();
connectivityManager.registerNetworkCallback(networkRequest, networkCallback);

取消监听器

在不需要监听时,记得取消注册以避免内存泄漏:

connectivityManager.unregisterNetworkCallback(networkCallback);

判断网络类型

有时候需要区分当前网络是Wi-Fi还是移动数据,可以通过以下方式实现:

android判断网络连接-图3
(图片来源网络,侵删)

使用NetworkCapabilities判断

if (capabilities != null) {
    if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
        // 当前是Wi-Fi网络
    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
        // 当前是移动数据网络
    }
}

使用NetworkInfo判断(旧版本)

if (activeNetworkInfo != null) {
    int type = activeNetworkInfo.getType();
    if (type == ConnectivityManager.TYPE_WIFI) {
        // 当前是Wi-Fi网络
    } else if (type == ConnectivityManager.TYPE_MOBILE) {
        // 当前是移动数据网络
    }
}

处理网络权限和异常

在Android 6.0及以上版本,运行时权限管理要求动态申请ACCESS_NETWORK_STATE权限,如果网络不可用,需要提示用户或采取相应的降级处理措施,以下是权限申请的示例:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) 
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, 
            new String[]{Manifest.permission.ACCESS_NETWORK_STATE}, 
            REQUEST_CODE_NETWORK_STATE);
}

网络状态判断的常见场景

在实际开发中,网络状态判断通常用于以下场景:

  1. 网络请求前检查:在发起HTTP请求前,先检查网络是否可用,避免无网络时的无效请求。
  2. 实时网络监控:在视频播放、文件下载等场景中,实时监控网络状态,根据网络质量调整策略(如切换清晰度、暂停下载等)。
  3. 用户体验优化:当网络不可用时,提示用户检查网络设置,或切换到离线模式。

网络状态判断的注意事项

  1. 主线程限制:网络相关的操作不能在主线程中执行,需要放在子线程或使用异步任务(如AsyncTask、RxJava、Coroutine等)。
  2. 权限处理:确保在AndroidManifest.xml中声明ACCESS_NETWORK_STATE权限,并在运行时动态申请(针对Android 6.0及以上)。
  3. 网络类型判断的准确性:某些设备可能同时存在多种网络连接(如Wi-Fi和移动数据),此时需要明确判断当前使用的网络类型。

网络状态判断的代码示例

以下是一个完整的示例,展示如何检查网络状态并监听变化:

public class NetworkUtils {
    public static 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.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || 
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || 
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
        }
        return false;
    }
    public static void registerNetworkCallback(Context context, ConnectivityManager.NetworkCallback callback) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager != null) {
            NetworkRequest request = new NetworkRequest.Builder()
                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                    .build();
            connectivityManager.registerNetworkCallback(request, callback);
        }
    }
}

相关问答FAQs

问题1:为什么在Android 9.0以上使用HTTP请求会被阻止?
解答:从Android 9.0(API 28)开始,Google默认限制了明流量(HTTP)的使用,以提升应用的安全性,HTTP协议数据传输过程中是未加密的,容易被窃听或篡改,开发者应尽量使用HTTPS协议进行网络通信,确保数据传输的安全性,如果必须使用HTTP,需要在AndroidManifest.xml中添加android:usesCleartextTraffic="true"属性,但这会降低应用的安全性,不建议在生产环境中使用。

问题2:如何判断当前网络是否连接的是移动数据而非Wi-Fi?
解答:可以通过ConnectivityManager获取当前网络的NetworkCapabilities,然后检查是否包含TRANSPORT_CELLULAR类型,具体代码如下:

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
    Network network = connectivityManager.getActiveNetwork();
    NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
    if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
        // 当前是移动数据网络
    } else if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
        // 当前是Wi-Fi网络
    }
}
分享:
扫描分享到社交APP
上一篇
下一篇