写点什么

如何对 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
用户头像

Changing Lin

关注

获得机遇的手段远超于固有常规之上~ 2020.04.29 加入

我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。

评论

发布
暂无评论
如何对Android 11进行网络状态监听