本接新建一个空项目
day08_BroadcastTest
1、广播是啥
Android 中的广播机制非常灵活,每个应用程序可以对自己需要的广播进行注册。发送广播可以通过Intent
,接收广播需要广播接收器
。
- 标准广播
Normal broadcasts
:所有的广播接收器都会接收到此广播消息,异步执行,没有任何先后顺序,无法被截断 - 有序广播
Ordered broadcasts
:同步执行的广播,当一个广播接收器的逻辑执行完毕后才会传递给下一个广播接收器,优先级高的广播接收器可以先收到消息,还可以截断广播消息
2、系统啥时候发送广播
开机完成,电量变化,时区改变等活动发生时系统都会发送一条广播
3、如何创建广播接收器
- 新建一个继承自
BroadcastReceiver
的类 - 重写
onReceive()
广播到来时,onReceive()
就会执行,里面可以写处理的逻辑。
广播接收器使用时首先要注册广播,在AndroidManifest.xml
注册称为静态注册,在代码中注册称为动态注册。
4、动态注册一个监听网络变化的程序
主活动修改:
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetWorkChangeReceiver netWorkChangeReceiver;
public MainActivity() {
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(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);
}
private class NetWorkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"网络环境发生变化", Toast.LENGTH_SHORT).show();
}
}
}
- 新建了一个继承自
BroadcastReceiver
的类NetWorkChangeReceiver
,并重写了父类的onReceiver()
方法,这样网络变化时就会提示信息 - 在
onCreate()
中,创建了IntentFilter
实例,并给他添加了一个action
:android.net.conn.CONNECTIVITY_CHANGE
,当系统网络状态改变时,系统就会发送这条广播 - 在
onCreate()
中,又创建了NetworkChangeReceiver
实例,然后调用registerReceiver()
方法注册,这样使得该实例可以接收所有值为android.net.conn.CONNECTIVITY_CHANGE
的广播,也就实现了监听网络变化的功能 - 最后记得,在活动销毁时要通过
unregisterReceiver()
取消注册
测试运行:
在启动时会收到一条广播,开关飞行模式也会收到广播
5、监听网络状态
这就需要应用声明访问网络的权限了,在AndroidManifest.xml
中添加:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
继续修改主活动的NetworkChangeReceiver
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (connectivityManager != null) {
Network activeNetwork = connectivityManager.getActiveNetwork();
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
if (networkCapabilities != null && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
Toast.makeText(context,"已连接到网络", Toast.LENGTH_LONG).show();
if(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)){
Toast.makeText(context,"wifi连接网络",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"数据流量连接网络",Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(context,"未连接到网络",Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(context,"没有可用网络", Toast.LENGTH_SHORT).show();
}
}
}
这里我要说一句,因为书上的代码getActiveNetworkInfo()
已经在api21后弃用,所以我用了android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
来判断版本并采用新的api的NetworkCapabilities
来判断网络状态
【参考资料】
打开wifi,
关闭wifi:
6、静态注册实现开机开机启动
这个逻辑也很简单,收到开机广播时在onReceive()
中执行启动活动就行。
Android Studio
提供了快捷方式创建广播接收器,右键单击包名,新建->other
->Broadcast Receiver
命名为BootCompleteReceiver
。Exported
表示是否允许该广播接受去接收本程序之外的广播,Enabled
表示是否启用这个广播接收器
修改BootCompleteReceiver
:
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"已经检测到开机了!",Toast.LENGTH_LONG).show();
}
}
打开AndroidManifest.xml
,发现AS自动帮我们完成了广播接收器的代码:
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
</receiver>
不过这还不够,我们还要声明启动权限以及加入Boot_COMPLETED
的权限:
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
然后运行并重启:
完成!