监听网络变化及获取网络形式

来源:互联网 发布:防复制软件 编辑:程序博客网 时间:2024/05/18 22:09

在实际开发中在我们的 app 中几乎都会用到网络,有时我们需要在网络改变时给用户一些体验上的友好提示,比如:我们在视频播放时,由wifi切换到4G网络时,要给用户提示,当前为 4G 网络状态,注意流量的使用等.

网络变化的监听

实现方法,我们通过添加广播的方式,监听网络变化.
1. 添加网络状态权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  1. 创建网络变化监听广播
public class NetStatusBroadcast extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {    //当网络变化时,该广播中该方法会被回调.    }}
  1. 在 AndroidManifest.xml 中添加广播的配置信息,如下:
<receiver android:name=".NetStatusBroadcast">    <intent-filter>        <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>    </intent-filter></receiver>

实现这个功能很简单,就上面这个几行代码就可以实现.

在注册网络变化监听时,建议是使用动态注册方式.不要忘记当程序退出时记得你,取消注册.

IntentFilter filter = new IntentFilter();        filter.addAction(NetStatusBroadcast.NET_CHANGE_ACTION);        mBroadcast = new NetStatusBroadcast();        this.registerReceiver(mBroadcast,filter);
下面是我也的一个网络变化相应的工具,如果有什么地方些的不好或有错误请指出来,一起交流,进步.

工具下载地址:https://github.com/CNCFOX/NetStatus

思路:

先介绍几个类:

  1. NetType 是一个枚举,在这里存放这网络状态:
public enum NetType {    NO_NET,             //没有网络    NET_WIFI,           //wifi 网络    NET_3G_4G           //移动网络  3G 4G}
  1. NetTools 类,在该类中可以判断网络是否可用,获取当前网络状态.
    先看一下代码(代码中有注释,不过多解释):要说明一下,在使用前,一定要在使用前调用init()方法设置Context.
public class NetTools {    /**     * 获取连接服务     * @param context :     * @return     */    private static ConnectivityManager getConnectivityMannager(Context context){        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);    }    private static Context sCtx;    /**     * 初始化 Context ,一般建议在 Application 中进行设置     * @param context     */    public static void init(Context context){        if (sCtx != null) return;        if (context instanceof Activity){            sCtx = ((Activity) context).getApplication();            return;        }        if (context instanceof Service){            sCtx = ((Service) context).getApplication();            return;        }        sCtx = context.getApplicationContext();    }    /**     * 判断网络是否连接     * <br/> 在使用这个方法时,一定要先通过#NetTools init() 方法中进行Context 设置     * @return     */    public static boolean isConnected(){        return isConnected(sCtx);    }    /**     * 判断网络是否连接     * @param context     * @return     */    public static boolean isConnected(Context context){        if (context == null){            throw new RuntimeException(NetTools.class.getSimpleName() + " # Content  is null");        }        init(context);        ConnectivityManager connectivityManager = getConnectivityMannager(sCtx);        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();        return networkInfo != null && networkInfo.isConnected();    }    /**     * 获取网络状态     * <br/> 在使用这个方法时,一定要先通过#NetTools init() 方法中进行 Context 设置     * @return     * <br/> enum NetType     * <br/> #NO_NET : 没有网络     * <br/> NET_WIFI : wifi 网络     * <br/> NET_3G_4G : 移动网络  3G 4G     */    public static NetType netType(){        return netType(sCtx);    }    /**     * 获取网络状态     * @return     * <br/> enum NetType     * <br/> #NO_NET : 没有网络     * <br/> NET_WIFI : wifi 网络     * <br/> NET_3G_4G : 移动网络  3G 4G     */    public static NetType netType(Context context){        if (context == null){            throw new RuntimeException(NetTools.class.getSimpleName() + " # Content  is null");        }        init(context);        ConnectivityManager connectivityManager = getConnectivityMannager(sCtx);        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();        if (networkInfo == null) return NetType.NO_NET;        int type = networkInfo.getType();        if (type == ConnectivityManager.TYPE_MOBILE) return NetType.NET_3G_4G;        if (type == ConnectivityManager.TYPE_WIFI) return NetType.NET_WIFI;        return NetType.NO_NET;    }}
  1. NetObserver 类,管理注册监听类.
public class NetObserver {    private static NetStatusReceiver sGlobalReceiver;    private static NetStatusReceiver sNetStatusReceiver;    /**     * 注册全局回调,全局网络状态改变时,每次都会回调,主要用于设置全局网络状态使用     * @param netStatusReceiver     */    public static synchronized void registerlGlobalReceiver(NetStatusReceiver netStatusReceiver){        sGlobalReceiver = netStatusReceiver;    }    /**     * 获取全局回调     * @return     */    public static NetStatusReceiver getGlobalReceiver(){        return sGlobalReceiver;    }    /**     * 取消注册的全局回调     */    public static void unGlobalRegister(){        sGlobalReceiver = null;    }    /**     * 注册回调     * @param netStatusReceiver     */    public static synchronized void register(NetStatusReceiver netStatusReceiver){        sNetStatusReceiver = netStatusReceiver;    }    /**     * 取消     */    public static void unregister(){        sNetStatusReceiver = null;    }    public static NetStatusReceiver  getNetStatusReceiver(){        return sNetStatusReceiver;    }}

4.NetStatusReceiver 接口.

public interface NetStatusReceiver {    void netStatusChanged(NetType netType);}

看完这几个类,可能已经知道大概的思路了,下面介绍一下我的思路.

  1. 在 AndroidManifest.xml 中添加注册网络状态改变监听广播:这里推荐使用动态注册方式,如果使用动态注册,在程序退出时不要忘记取消注册

    • 静态注册
<receiver android:name=".netutils.NetStatusBroadcast">    <intent-filter>        <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>    </intent-filter></receiver>
  • 动态注册
        IntentFilter filter = new IntentFilter();        filter.addAction(NetStatusBroadcast.NET_CHANGE_ACTION);        mBroadcast = new NetStatusBroadcast();        this.registerReceiver(mBroadcast,filter);

注意: 不要忘记添加权限:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

  1. ### 实现网络状态改变接收广播:
public class NetStatusBroadcast extends BroadcastReceiver {    private static final String TAG = "NetStatusBroadcast";    public  static  final String NET_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";    /** 有些时候网络改变时会调用两次,使用这个变了记录上一次改变时的网络状态,如果和上一次相同,则不向下通知 */    private static NetType sNetTypeCache = null;    @Override    public void onReceive(Context context, Intent intent) {        NetTools.init(context);        Log.i(TAG,"Cache Net :" + sNetTypeCache );        if (NetTools.netType() == sNetTypeCache) return;        Log.i(TAG,"Changed net :" + NetTools.netType());        if (intent.getAction().equals(NET_CHANGE_ACTION)){            sNetTypeCache = NetTools.netType();            NetStatusReceiver receiver = NetObserver.getGlobalReceiver();            if (receiver != null) receiver.netStatusChanged(sNetTypeCache);            receiver = NetObserver.getNetStatusReceiver();            if (receiver != null) receiver.netStatusChanged(sNetTypeCache);        }    }}
  1. ### 添加注册和取消注册:
    建议在 onResume 中添加注册,在 onDestroy 中添加取消注册.
ublic class OtherActivity extends Activity {    private Button mBtnFinsh;    private NetStatusReceiver receiver = new NetStatusReceiver() {        @Override        public void netStatusChanged(NetType netType) {            Toast.makeText(OtherActivity.this,name + "OtherActivity page net type" + netType ,Toast.LENGTH_SHORT).show();        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_other);        mBtnFinsh = (Button) findViewById(R.id.btn_finsh);    }    @Override    protected void onResume() {        super.onResume();        NetObserver.register(receiver);    }    @Override    protected void onDestroy() {        super.onDestroy();        NetObserver.unregister();    }    public void exitActivity(View view) {        finish();    }}

详细内容请参考工程代码工具下载地址:https://github.com/CNCFOX/NetStatus

0 0
原创粉丝点击