1.定义广播接收者
- 定义一个类继承BroadcastReceiver,并重写onReceive()方法。
@Override
public class SMSBroadCastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
}
}
- 在清单文件中配置该类(静态注册),指定接收的广播种类
<receiver android:name="com.example.broadcast.SMSBroadCastReceiver">
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
广播是通过intent发送的,intent中会携带一个action,系统会在所有清单文件中寻找,看哪一个广播接收者的intent-filter和广播中的intent是匹配的,那么这个广播接收者就会收到这条广播,它的onReceive方法就会执行。
BroadcastReceiver除了在清单文件中声明,也可以在代码中声明,使用registerReceiver方法动态注册Receiver
动态注册时,无须在AndroidManifest中注册receiver组件。直接在代码中通过调用Context的registerReceiver函数,可以在程序中动态注册BroadcastReceiver。registerReceiver的定义形式如下:
SMSBroadcastReceiver receiver = new SMSBroadcastReceiver();
IntentFilter intentFilter= new IntentFilter();
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(receiver, intentFilter);
动态注册的广播接收者,还需要在onDestroy()回调中取消注册
unregisterReceiver(receiver)。
2.发送自定义广播
- 创建自定义广播:
//创建一个传递消息的意图对象
Intent intent = new Intent();
//设置要广播的事件类型
intent.setAction("com.example.broadcast.appointment");
//设置广播的消息数据
intent.putExtra("appointment", "明天天气晴朗,是约会的好日子......");
//发送一个广播消息
sendBroadcast(intent);
- 接收自定义广播:
public class MyBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String appointment = intent.getStringExtra("appointment");
Toast.makeText(context, appointment , 1).show();
}
}
在AndroidManifest.xml中配置广播接收者:
<receiver android:name="com.example.broadcast.MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.broadcast.appointment">
</intent-filter>
</receiver>
3.广播的两种类型
无序广播:所有跟广播的intent匹配的广播接收者都可以收到该广播,并且是没有先后顺序(同时收到)
- 接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播。
- Context.sendBroadcast(intent);
有序广播:所有跟广播的intent匹配的广播接收者都可以收到该广播,但是会按照广播接收者的优先级来决定接收的先后顺序,优先级高的先收到,优先级低的后收到。
- 优先级别声明在 intent-filter 元素的 android:priority 属性中,取值范围:-1000~1000,优先级别也可以调用IntentFilter对象的setPriority()进行设置 。
- Context.sendOrderedBroadcast(intent);
- 结果接收者:所有广播接收者都接收到广播之后,它才接收,并且一定会接收
- abortBroadCast():阻止其他接收者接收这条广播,类似拦截,只有有序广播可以被拦截
4.使用本地广播
只在应用程序内部进行传递的广播,发送和接收都只在本应用程序有效。
本地广播是无法通过静态注册来实现的。因为静态注册是为了让程序未启动也能接收广播。本地广播是在本程序内进行
传递,肯定是已经启动了,因此也完全不需要静态注册。使用LocalBroadcastManager对广播进行管理,代码如下。
public class MainActivity extends Activity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
//本地广播数据类型实例
private LocalBroadcastManager localBroadcastManager;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//获取本地广播实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcast.LOCAL_BROADCAST");
//发送本地广播。
localBroadcastManager.sendBroadcast(intent);
}
});
//新建intentFilter并给其action标签赋值。
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcast.LOCAL_BROADCAST");
//创建广播接收器实例,并注册。将其接收器与action标签进行绑定。
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
}
//在onDestroy()方法中取消注册
@Override
public void onDestroy(){
super.onDestroy();
//取消注册调用的是unregisterReceiver()方法,并传入接收器实例。
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
Toast.makeText(context,"这是本地广播接收器",Toast.LENGTH_SHORT).show();
}
}
}
- 本地广播的优势
- 可以明确地知道正在发送的广播不会离开我们的程序, 因此不需要担心机密数据泄漏的问题。
- 其他的程序无法将广播发送到我们程序的内部, 因此不需要担心会有安全漏洞的隐患。
- 发送本地广播比起发送系统全局广播将会更加高效。
5.广播的生命周期
广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁
广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框
最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
耗时的较长的工作最好放在服务中完成