如何对 Android 11 进行网络状态监听
作者:Changing Lin
- 2021 年 12 月 07 日
本文字数:3001 字
阅读完需:约 10 分钟
1.背景
问题:有用户反馈我们的 IM 应用在 Android 11 上面的网络状态监听不太准确,比如:从 wifi 切换成 4g,有网络连接会判断成无网络连接,导致部门业务逻辑在网络恢复时没有执行,影响功能体验;因此展开原有的网络状态监听模块在 Android 11 上面不准确的原因分析,以及解决方法的摸索。
2.原因分析
首先,明确问题,现有的网络状态监听在 Android 11 上面是如何不准确?
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Observable;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import androidx.annotation.RequiresPermission;
/**
* 网络改变通知并回调的类
*/
public class NetWorkObservable extends Observable<NetWorkObserver> {
private final String TAG = "NetWorkObservable";
public static final int[] ALL_NETWORK_TYPES = new int[]{R.drawable.ic_default, R.drawable.wifi, R.drawable.ic_4g,
R.drawable.ic_4g, R.drawable.ic_4g, R.drawable.ic_5g};
public static final int NETWORK_NONE = 0; // 没有网络连接
public static final int NETWORK_WIFI = 1; // wifi连接
public static final int NETWORK_2G = 2; // 2G
public static final int NETWORK_3G = 3; // 3G
public static final int NETWORK_4G = 4; // 4G
public static final int NETWORK_5G = 5; // 手机流量
private static volatile NetWorkObservable INSTANCE;
private Context mContext;
private ConnectivityManager mConnectivityManager;
private boolean mIsNetWorkActive = false;// 当前网络是否连接上
private boolean mRegister;// 是否注册了广播
private String mLastIP = "";
/**
* 监听网络状态改变的广播
*/
private BroadcastReceiver mNetWorkChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (null == intent || !ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
return;
}
final boolean isConnected = isGprsOrWifiConnected();
final String ip = IPUtils.getIpAddress(mContext);
LogUtil.printE(TAG, "获取到新的IP为: " + ip+" isConnected: "+isConnected);
if (TextUtils.isEmpty(ip)) {
mIsNetWorkActive = false;
mLastIP = null;
notifyChanged(false);
} else if (mIsNetWorkActive != isConnected || !ip.equals(mLastIP)) {// 和之前的状态不同
mIsNetWorkActive = isConnected;
mLastIP = ip;
notifyChanged(mIsNetWorkActive);//网络发生改变,执行回调
}
}
};
private NetWorkObservable() {
}
public static NetWorkObservable getInstance() {
if (INSTANCE == null) {
synchronized (NetWorkObservable.class) {
if (INSTANCE == null)
INSTANCE = new NetWorkObservable();
}
}
return INSTANCE;
}
/**
* 初始化资源
* @param context 上下文
*/
public void init(Context context) {
mContext = context;
mConnectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
mIsNetWorkActive = isGprsOrWifiConnected(); // 获取程序启动时的网络状态
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(mNetWorkChangeReceiver, intentFilter); // 注册网络监听广播
mRegister = true;
}
/**
* 检测网络连接状态
* @return true 连接;false 断开
*/
private boolean isGprsOrWifiConnected() {
boolean result = false;
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
NetworkInfo gprs = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo wifi = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo ethernet = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET);
boolean isConnectedGprs = gprs != null && gprs.isConnected();
boolean isConnectedWifi = wifi != null && wifi.isConnected();
boolean isConnectedEthernet = ethernet != null && ethernet.isConnected();
result = isConnectedGprs || isConnectedWifi || isConnectedEthernet;
} else {
Network[] networks = mConnectivityManager.getAllNetworks();//获取所有网络连接的信息
for (int i = 0; i < networks.length; i++) { //获取ConnectivityManager对象对应的NetworkInfo对象
NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(networks[i]);
if (networkInfo != null) {
result = result || networkInfo.isConnected();
}
}
}
return result;
}
/**
* 执行网络改变的回调(通知注册了的类)
* @param connected
*/
private void notifyChanged(boolean connected) {
synchronized (mObservers) {
for (int i = mObservers.size() - 1; i >= 0; i--) {
mObservers.get(i).onNetWorkStatusChange(connected);
}
}
}
/**
* 释放回收资源
*/
public void release() {
if (mRegister && mContext != null) {
mContext.unregisterReceiver(mNetWorkChangeReceiver);
mRegister = false;
mContext = null;
}
unregisterAll();
}
/**
* 查询 网络状态
* @return true 正常连接 false 断开连接
*/
public boolean isNetworkActive() {
return mIsNetWorkActive;
}
public boolean contains(NetWorkObserver observer) {
return mObservers.contains(observer);
}
}
复制代码
3.解决方法
代码仓库:
git clone https://github.com/pwittchen/ReactiveNetwork.git
复制代码
简介:Android library listening network connection state and Internet connectivity with RxJava Observables
划线
评论
复制
发布于: 1 小时前阅读数: 8
版权声明: 本文为 InfoQ 作者【Changing Lin】的原创文章。
原文链接:【http://xie.infoq.cn/article/cda0471fc94fd04b222a2019c】。文章转载请联系作者。
Changing Lin
关注
获得机遇的手段远超于固有常规之上~ 2020.04.29 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。
评论