上一篇
安卓判断网络改变
- 行业动态
- 2025-04-24
- 6
在Android中,可通过ConnectivityManager获取当前Network对象,注册NetworkCallback监听网络状态变化,在onAvailable()和onLost()回调中处理网络连接/断开事件,需注意动态注册及后台
安卓判断网络改变的实现方法
监听网络状态的核心思路
安卓系统提供多种方式监听网络变化,核心是通过 ConnectivityManager
配合 广播接收器 或 NetworkCallback
实现,以下是两种主流方案:
方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
BroadcastReceiver |
兼容低版本(API < 21) | 简单易用,兼容性好 | 延迟较高,无法实时感知网络变化 |
NetworkCallback |
现代方案(API >= 21) | 实时性强,精准控制 | 需适配低版本,代码稍复杂 |
实现方案详解
使用 BroadcastReceiver
监听网络广播
步骤:
- 定义
BroadcastReceiver
子类,处理android.net.conn.CONNECTIVITY_CHANGE
广播。 - 在
AndroidManifest.xml
中注册接收器(或动态注册)。 - 通过
ConnectivityManager
获取当前网络状态。
代码示例:
// 1. 定义广播接收器 public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { // 获取当前网络状态 ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); boolean isConnected = networkInfo != null && networkInfo.isConnected(); // 根据需求处理网络变化 } } } // 2. 在 Manifest 中注册(静态注册) <receiver android:name=".NetworkChangeReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> // 3. 动态注册(推荐在 Activity 或 Service 中) IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(new NetworkChangeReceiver(), filter);
注意事项:
- 需在
AndroidManifest.xml
中声明权限:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 静态注册的广播在应用退出后仍会监听,动态注册需手动管理生命周期。
使用 NetworkCallback
(API >= 21)
步骤:
- 通过
ConnectivityManager.registerNetworkCallback
注册回调。 - 在回调中处理网络可用性变化。
代码示例:
public class NetworkMonitor { private ConnectivityManager connectivityManager; private NetworkRequest networkRequest; private NetworkCallback networkCallback; public NetworkMonitor(Context context) { connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); networkRequest = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(); networkCallback = new NetworkCallback(); } public void startListening() { connectivityManager.registerNetworkCallback(networkRequest, networkCallback); } public void stopListening() { connectivityManager.unregisterNetworkCallback(networkCallback); } private class NetworkCallback extends ConnectivityManager.NetworkCallback { @Override public void onAvailable(Network network) { super.onAvailable(network); // 网络可用时的逻辑 } @Override public void onLost(Network network) { super.onLost(network); // 网络丢失时的逻辑 } } }
优势:
- 实时性强,可精确感知网络变化。
- 支持自定义网络能力(如仅监听 Wi-Fi 或移动网络)。
网络类型判断
通过 NetworkCapabilities
判断当前网络类型:
Network network = cm.getActiveNetwork(); NetworkCapabilities capabilities = cm.getNetworkCapabilities(network); if (capabilities != null) { if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { // 当前是 Wi-Fi } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { // 当前是移动数据 } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) { // 当前是有线网络 } }
常见问题与解答
问题 1:如何获取当前网络类型(Wi-Fi/移动数据/蓝牙等)?
解答:
通过 ConnectivityManager.getNetworkCapabilities(Network)
获取网络能力,结合 hasTransport()
方法判断类型。
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { // Wi-Fi 网络 }
问题 2:如何在网络变化时执行异步任务(如重新发起请求)?
解答:
在网络回调中结合 Handler
或 ExecutorService
执行异步操作。
@Override public void onAvailable(Network network) { // 延迟 1 秒后执行任务 new Handler(Looper.getMainLooper()).postDelayed(() -> { // 重新发起网络请求 }, 1000); }
权限与兼容性注意事项
权限 | 作用 | 是否需要动态申请 |
---|---|---|
ACCESS_NETWORK_STATE |
获取网络状态信息 | 否 |
INTERNET |
访问网络 | 否(仅判断状态时) |
ACCESS_WIFI_STATE |
获取 Wi-Fi 状态(可选) | 否 |
低版本兼容:
- API < 21 的设备需使用
BroadcastReceiver
。 - 若需同时兼容高低版本,可封装监听逻辑,根据系统版本选择实现方式