一、创建广播接收器
首先,我们需要创建一个广播接收器(BroadcastReceiver
),用于接收系统发出的网络变化广播。在本例中,我们创建了一个名为ConnectReceiver
的广播接收器。
public class ConnectReceiver extends BroadcastReceiver {
public final static String TAG = "ConnectReceiver";
// ...其他代码...
}
二、注册广播接收器
在Android 7.0(API 24)及以上版本中,静态注册的网络变化广播接收器将不再生效。因此,我们需要在代码中动态注册广播接收器。在本例中,我们在registerReceiver()
方法中注册了ConnectReceiver
。
public static void registerReceiver() {
try {
if (haveRegisted) {
return;
}
ConnectReceiver mConnectReceiver = new ConnectReceiver();
IntentFilter filter = new IntentFilter();
filter.setPriority(Integer.MAX_VALUE);
filter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
WwUtil.APPLICATION_CONTEXT.registerReceiver(
mConnectReceiver, filter);
haveRegisted = true;
} catch (Throwable e) {
Log.w(TAG, "registerReceiver err:", e);
}
}
在这个方法中,我们创建了一个IntentFilter
对象,并设置了监听的网络变化广播。然后,我们使用registerReceiver()
方法将ConnectReceiver
注册为广播接收器。注意,我们需要在调用这个方法的地方确保已经获取到了应用的Context
对象。
三、处理网络变化
当网络发生变化时,系统会发出相应的广播,我们的ConnectReceiver
将会接收到这些广播并调用onReceive()
方法。在这个方法中,我们可以处理网络变化。
@Override
public void onReceive(Context context, final Intent intent) {
// 将网络状态变化的处理放在后台线程中运行,以避免阻塞主线程
ThreadUtils.runOnBackground(new Runnable() {
@Override
public void run() {
try {
// 如果 intent 为空或者 action 为空,直接返回
if (intent == null || intent.getAction() == null)
return;
long startTime = System.currentTimeMillis();
boolean isNetWorkChange = false;
boolean isNetworkConnected = false;
boolean isVpnChange = false;
// 如果 mNetworkChangeMgr 为空,创建一个新的 NetworkChangeMgr 对象
if (mNetworkChangeMgr == null) {
mNetworkChangeMgr = new NetworkChangeMgr();
}
// 获取网络状态变化的 action
String networkStateChangedAction = WifiManager.NETWORK_STATE_CHANGED_ACTION;
// 判断收到的广播是否为网络状态变化的广播
if (android.net.ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())
|| (!TextUtils.isEmpty(networkStateChangedAction) && networkStateChangedAction.equals(intent.getAction()))) {
// 检查网络是否发生了变化
isNetWorkChange = mNetworkChangeMgr.isNetWorkChange(SharedPreferenceUtil.hasAgreedPrivacy());
// 检查 VPN 是否发生了变化
isVpnChange = mNetworkChangeMgr.isVpnChange();
// 如果网络状态或 VPN 状态发生了变化
if (isNetWorkChange || isVpnChange) {
// 检查当前是否有网络连接
isNetworkConnected = NetworkUtil.isNetworkConnected();
// 检查当前是否连接到 Wi-Fi
final boolean isWifi = mNetworkChangeMgr.isCurrentWifi();
// 如果当前有网络连接,更新统计数据中的 Wi-Fi 状态
if (isNetworkConnected) {
StatisticsUtil.setIsWifi(isWifi);
}
}
}
} catch (Throwable e) {
Log.w(TAG, "onReceive", e);
}
}
});
}
在onReceive()
方法中,我们首先判断收到的广播是否是我们关心的网络变化广播。如果是,我们通过NetworkChangeMgr
对象来判断网络是否发生了变化。如果网络确实发生了变化,我们可以在这里进行相应的处理,例如更新UI或者重新请求数据等。
四、如何判断网络变化
本节讲述isNetWorkChange
是如何实现判断网络是否有变化的。下面是isNetWorkChange
实现的流程图。
我们首先判断当前网络类型和最后一次记录的网络类型是否相同。
如果不相同,我们会检查最后一次的网络类型是否为初始状态;如果是初始状态,则认为网络没有变化,否则认为网络发生了变化。
如果网络类型相同,我们会根据当前网络类型是WiFi还是移动数据进行不同的判断。
- 对于WiFi,我们会检查当前和最后一次的WiFi信息是否都不为空,然后判断WiFi的BSSID、SSID和NetworkId是否都相同。
- 对于移动数据,我们会判断网络的ExtraInfo、Subtype和Type是否都相同。根据这些判断结果,我们可以得出网络是否发生了变化。
五、总结
本文介绍了如何在Android中监听网络变化。首先,创建一个广播接收器(BroadcastReceiver
)来接收系统发出的网络变化广播。然后,在代码中动态注册广播接收器,并设置监听的网络变化广播。当网络发生变化时,系统会发出相应的广播,广播接收器将接收到这些广播并调用onReceive()
方法,在这个方法中可以处理网络变化。
为了判断网络是否发生变化,我们需要比较当前网络类型和最后一次记录的网络类型,如果不同则认为网络发生了变化。如果网络类型相同,还需要进一步比较网络的详细信息,如WiFi的BSSID、SSID和NetworkId,或者移动数据的ExtraInfo、Subtype和Type,只有在所有这些详细信息都相同时,才认为网络没有发生变化。最后,更新上一次记录的网络类型、网络信息等。