一、前言 关于网络请求错误大概有两种情况: 1)当前没有网络。 2)有网络,客户端错误或者服务器错误。 今天我们就来讨论第一种:当前没有网络这种错误。网络可以分为移动数据网络和wifi。至于这些网络状态的变化,我们有必要去正真的研究一下。
二、实现的思路 经过认真查找网上资料,大概有三种思路: 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还是移动数据网络。网络状态保存在这两个字段中,方便供其他页面调用。如果想添加更多状态,请自行添加!
好了!网络状态监听大概就讲到这边!如果有出错或者需要改进的地方,欢迎指点或者交流。

更多相关文章

  1. Android用户界面之notifaction(状态栏通知)
  2. Android中Dialog对话框的调用及监听
  3. Android监控电池电量和充电状态
  4. android使用遥控器模拟鼠标拖拽操作
  5. Android(安卓)使用AsyncTask 后监听异步加载完毕的动作-(by terry
  6. Android实现https网络通信之添加指定信任证书/信任所有证书
  7. Android(安卓)播放网络视频,视频流的处理
  8. Android(安卓)webview新漏洞,可导致同WiFi网络可窃取SD卡内容
  9. Android(安卓)Studio实现网络版音乐播放器(简单易上手)

随机推荐

  1. 基于Eclipse的Android开发(一)——创建第一
  2. Android操作Excel文件的功能实现
  3. Android开发中的drawable文件:shape、laye
  4. Android设备扫描机制详解
  5. Android(安卓)Handler Looper Message工
  6. android键盘隐藏
  7. 如何在android 中编译alsa-utils工具
  8. Android(安卓)Alarm驱动源代码分析(Alarm.
  9. Android(安卓)USB配件模式
  10. android设备连接到pc进行应用程序调试