首先我们要知道写一个网络监听要用到什么方法:
- 自定义一个NetReceiver继承自BroadcastReceiver;
- 需要写一个NetUtil去判断当前手机的网络类型;
- 在NetUtil中需要写获取手机网络的方法,定义手机连接网络的类型
- 在获取手机网络的方法中需要用到ConnectivityManager、NetWorkInfo
首先是写一个NetReceiver代码如下:
public class NetReceiver extends BroadcastReceiver {
public NetState state = MainActivity.state;
@Override
public void onReceive(Context context, Intent intent) {
// 如果相等的话就说明网络状态发生了变化
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
int netWorkState = NetUtils.getNetWorkState(context);
// 接口回调传过去状态的类型
state.onNetChange(netWorkState);
}
}
// 自定义接口
public interface NetState {
public void onNetChange(int netMobile);
}
}
简单解释一下,这个类继承自BroadcastReceiver,然后在类里面声明一个接口NetState,接口里面声明一个方法onNetChange(int netMobile)
下面是NetUtil类的代码:
public class NetUtils {
private NetUtils() {
throw new UnsupportedOperationException("初始化失败");
}
/**
* 没有网络连接
*/
private static final int NetWork_NONE = -1;
/**
* 手机网络
*/
private static final int NetWork_MOBILE = 0;
/**
* WIFI网络
*/
private static final int NetWork_WIFI = 1;
public static final int getNetWorkState(Context context){
//得到连接管理器对象
ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetWorkInfo = manager.getActiveNetworkInfo();
if (activeNetWorkInfo != null && activeNetWorkInfo.isConnected()){
if (activeNetWorkInfo.getType() == ConnectivityManager.TYPE_WIFI){
return NetWork_WIFI;
} else if (activeNetWorkInfo.getType() == ConnectivityManager.TYPE_MOBILE){
return NetWork_MOBILE;
}
}else{
return NetWork_NONE;
}
return NetWork_NONE;
}
}
这个工具类主要写一个方法返回一个手机网络的类型 -1 为未连接网络, 0 为手机GPRS网络 , 1 为手机WIFI网络
然后在方法里面使用ConnectivityManager获取网络manager实例,然后初始化NetWorkInfo来判断网络是否连接且判断连接的方式,然后返回int类型的网络类型
写完之后要做的事情无非就是注册了,说到注册receiver大家都知道有两种方法去注册,一种是在Manifest.xml文件中注册,如下:
<receiver android:name=".receiver.NetReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
还有一种是代码,但是比较麻烦,因为有注册就要有销毁所以要在onCreate方法中实例化一下receiver然后注册,在onDestory方法中销毁receiver,具体如下:
private NetReceiver receiver;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new NetReceiver();
IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver,filter);
}
@Override protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
注册代码还是挺简单的,主要的来了,在MainActivity中实现NetState接口,会弹出一个复写方法onNetChange,然而我们重写这个方法就可以监听网络变化了
MainActivity代码如下:
public class MainActivity extends AppCompatActivity implements NetReceiver.NetState {
private Context mContext = this;
public static NetReceiver.NetState state;
private LinearLayout tv_noNetConnect;
/**
* 网络类型
*/
private int netMobile;
private NetReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new NetReceiver();
IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver,filter);
tv_noNetConnect = (LinearLayout) findViewById(R.id.tv_nonetconnect);
state = this;
if (!isConnetion()) {
updateNetView();
}
}
/**
* 初始化判断是否联网
*
* @return true or false
*/
public boolean isConnetion() {
this.netMobile = NetUtils.getNetWorkState(MainActivity.this);
return isNetConnect();
}
/**
* 判断有无网络 。
*
* @return true 有网, false 没有网络.
*/
public boolean isNetConnect() {
if (netMobile == 1) {
return true;
} else if (netMobile == 0) {
return true;
} else if (netMobile == -1) {
return false;
}
return false;
}
@Override
public void onNetChange(int netMobile) {
this.netMobile = netMobile;
if (netMobile == -1) {
Logger.e("--------------->", "没有网络连接");
} else if (netMobile == 0) {
Logger.e("--------------->", "手机网络");
} else {
Logger.e("--------------->", "WIFI网络");
}
updateNetView();
}
private void updateNetView() {
if (!isConnetion()) {
ToastUtils.showToast(this, "没有网络连接");
if (tv_noNetConnect.getVisibility() == View.GONE) {
tv_noNetConnect.setVisibility(View.VISIBLE);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
tv_noNetConnect.setVisibility(View.GONE);
}
}, 3000);
}
} else {
ToastUtils.showToast(this, "网络已连接");
if (tv_noNetConnect.getVisibility() == View.VISIBLE) {
tv_noNetConnect.setVisibility(View.GONE);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
在代码中,我还写多了两个方法,用于提醒用户没有网络的提示layout和判断有没有网络和是否联网的方法
其中:判断有没有网络的方法isConnection()这个方法中是直接判断该Activity页面中网络的状况然后把网络的值赋给netMobile然后在返回isNetConnect(),在isNetConnect()方法中判断netMobile的值决定返回True or False,最后只要在初始化的时候调用一下isConnect()方法,就是先检测网络,然后进行提醒,具体的提醒我也另外写了一个方法,就是updateNetView(),所以一开始用if(!isConnect())去判断手机是否联网,如果没有联网就会直接调用updateNetView(),在updateNetView()方法中用Handler去完成了提示只显示3秒的操作,然后在onNetChange()方法中判断最后还调用一次updateNetView(),为了后来连上网之后用户能够得知已经连上网了