Android(安卓)网络状态监听那些事
16lz
2021-01-26
一、前言 关于网络请求错误大概有两种情况: 1)当前没有网络。 2)有网络,客户端错误或者服务器错误。 今天我们就来讨论第一种:当前没有网络这种错误。网络可以分为移动数据网络和wifi。至于这些网络状态的变化,我们有必要去正真的研究一下。
二、实现的思路 经过认真查找网上资料,大概有三种思路: 1)启动Service服务并开启一条线程,线程一直检测当前网络状态,并通过广播方式发送这些状态信息。 2)只有与服务器交互时(比如:加载,上传等),才检测当前网络状态是否有连接。这种方法优点就是不用实时监听网络状态,不足的是每一个请求方法都要写判断,代码量变大。有人会说写成一个封装类,这样虽然减少代码编写,但是也都需要我们主动去获取,也会麻烦。 3)对于上面这种情况,谷歌已经帮我们封装好,只需要我们接收广播做进一步监听即可。 在这里我会实现以上第二和第三两种思路!
1、第一种:请求时,做网络判断 网络类型主要有两种:第一种,wifi;第二种,移动数据网络。 下面通过一些代码来获得当前网络状态以及网络信息。 判断当前网络状态是否有连接。
2、第二种:自定义广播监听网络状态 说到自定义广播,首先要知道广播的注册方式。注册方式有:动态注册、静态注册。 静态注册: 在 AndroidMainest文件中配置:
好了!网络状态监听大概就讲到这边!如果有出错或者需要改进的地方,欢迎指点或者交流。
二、实现的思路 经过认真查找网上资料,大概有三种思路: 1)启动Service服务并开启一条线程,线程一直检测当前网络状态,并通过广播方式发送这些状态信息。 2)只有与服务器交互时(比如:加载,上传等),才检测当前网络状态是否有连接。这种方法优点就是不用实时监听网络状态,不足的是每一个请求方法都要写判断,代码量变大。有人会说写成一个封装类,这样虽然减少代码编写,但是也都需要我们主动去获取,也会麻烦。 3)对于上面这种情况,谷歌已经帮我们封装好,只需要我们接收广播做进一步监听即可。 在这里我会实现以上第二和第三两种思路!
1、第一种:请求时,做网络判断 网络类型主要有两种:第一种,wifi;第二种,移动数据网络。 下面通过一些代码来获得当前网络状态以及网络信息。 判断当前网络状态是否有连接。
/** * 判断是否有网络连接 * @param context * @return */public static boolean isNetworkConnected(Context context) { if (context != null) { ConnectivityManager mConnectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mNetworkInfo = mConnectivityManager .getActiveNetworkInfo(); if (mNetworkInfo != null) { return mNetworkInfo.isAvailable(); } } return false;}
判断当前是否是wifi网络。 /** * 判断当前网络是否是wifi网络 * * @param context * @return boolean */public static boolean isWifi(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo(); if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) { return true; } return false;}
判断当前是否是移动数据网络。 /** * 判断当前网络是否是移动网络 * * @param context * @return boolean */public static boolean isMoble(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo(); if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_MOBILE) { return true; } return false;}
获取当前网络状态。 /** * 获取当前的网络状态 :没有网络-0:WIFI网络1:4G网络-4:3G网络-3:2G网络-2 * 自定义 * * @param context * @return */public static int getAPNType(Context context) { //结果返回值 int netType = 0; //获取手机所有连接管理对象 ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context .CONNECTIVITY_SERVICE); //获取NetworkInfo对象 NetworkInfo networkInfo = manager.getActiveNetworkInfo(); //NetworkInfo对象为空 则代表没有网络 if (networkInfo == null) { return netType; } //否则 NetworkInfo对象不为空 则获取该networkInfo的类型 int nType = networkInfo.getType(); if (nType == ConnectivityManager.TYPE_WIFI) { //WIFI netType = 1; } else if (nType == ConnectivityManager.TYPE_MOBILE) { int nSubType = networkInfo.getSubtype(); TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService (Context.TELEPHONY_SERVICE); //3G 联通的3G为UMTS或HSDPA 电信的3G为EVDO if (nSubType == TelephonyManager.NETWORK_TYPE_LTE && !telephonyManager.isNetworkRoaming()) { netType = 4; } else if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS || nSubType == TelephonyManager.NETWORK_TYPE_HSDPA || nSubType == TelephonyManager.NETWORK_TYPE_EVDO_0 && !telephonyManager.isNetworkRoaming()) { netType = 3; //2G 移动和联通的2G为GPRS或EGDE,电信的2G为CDMA } else if (nSubType == TelephonyManager.NETWORK_TYPE_GPRS || nSubType == TelephonyManager.NETWORK_TYPE_EDGE || nSubType == TelephonyManager.NETWORK_TYPE_CDMA && !telephonyManager.isNetworkRoaming()) { netType = 2; } else { netType = 2; } } return netType;}
获取当前网络信息。 /** * 获取网络连接的类型信息 * @param context * @return */public static String getNetInfo(Context context) { ConnectivityManager mConnectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo wifi = mConnectivityManager .getNetworkInfo(ConnectivityManager.TYPE_WIFI); NetworkInfo mobile = mConnectivityManager .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); StringBuffer sb = new StringBuffer(); if (wifi != null && wifi.isAvailable()) { sb.append("WIFI"); } if (mobile != null && mobile.isAvailable()) { sb.append(mobile.getSubtypeName() + ","); sb.append(getMobileInfo(mobile.getSubtype())); } return sb.toString();}/** * 移动网络信息 * * @param type * @return */public static String getMobileInfo(int type) { String netInfo = null; switch (type) { case 0: netInfo = "未知"; break; case 1: netInfo = "联通2G"; break; case 2: netInfo = "移动2G"; break; case 3: netInfo = "联通3G"; break; case 4: netInfo = "电信2G"; break; case 5: netInfo = "电信3G"; break; case 6: netInfo = "电信3G"; break; case 7: netInfo = "1xRTT"; break; case 8: netInfo = "联通3G"; break; case 9: netInfo = "HSUPA"; break; case 10: netInfo = "HSPA"; break; case 11: netInfo = "IDEN"; break; case 12: netInfo = "电信3G"; break; case 13: netInfo = "4G"; break; case 14: netInfo = "eHRPD"; break; case 15: netInfo = "HSPAP"; break; default: break; } return netInfo;}
以上封装方法可以在网络请求是做判断,并且可以得出当前网络信息。 2、第二种:自定义广播监听网络状态 说到自定义广播,首先要知道广播的注册方式。注册方式有:动态注册、静态注册。 静态注册: 在 AndroidMainest文件中配置:
动态注册: 在Application中的oncreate()方法中调用一下方法,做动态注册。 /** * 网络状态广播注册 * @author hjy * created at 2016/12/12 15:30 */private void netWorkReceiver(){ IntentFilter filter = new IntentFilter(); filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); filter.addAction("android.net.wifi.WIFI_STATE_CHANGED"); filter.addAction("android.net.wifi.STATE_CHANGE"); mNetWorkReceiver = new NetWorkReceiver(netWorkHandler); registerReceiver(mNetWorkReceiver,filter);}
注册好了,接下来就来看一下自定义广播中是怎么去接收的呢?贴上代码..... /** * 网络状态监听广播 * @author hjy * created at 2016/12/12 15:20 */public class NetWorkReceiver extends BroadcastReceiver { private static final String TAG = "test"; private Handler mHandler; public NetWorkReceiver() {} public NetWorkReceiver(Handler mHandler) { this.mHandler = mHandler; } @Override public void onReceive(Context context, Intent intent) { //wifi开关监听 isOpenWifi(intent, mHandler); //是否连接wifi isConnectionWifi(intent, mHandler); //监听网络连接设置 isConnection(intent, mHandler, context); } /** * 监听wifi打开与关闭 * (与连接与否无关) * @author hjy * created at 2016/12/12 17:33 */ private void isOpenWifi(Intent intent, Handler mHandler) { // 这个监听wifi的打开与关闭,与wifi的连接无关 if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0); switch (wifiState) { //Wifi关闭 case WifiManager.WIFI_STATE_DISABLED: LogUtil.e(TAG, "wifiState:wifi关闭!" ); break; case WifiManager.WIFI_STATE_DISABLING: break; case WifiManager.WIFI_STATE_ENABLING: break; case WifiManager.WIFI_STATE_ENABLED: LogUtil.e(TAG, "wifiState:wifi打开!" ); break; case WifiManager.WIFI_STATE_UNKNOWN: break; default: break; } } } /** * 连接有用的wifi(有效无线路由) * WifiManager.WIFI_STATE_DISABLING与WIFI_STATE_DISABLED的时候,根本不会接到这个广播 * @author hjy * created at 2016/12/13 9:47 */ private void isConnectionWifi(Intent intent, Handler mHandler) { if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) { Parcelable parcelableExtra = intent .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if (null != parcelableExtra) { NetworkInfo networkInfo = (NetworkInfo) parcelableExtra; NetworkInfo.State state = networkInfo.getState(); boolean isConnected = state == NetworkInfo.State.CONNECTED; //wifi连接 if (isConnected) { mHandler.sendEmptyMessage(ConstantsUtil.NetWork.IS_WIFI); LogUtil.e(TAG, "isConnected:isWifi:true"); } } } } /** * 监听网络连接的设置,包括wifi和移动数据的打开和关闭。(推荐) * 这个广播的最大弊端是比上边两个广播的反应要慢,如果只是要监听wifi,我觉得还是用上边两个配合比较合适 * @author hjy * created at 2016/12/13 9:47 */ private void isConnection(Intent intent, Handler mHandler, Context context) { if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { ConnectivityManager manager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = manager.getActiveNetworkInfo(); if (activeNetwork != null) { // connected to the internet if (activeNetwork.isConnected()) { if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) { // connected to wifi mHandler.sendEmptyMessage(ConstantsUtil.NetWork.IS_WIFI); LogUtil.e(TAG, "当前WiFi连接可用 "); } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { // connected to the mobile provider's data plan mHandler.sendEmptyMessage(ConstantsUtil.NetWork.IS_MOBILE); LogUtil.e(TAG, "当前移动网络连接可用 "); } } else { LogUtil.e(TAG, "当前没有网络连接,请确保你已经 打开网络 "); mHandler.sendEmptyMessage(ConstantsUtil.NetWork.NO_CONNECTION); } LogUtil.e(TAG, "TypeName:" + activeNetwork.getTypeName()); LogUtil.e(TAG, "SubtypeName:" + activeNetwork.getSubtypeName()); LogUtil.e(TAG, "State:" + activeNetwork.getState()); LogUtil.e(TAG, "DetailedState:" + activeNetwork.getDetailedState().name()); LogUtil.e(TAG, "ExtraInfo:" + activeNetwork.getExtraInfo()); LogUtil.e(TAG, "Type:" + activeNetwork.getType()); } else { // not connected to the internet LogUtil.e(TAG, "当前没有网络连接,请确保你已经打开网络 "); mHandler.sendEmptyMessage(ConstantsUtil.NetWork.NO_CONNECTION); } } }}
辅助类: /** * 常量工具类 * Created by hjy on 2016/9/26. */public class ConstantsUtil { /** * 网络监听 * @author hjy * created at 2016/11/25 12:03 */ public class NetWork { //移动:Moblie public static final String MOBLIE = "Moblie"; // Wifi:Wifi public static final String WIFI = "Wifi"; //当前是wifi状态 public static final int IS_WIFI = 0x001; //当前是Mobile状态 public static final int IS_MOBILE = 0x002; //都没有连接 public static final int NO_CONNECTION = 0x003; //关闭wifi //public static final int OPEN_WIFI = 0x004; //打开wifi //public static final int CLOSE_WIFI = 0x005; }}
在Application中调用: /** * Created by hjy on 2016/9/26. */public class BaseApplication extends Application { //网络监听广播 private NetWorkReceiver mNetWorkReceiver; //表示是否连接 public static boolean isConnected; //表示网络类型(移动数据或者wifi)移动:Moblie Wifi:Wifi public static String netWorkState; @Override public void onCreate() { super.onCreate(); /*****网络状态监听********/ netWorkReceiver(); } /** * 获取上下文 * @author hjy * created at 2016/9/26 9:03 */ public static Context getContext() { return mContext; } /** * 网络状态广播注册 * @author hjy * created at 2016/12/12 15:30 */ private void netWorkReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); filter.addAction("android.net.wifi.WIFI_STATE_CHANGED"); filter.addAction("android.net.wifi.STATE_CHANGE"); mNetWorkReceiver = new NetWorkReceiver(netWorkHandler); registerReceiver(mNetWorkReceiver,filter); } //网络监听Handler private Handler netWorkHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case ConstantsUtil.NetWork.IS_WIFI: netWorkState = ConstantsUtil.NetWork.WIFI; isConnected = true; break; case ConstantsUtil.NetWork.IS_MOBILE: netWorkState = ConstantsUtil.NetWork.MOBLIE; isConnected = true; break; case ConstantsUtil.NetWork.NO_CONNECTION: isConnected = false; break; } } };}
实现思路大概是这样:在NetWorkReceiver广播中监测到当前网络状态,通过Handler发送消息给Application,然后在BaseApplication中定义静态isConnected和 静态netWorkState字段来保存网络状态。 isConnected代表网络是否连接。 netWorkState代表网络连接时,当前连接的是Wifi还是移动数据网络。网络状态保存在这两个字段中,方便供其他页面调用。如果想添加更多状态,请自行添加! 好了!网络状态监听大概就讲到这边!如果有出错或者需要改进的地方,欢迎指点或者交流。
更多相关文章
- Android用户界面之notifaction(状态栏通知)
- Android中Dialog对话框的调用及监听
- Android监控电池电量和充电状态
- android使用遥控器模拟鼠标拖拽操作
- Android(安卓)使用AsyncTask 后监听异步加载完毕的动作-(by terry
- Android实现https网络通信之添加指定信任证书/信任所有证书
- Android(安卓)播放网络视频,视频流的处理
- Android(安卓)webview新漏洞,可导致同WiFi网络可窃取SD卡内容
- Android(安卓)Studio实现网络版音乐播放器(简单易上手)