概览
5. BroadcastReceiver广播
5.1 BroadcastReceiver简介
BroadcastReceiver是接受广播通知的组件。广播是一种同时通知多个对象的事件通知机制。通常情况下,广播是以消息提示框、对话框或者通知的形式体现的。
Android中的广播来源:系统事件、普通应用程序。
常用的系统事件:
- 电池电量低
- 系统启动完成
- 系统日期发生改变
- 系统时间发生改变
- 系统连接电源
- 系统被关闭
BroadcastReceiver类是所有广播接收器的抽象基类,其实现类用来对发送出来的广播进行筛选并做出响应。广播接收器的生命周期非常简单,当消息到达,接收器调用onReceive()方法(实现BroadcastReceiver类需要重写),在该方法结束后,BroadcastReceiver示例失效。
在Android操作系统中每启动一个广播都要重新实例化一个新的广播组件对象,并自动调用类中的onReceive()方法对广播事件进行处理。用于接收的广播有以下两大类:
- 普通广播:使用Context.sendBroadcast()方法发送
- 可以在同一时刻被所有接受者接收到
- 接收者不能将处理结果传递给下一个接收者
- 无法终止广播的传播
- 有序广播:使用Context.sendOrderedBroadcast()方法发送
- 相同优先级的接受者接收顺序是随机的,不同优先级的接收者按照优先级由高到低的顺序依次接收。
- 接收者可以将处理结果传递给下一个接收者
- 可以终止广播的传播
5.2 接收系统广播
5.2.1 动态注册广播
流程:
- 创建一个广播接收器:新建一个类让其继承于BroadcastReceiver,并重写父类的onReceive()方法,有广播时,该方法就会执行
- 使用IntentFilter,并为其添加一个action,广播接收器想要监听什么广播,就添加相应的action值
- 创建广播接收器的实例,并使用registerReceiver()方法[两个参数:第一个参数为广播接收器实例,第二个参数为intentFilter]进行注册
- 最后在onDestroy()方法中 使用unregisterReceiver()方法传入广播接收器的实例取消注册
代码示例:
//创建一个类继承自BroadcastReceiver,并重写onReceive()方法
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
}
}
//在主活动中定义
private IntentFilter intentFilter;
private MyBroadcastReceiver myBroadcastReceiver;
//在Oncreate()方法中注册
intentFilter = new IntentFilter();
//广播接收器想要监听什么广播,就添加对应的action
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
myBroadcastReceiver = new MyBroadcastReceiver();
//进行注册
registerReceiver(myBroadcastReceiver,intentFilter);
//在onDestroy()方法中取消注册
//动态注册的广播接收器一定要取消注册
unregisterReceiver(myBroadcastReceiver);
5.2.2 静态注册广播
流程:
- 在同一包下,New->Other->Broadcast Receiver
Exported:表示是否允许这个广播接收器接收本程序以外的广播
Enable: 是否启用这个广播接收器 - 在 AndroidManifest.xml文件中,receiver标签中,配置intent-filter标签,并配置想要监听的广播的action
代码示例:
使用AS创建一个Broadcast Receiver:
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();
}
}
在Manifest.xml文件中配置receiver:
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<!-- 系统启动完成的广播action-->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
5.3 发送自定义广播
注意:
发送自定义广播时,广播接收不到:
- 如果是同一个包类:需要加上 intent.setComponent(new ComponentName(“接收广播类所在包名”,“接收广播类的全类名”))
- 如果是不同应用之间发送: 需要加上 intent.setFlags(0x01000000); 其他应用就可以收到发送的广播了
5.3.1 发送标准广播
流程:
- 使用AS创建一个Broadcast Receiver
- 在Manifest.xml文件中配置receiver标签下的intent-filter,为其配置action
- 在主活动文件中创建Intent,并在其传入自定义的action
- 使用sendBroadcast(intent)方法发送广播
代码示例:
- 创建广播接收器用来接收广播
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
- 在Manifest文件中配置action
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<!-- 让 MyBroadcastReceiver 接收一条值为com.example.broadcasttest.MY_BROADCAST的广播-->
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
在主活动中发送广播:
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
//可以携带数据给广播接收器
intent.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.MyBroadcastReceiver"));
//发送标准广播
sendBroadcast(intent);
5.3.2 发送有序广播
流程:
- 新建一个项目并使用AS创建一个Broadcast Receiver
- 在Manifest.xml文件中配置receiver标签下的intent-filter,为其配置要接收的广播的action,以及配置 android:priority优先级(数值越大优先级越高)
- 在上一个项目的主活动文件中创建Intent,并在其传入自定义的action
- 使用sendOrderedBroadcast(intent,null)方法发送广播 第二参数为与权限相关的字符串
- 如果需要截断广播,在广播接收类中OnReceive方法中调用 abortBroadcast()方法,后面的接收器将无法接收广播
代码示例:
- 创建新项目并新建Broadcast Receiver:
public class AnotherBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
abortBroadcast(); //截断广播
}
}
- 配置action以及优先级:
<receiver
android:name=".AnotherBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter
android:priority="100"
>
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
- 在主活动发送有序广播:
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
//可以携带数据给广播接收器
intent.setFlags(0x01000000); //不用应用间需要使用setFlags()方法
//发送有序广播
sendOrderedBroadcast(intent,null);
由于 AnotherBroadcastReceiver优先级比MyBroadcastReceiver优先级高,所以当发送了有序广播后, AnotherBroadcastReceiver先接收,并且在 onReceive()方法中调用abortBroadcast()方法将广播截断,所以MyBroadcastReceiver将无法收到广播
5.4 使用本地广播
使用LocalBroadcastManager 对广播进行管理 ,本地广播只能动态进行注册
需要在build.gradle中引入 implementation ‘androidx.localbroadcastmanager:localbroadcastmanager:1.0.0’
流程:
- 使用LocalBroadcastManager.getInstance(this)获取实例
- 使用 localBroadcastManager.registerReceiver()方法[两个参数:第一个参数为广播接收器实例,第二个参数为intentFilter]进行本地广播的注册
- 使用 localBroadcastManager.sendBroadcast(intent)方法发送广播
- 在onDestroy()方法中使用localBroadcastManager.unregisterReceiver()方法取消注册
代码示例:
- 新建一个广播接收器:
public class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
}
}
- 在主活动中动态注册本地广播:
//在主活动中定义
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
// 在onCreate()方法中 进行注册
//使用本地广播
localBroadcastManager = LocalBroadcastManager.getInstance(this);
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
//注册本地广播监听器
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
- 在其他方法中或按钮点击事件中发送广播:
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent); //发送本地广播
- 最后在onDestroy()方法中取消注册
localBroadcastManager.unregisterReceiver(localReceiver);