项目完整代码
https://github.com/Phil-tom/Android-The-First-Line-of-Code/tree/main/Chapter5/BroadcastTest
Android内置了很多系统级别的广播,我们可以在应用程序中通过监听这些广播来得到各种系统的状态信息。
动态注册监听网络变化
广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够接收到该广播,并在内部处理相应的逻辑。
注册广播的方式有两种:
(1)在代码中注册(动态注册)
(2)在AndroidManifest.xml中注册(静态注册)
创建广播接收器:新建一个类,让它继承自BroadcastReceiver,并重写父类的onReceive()就可以。当有广播到来时,onReceive()方法就会得到执行
目前正在学习《第一行代码Android(第二版)》的同学们注意
书上说是在程序运行一开始,会弹出消息框,这是对的,但是之后说去修改Data usage中的Cellular data按钮就可以看到变化情况,我使用的虚拟设备是Nexus 5X API 28。
如果你也是这个虚拟设备,想要看到变化情况需要先检查你的虚拟设备有没有连上WIFI,有的话你可调整WIFI的开关按钮;如果没有连上WIFI,则可以通过调整Mobile Network中的Mobile data来看到相应的提示框。
方式一
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//方式一
Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();
}
}
}
方式一运行结果
刚运行程序的时候
修改前
修改后
方式二
方式一的提示结果不够人性化,最好能告诉用户当前是有网络还是没网络,所以需要对代码进行进一步的优化
需要在AndroidManifest.xml中加入
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
//方式二
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show();
}
方式二运行结果
刚运行程序的时候
修改前
修改后
方式三
在方式二中,NetworkInfo 方法被标注为过时,所以方式三借鉴于网上的博客进行修改,比方式二更加人性化,会显示现在是WIFI,流量,还是没有网络
//方式三
//NetworkInfo 方法过时的处理方法
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Network network = connectivityManager.getActiveNetwork();
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
if (networkCapabilities != null) {
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
Toast.makeText(MainActivity.this, "WIFI", Toast.LENGTH_SHORT).show();
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
Toast.makeText(MainActivity.this, "流量", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(MainActivity.this, "没有网络", Toast.LENGTH_SHORT).show();
}
}
}
方式三运行结果
刚运行程序的时候
修改前
修改后
先关闭WIFI
打开流量