第1节 Broadcast Receiver概述
很多时候,我们希望一个应用程序在它没有运行起来的时候,也能感知系统状态的某些变化,如果条件合适,就让这个应用就运行起来。
比如,一个拦截骚扰电话的应用,平时它可能并不需要运行起来,它只关心有电话来的时候,看看这个号码是不是骚扰电话的号码,如果是就给用户发出一个提示,如果不是,那就和它没有关系,啥也不做。
为了实现这类功能,安卓系统引入了四大组件之一的BroadcastReceiver
,设计了一套广播与接收的机制,
- 任何应用或者安卓系统的自身组件可以像发送无线电波一样,向系统发出一条广播信息
Broadcast
; - 信息在系统中按照一定的规则传播(传播的规则稍后会详细介绍);
- 任何应用或者安卓系统的自身组件都拥有一台
接收机
-Broadcast Receiver
,这台接收机
会告诉安卓系统,它能接收某种特定的广播; - 如果安卓系统辨别出当前系统中传播的广播,正是某台
接收机
关注的广播,那么它就会把接收机
运行起来,让接收机
决定下一步怎么做?是让接收机
运行别的组件(Service或者Activity
)继续进一步的响应,还是忽略这条广播。
第2节 自定义Broadcast Receiver
无论是应用还是系统组件,它们定义Broadcast Receiver
的方式都是一样。
定义Broadcast Receiver
有两种方式,
- 静态定义:将
Broadcast Receiver
声明到AndroidManifest.xml
配置文件当中,它的特点是应用不必运行起来,系统能通过配置文件的描述判断当前系统中的广播是否是这台接收机关注的; - 动态定义:在代码中动态生成
Broadcast Receiver
,它的特点是应用要运行起来,在运行的过程当中判断当前系统中的广播是否是这台接收机关注的;
2.1 静态Broadcast Receiver
首先来看看如何定义一个静态的Broadcast Receiver
。
- 继承
BroadcastReceiver
类,实现它的onReceive
接口,public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } //实现onReceive接口,当收到指定的广播后被触发 @Override public void onReceive(Context context, Intent intent) { //添加对应的逻辑处理 } }
- 在
AndroidManifest.xml
配置文件当中,声明创建的Broadcast Receiver
,<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="custom.action.mybroadcast"/> ---指定关注的广播 <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
这里
intent-filter
标签中的android:name
属性设置的值custom.action.mybroadcast
,就是这台接收机
关注的广播。
当名称为custom.action.mybroadcast
的广播在系统中传播的时候,MyReceiver
就会被运行起来,并触发它的onReceive()
函数。开发者就需要在这里添加对应逻辑处理。
2.2 动态Broadcast Receiver
当应用运行起来以后,即使AndroidManifest.xml
文件中没有声明过Broadcast Receiver
也没有关系,它可以被动态的创建,
- 和创建静态
Broadcast Receiver
类似,首先要继承BroadcastReceiver
类,实现它的onReceive
接口,public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } //实现onReceive接口,当收到指定的广播后被触发 @Override public void onReceive(Context context, Intent intent) { //添加对应的逻辑处理 } }
- 注册
Broadcast Receiver
,并告诉系统这个Broadcast Receiver
关注哪些广播,可以添加多种关心的广播,//设置过滤器,确定关心的广播 IntentFilter filter = new IntentFilter(); filter.addAction("custom.action.mybroadcast"); //可以添加多种关心的广播 filter.addAction(......); //创建Receiver MyReceiver receiver = new MyReceiver(); //注册到系统当中,完成Receiver的设置 registerReceiver(receiver, filter);
- 使用完毕后,一定要注销
Broadcast Receiver
,否则系统会给出警告提示。unregisterReceiver(receiver);
动态的Broadcast Receiver
在注册使用完成之后一定要注销,不然会占用系统资源、浪费资源。
/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。
/*******************************************************************/
第3节 发送Broadcast
任何应用或者安卓系统的自身组件可以向系统发出广播信息Broadcast
,只要使用Context
的sendBroadcast()
方法就可以了,
unregisterReceiver(receiver);
Intent i = new Intent("custom.action.mybroadcast");
sendBroadcast(i);
发送出去的广播可以分成两类,一类是无序广播,一类是有序广播。
3.1 无序广播
这是一种不需要考虑接收者接收顺序的广播,比如说有3个接收机
,都关注custom.action.mybroadcast
这种广播,无所谓谁先收到谁后收到。接收机
不能阻止其它接收机
获取到这条广播。
3.1.1 发送
发送无序广播,只要使用Context
的sendBroadcast()
方法就可以了,
Intent i = new Intent("custom.action.mybroadcast");
sendBroadcast(i);
3.1.2 接收
在AndroidManifest.xml
中声明静态Broadcast Receiver
的时候,
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="custom.action.mybroadcast"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
就像前面介绍的那样,不用做什么特别的处理。
3.2 有序广播
这是一种需要考虑接收者接收顺序的广播,比如说有3个接收机
,都关注custom.action.mybroadcast
这种广播,那么安卓系统将根据这3个接收机
声明的优先级进行广播的投递。
而且有序广播是可以被阻截的。
比如,一个广播按照顺序传递给3个接收机
-A B C,但是B将广播拦截了,因此C将不会收到这个广播。
3.2.1 发送
Intent i = new Intent("custom.action.mybroadcast");
sendOrderedBroadcast(i, null);
3.2.1 接收
接收的时候,需要给intent-filter
标签设置android:priority
属性,表示这个接收机
的优先级。优先级从-1000到1000,数值越大,优先级越高。
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="custom.action.mybroadcast"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
接收到广播以后,Broadcast Receiver
可以将广播拦截,禁止它往下传播,
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
//实现onReceive接口
@Override
public void onReceive(Context context, Intent intent) {
//禁止往下传播
abortBroadcast();
}
}
如果接收机1
在onReceive()
中,希望把数据传递给下个接收机2
,
接收机1
可以使用setResultExtras()
方法,public class MyReceiver1 extends BroadcastReceiver { public MyReceiver() { } @Override public void onReceive(Context context, Intent intent) { Bundle b = new Bundle(); b.putString("data", "this data from MyReceiver"); setResultExtras(b); } }
- 在
接收机2
中,public class MyReceiver2 extends BroadcastReceiver { public MyReceiver2() { } @Override public void onReceive(Context context, Intent intent) { Bundle b = getResultExtras(true); if(b!=null) { //data就是前一个接收机1传来的-this data from MyReceiver String data = b.getString("data"); } } }
假如希望将数据放到onReceive()
传入的Intent
当中,是不会传递成功的,
@Override
public void onReceive(Context context, Intent intent) {
//这是不会成功的
intent.putExtra("data", "this data from MyReceiver");
}
传递数据,一定要通过BroadcastReceiver
提供的setResultExtras()
方法。
另外,测试发现,只要不在有序广播之间传递数据,使用sendBroadcast()
方法,也能成功发出有序广播。
Intent i = new Intent("custom.action.mybroadcast");
sendBroadcast(i);