标签:
很多时候,我们希望一个应用程序在它没有运行起来的时候,也能感知系统状态的某些变化,如果条件合适,就让这个应用就运行起来。
比如,一个拦截骚扰电话的应用,平时它可能并不需要运行起来,它只关心有电话来的时候,看看这个号码是不是骚扰电话的号码,如果是就给用户发出一个提示,如果不是,那就和它没有关系,啥也不做。
为了实现这类功能,安卓系统引入了四大组件之一的BroadcastReceiver,设计了一套广播与接收的机制,
Broadcast;接收机-Broadcast Receiver,这台接收机会告诉安卓系统,它能接收某种特定的广播;接收机关注的广播,那么它就会把接收机运行起来,让接收机决定下一步怎么做?是让接收机运行别的组件(Service或者Activity)继续进一步的响应,还是忽略这条广播。
无论是应用还是系统组件,它们定义Broadcast Receiver的方式都是一样。
定义Broadcast Receiver有两种方式,
静态定义:将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) {
//添加对应的逻辑处理
}
}在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()函数。开发者就需要在这里添加对应逻辑处理。
当应用运行起来以后,即使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和安豆网发布,其他网站出现本教程均属侵权。
/*******************************************************************/
任何应用或者安卓系统的自身组件可以向系统发出广播信息Broadcast,只要使用Context的sendBroadcast()方法就可以了,
unregisterReceiver(receiver);
Intent i = new Intent("custom.action.mybroadcast");
sendBroadcast(i);
发送出去的广播可以分成两类,一类是无序广播,一类是有序广播。
这是一种不需要考虑接收者接收顺序的广播,比如说有3个接收机,都关注custom.action.mybroadcast这种广播,无所谓谁先收到谁后收到。接收机不能阻止其它接收机获取到这条广播。

发送无序广播,只要使用Context的sendBroadcast()方法就可以了,
Intent i = new Intent("custom.action.mybroadcast");
sendBroadcast(i);
在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个接收机,都关注custom.action.mybroadcast这种广播,那么安卓系统将根据这3个接收机声明的优先级进行广播的投递。
而且有序广播是可以被阻截的。
比如,一个广播按照顺序传递给3个接收机-A B C,但是B将广播拦截了,因此C将不会收到这个广播。

Intent i = new Intent("custom.action.mybroadcast");
sendOrderedBroadcast(i, null);
接收的时候,需要给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);四大组件之BroadcastReceiver(一)-自定义“收音机”与发送“广播”
标签:
原文地址:http://blog.csdn.net/anddlecn/article/details/51741455