BroadcastReceiver使用

介绍

BroadcastReceiver 是Android四大组件之一。在Android系统中应用也是挺广泛的,在Android中可以自定义接收广播或者发送。
例如:

  • 开机的时候,系统会发送一条开机广播
  • 电量变化的时候,系统会发送一条电量变化的广播
  • 网络连接状态变化的时候,系统会发送一条网络连接变化的广播
  • qq有新的消息的时候,也会发送一条广播

应用

接收特定广播

要创建一个广播接收器,首先要新建一个类,让他继承BroadcastReceiver,并且重写onReceived()方法。接收到对应广播后就会之心onReceive里的逻辑。

1
2
3
4
5
6
7
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
//接收到广播后就会执行下面的逻辑处理
public void onReceive(Context context, Intent intent) {
ToastUtils.show(context,"耳机接口状态发生了变化");
}
}

然后就是广播注册了,广播注册有动态静态两种方式,这里先讲动态注册。
动态注册有三个重要的方法,都是继承Activity的:

Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) 

注册广播,其中receiver是继承了BroadcastReceiver的自定义广播接收类,filter是过滤广播的Intent,即设置接收哪些广播。一般在activity的onCreate()方法中调用。

void unregisterReceiver(BroadcastReceiver receiver)

注销广播,receiver为注册的广播,一般在activity的onDestory()方法中调用。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class MainActivity extends AppCompatActivity {
private MyBroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//接收系统在耳机口状态变化时发出的广播
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
//注册广播
registerReceiver(receiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
//注销广播
unregisterReceiver(receiver);
}

当插拔耳机的时候就会弹出toast:
效果图

发送自定义广播

发送广播也很简单,只有一个方法:

void sendBroadcast(Intent intent)

intent是要发送的自定义广播。示例代码如下:

1
2
3
4
5
public void sendBroadCast(View view) {
//广播名字一般加上包名前缀,防止重复
Intent intent = new Intent("com.stxr.breadcastLearning.sample");
sendBroadcast(intent);
}

然后在要接收的Receiver中添加对应的IntentFilter:

1
2
3
4
5
receiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//添加自定义广播
intentFilter.addAction("com.stxr.breadcastLearning.sample");
registerReceiver(receiver, intentFilter);

完整示例代码:

MainActivity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MainActivity extends AppCompatActivity {
private MyBroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//接收自定义广播
intentFilter.addAction("com.stxr.breadcastLearning.sample");
//接收系统广播(耳机插拔状态)
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
//注册广播
registerReceiver(receiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
//注销广播
unregisterReceiver(receiver);
}
//Button按钮的回调方法,按下按钮发送自定义广播
public void sendBroadCast(View view) {
//广播名字一般加上包名前缀,防止重复
Intent intent = new Intent("com.stxr.breadcastLearning.sample");
sendBroadcast(intent);
}
}

MyBroadcastReceiver:

1
2
3
4
5
6
7
8
9
10
11
12
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
//接收广播后的逻辑处理
public void onReceive(Context context, Intent intent) {
//判别广播的类型
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
ToastUtils.show(context,"耳机接口状态发生了变化");
} else if (intent.getAction().equals("com.stxr.breadcastLearning.sample")) {
ToastUtils.show(context,"接收到了自定义广播");
}
}
}

分别接收到不同的广播:
效果图
效果图

静态广播

介绍

动态广播要打开APP才能接收信息,但是静态广播可以在不开APP的时候接收广播。比如要实现软件的开机启动就必须用到静态广播。静态广播的使用方法也很简单,只需要在AndroidMenifest中注册就行:

1
2
3
4
5
6
7
8
9
10
...
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.stxr.breadcastLearning.sampl" />
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>

其中:

  • android:name 自定义Receiver的类名
  • android:enabled 是否使能Receiver
  • android:exported 是否允许广播接收器接收本程序以外的广播

上面的效果和动态注册效果一样。

有序广播

介绍

有序广播可以通过程序来截断,可以使高优先级的广播接收器接收到之后进行截断,从而终止传播。
将有序广播变为无序广播只需将 sendBroadCast() 方法改为 sendOrderedBroadcast() 方法,sendOrderedBroadcast() 第二个参数一般为null。如下:

1
2
3
4
public void sendBroadCast(View view) {
Intent intent = new Intent("com.stxr.breadcastLearning.sample");
sendOrderedBroadcast(intent,null);
}

设置优先级

设置了有序广播,就要设置广播的优先级,优先级范围值为:-1000~1000。

  • 动态注册可用IntentFilter下的setPriority() 方法,
  • 静态注册可用intent-filter标签下的android:priority 属性

终止广播

终止广播只需要调用BroadcastReceiver 下的abortBroadcast() 方法即可。

1
2
3
4
5
6
7
8
9
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
//接收广播后的逻辑处理
public void onReceive(Context context, Intent intent) {
ToastUtils.show(context,"接收到了自定义广播");
//终止广播
abortBroadcast();
}
}

本地广播

介绍

本地广播,顾名思义就是只在当前App传播的广播,如果不想自己的广播被别的程序获取,本地广播就派上用场了。

动态注册

本地广播和全局广播大同小异,只是多用了一个LocalBroadcastManager来对广播进行管理。原来方法也相应的替换为LocalBroadcastManager 下的方法:

  • sendBroadcast 替换为 LocalBroadcastManager.sendBroadcast
  • registerReceiver 替换为 LocalBroadcastManager.registerReceiver
  • unregisterReceiver 替换为 LocalBroadcastManager.unregisterReceiver

注意: LocalBroadcastManager 要通过 LocalBroadcastManager的getInstance()获取实例。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MainActivity extends AppCompatActivity {
private MyBroadcastReceiver receiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new MyBroadcastReceiver();
//获取实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.stxr.breadcastLearning.sample");
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
//注册广播
localBroadcastManager.registerReceiver(receiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
//注销广播
localBroadcastManager.unregisterReceiver(receiver);
}
public void sendBroadCast(View view) {
Intent intent = new Intent("com.stxr.breadcastLearning.sample");
//发送广播
localBroadcastManager.sendBroadcast(intent);
}

静态注册

本地广播无法静态注册,因为发送本地广播的时候,程序肯定已经启动,所以不需要静态注册。

常见的系统广播

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//关闭或打开飞行模式时的广播
Intent.ACTION_AIRPLANE_M;
//充电状态,或者电池的电量发生变化;//电池的充电状态、电荷级别改变,不能通过组建声;
Intent.ACTION_BATTERY_CH;
//表示电池电量低
Intent.ACTION_BATTERY_LO;
//表示电池电量充足
Intent.ACTION_BATTERY_OK;
//关闭或打开飞行模式时的广播
Intent.ACTION_AIRPLANE_MODE_CHANGED;
//充电状态,或者电池的电量发生变化//电池的充电状态、电荷级别改变,不能通过组建声明接收这个广播,只有通过Context.registerReceiver()注册
Intent.ACTION_BATTERY_CHANGED;
//表示电池电量低
Intent.ACTION_BATTERY_LOW;
//表示电池电量充足,即从电池电量低变化到饱满时会发出广播
Intent.ACTION_BATTERY_OKAY;
//在系统启动完成后,这个动作被广播一次(只有一次)。
Intent.ACTION_BOOT_COMPLETED;
//按下照相时的拍照按键(硬件按键)时发出的广播
Intent.ACTION_CAMERA_BUTTON;
//当屏幕超时进行锁屏时,当用户按下电源按钮,长按或短按(不管有没跳出话框),进行锁屏时,android系统都会广播此Action消息
Intent.ACTION_CLOSE_SYSTEM_DIALOGS;
//设备当前设置被改变时发出的广播(包括的改变:界面语言,设备方向,等,请参考Configuration.java)
Intent.ACTION_CONFIGURATION_CHANGED;
//设备日期发生改变时会发出此广播
Intent.ACTION_DATE_CHANGED;
//设备内存不足时发出的广播,此广播只能由系统使用,其它APP不可用
Intent.ACTION_DEVICE_STORAGE_LOW;
//设备内存从不足到充足时发出的广播,此广播只能由系统使用,其它APP不可用
Intent.ACTION_DEVICE_STORAGE_OK;
//发出此广播的地方frameworks\base\services\java\com\android\server\DockObserver.java
Intent.ACTION_DOCK_EVENT;
//移动APP完成之后,发出的广播(移动是指:APP2SD)
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE;
//正在移动APP时,发出的广播(移动是指:APP2SD)
Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
//Gtalk已建立连接时发出的广播
Intent.ACTION_GTALK_SERVICE_CONNECTED;
//Gtalk已断开连接时发出的广播
Intent.ACTION_GTALK_SERVICE_DISCONNECTED;
//在耳机口上插入耳机时发出的广播
Intent.ACTION_HEADSET_PLUG;
//改变输入法时发出的广播
Intent.ACTION_INPUT_METHOD_CHANGED;
//设备当前区域设置已更改时发出的广播
Intent.ACTION_LOCALE_CHANGED;
//表示用户和包管理所承认的低内存状态通知应该开始。
Intent.ACTION_MANAGE_PACKAGE_STORAGE;
//未正确移除SD卡(正确移除SD卡的方法:设置--SD卡和设备内存--卸载SD卡),但已把SD卡取出来时发出的广播,扩展介质(扩展卡)已经从 SD 卡插槽拔出,但是挂载点 (mount point) 还没解除 (unmount)
Intent.ACTION_MEDIA_BAD_REMOVAL;
//按下"Media Button" 按键时发出的广播,假如有"Media Button" 按键的话(硬件按键)
Intent.ACTION_MEDIA_BUTTON;
//插入外部储存装置,比如SD卡时,系统会检验SD卡,此时发出的广播?
Intent.ACTION_MEDIA_CHECKING;
//已拔掉外部大容量储存设备发出的广播(比如SD卡,或移动硬盘),不管有没有正确卸载都会发出此广播,用户想要移除扩展介质(拔掉扩展卡)。
Intent.ACTION_MEDIA_EJECT;
//插入SD卡并且已正确安装(识别)时发出的广播, 扩展介质被插入,而且已经被挂载。
Intent.ACTION_MEDIA_MOUNTED;
//拓展介质存在,但使用不兼容FS(或为空)的路径安装点检查介质包含在Intent.mData领域。
Intent.ACTION_MEDIA_NOFS;
//外部储存设备已被移除,不管有没正确卸载,都会发出此广播, 扩展介质被移除。
Intent.ACTION_MEDIA_REMOVED;
//广播:已经扫描完介质的一个目录
Intent.ACTION_MEDIA_SCANNER_FINISHED;
//请求媒体扫描仪扫描文件并将其添加到媒体数据库。
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE;
//广播:开始扫描介质的一个目录
Intent.ACTION_MEDIA_SCANNER_STARTED;
// 广播:扩展介质的挂载被解除 (unmount),因为它已经作为 USB 大容量存储被共享。
Intent.ACTION_MEDIA_SHARED;
Intent.ACTION_MEDIA_UNMOUNTABLE;//
// 广播:扩展介质存在,但是还没有被挂载 (mount)
Intent.ACTION_MEDIA_UNMOUNTED
Intent.ACTION_NEW_OUTGOING_CALL;
//成功的安装APK之后//广播:设备上新安装了一个应用程序包。//一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_ADDED;
//一个已存在的应用程序包已经改变,包括包名
Intent.ACTION_PACKAGE_CHANGED;
//清除一个应用程序的数据时发出的广播(在设置--应用管理--选中某个应用,之后点清除数据时?)//用户已经清除一个包的数据,包括包名(清除包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_DATA_CLEARED;
//触发一个下载并且完成安装时发出的广播,比如在电子市场里下载应用?
Intent.ACTION_PACKAGE_INSTALL;
//成功的删除某个APK之后发出的广播,一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_REMOVED;
//替换一个现有的安装包时发出的广播(不管现在安装的APP比之前的新还是旧,都会发出此广播?)
Intent.ACTION_PACKAGE_REPLACED;
//用户重新开始一个包,包的所有进程将被杀死,所有与其联系的运行时间状态应该被移除,包括包名(重新开始包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_RESTARTED;
//插上外部电源时发出的广播
Intent.ACTION_POWER_CONNECTED;
//已断开外部电源连接时发出的广播
Intent.ACTION_POWER_DISCONNECTED;
Intent.ACTION_PROVIDER_CHANGED;//
//重启设备时的广播
Intent.ACTION_REBOOT;
//屏幕被关闭之后的广播
Intent.ACTION_SCREEN_OFF;
//屏幕被打开之后的广播
Intent.ACTION_SCREEN_ON;
//关闭系统时发出的广播
Intent.ACTION_SHUTDOWN;
//时区发生改变时发出的广播
Intent.ACTION_TIMEZONE_CHANGED;
//时间被设置时发出的广播
Intent.ACTION_TIME_CHANGED;
//广播:当前时间已经变化(正常的时间流逝), 当前时间改变,每分钟都发送,不能通过组件声明来接收
,只有通过Context.registerReceiver()方法来注册
Intent.ACTION_TIME_TICK;
//一个用户ID已经从系统中移除发出的广播
Intent.ACTION_UID_REMOVED;
//设备已进入USB大容量储存状态时发出的广播?
Intent.ACTION_UMS_CONNECTED;
//设备已从USB大容量储存状态转为正常状态时发出的广播?
Intent.ACTION_UMS_DISCONNECTED;
Intent.ACTION_USER_PRESENT;//
//设备墙纸已改变时发出的广播
Intent.ACTION_WALLPAPER_CHANGED;