BroadcastReceiver 用于异步接收广播Intent。主要有两大类,用于接收广播的:
·正常广播 Normal broadcasts(用 Context.sendBroadcast()发送)是完全异步的。它们都运行在一个未定义的顺序,通常是在同一时间。这样会更有效,但意味着receiver不能包含所要使用的结果或中止的API。
·有序广播 Ordered broadcasts(用 Context.sendOrderedBroadcast()发送)每次被发送到一个receiver。所谓有序,就是每个receiver执行后可以传播到下一个receiver,也可以完全中止传播--不传播给其他receiver。 而receiver运行的顺序可以通过matched intent-filter 里面的android:priority来控制,当priority优先级相同的时候,Receiver以任意的顺序运行。
要注意的是,即使是Normal broadcasts,系统在某些情况下可能会恢复到一次传播给一个receiver。 特别是receiver可能需要创建一个进程,为了避免系统超载,只能一次运行一个receiver。
Broadcast Receiver 并没有提供可视化的界面来显示广播信息。可以使用Notification和Notification Manager来实现可视化的信息的界面,显示广播信息的内容,图标及震动信息。
生命周期
一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)的才有效的,当从该函数返回后,该对象就无效的了,结束生命周期。
因此从这个特征可以看出,在所调用的onReceive(Context, Intent)函数里,不能有过于耗时的操作,不能使用线程来执行。对于耗时的操作,请start service来完成。因为当得到其他异步操作所返回的结果时,BroadcastReceiver 可能已经无效了。
发送广播
事件的广播比较简单,构建Intent对象,可调用sendBroadcast(Intent)方法将广播发出。另外还有sendOrderedBroadcast(),sendStickyBroadcast()等方法,请查阅API Doc。
1.new Intent with action name
Intent intent = new Intent(String action);
或者 只是new Intent, 然后
intent.setAction(String action);
2.set data等准备好了后,in activity,
sendBroadcast(Intent); // 发送广播
接收广播
通过定义一个继承BroadcastReceiver类来实现,继承该类后覆盖其onReceiver方法,并在该方法中响应事件。
- public class SMSReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // get data from SMS intent
- Bundle bundle = intent.getExtras();
- if (bundle != null){
- // get message by "pdus"
- Object[] objArray = (Object[]) bundle.get("pdus");
- // rebuild SMS
- SmsMessage[] messages = new SmsMessage[objArray.length];
- for (int i=0; i < objArray.length; i++){
- messages[i] = SmsMessage.createFromPdu((byte[])objArray[i]);
- StringBuilder str = new StringBuilder("from: ");
- str.append(messages[i].getDisplayOriginatingAddress());
- str.append("\nmessage:\n");
- str.append(messages[i].getDisplayMessageBody());
- Toast.makeText(context, str.toString(), Toast.LENGTH_LONG)
- .show();
- }
- }
- }
- }
注册Receiver
注册有两种方式:
1. 静态方式,在AndroidManifest.xml的application里面定义receiver并设置要接收的action。
- <receiver android:name=".SMSReceiver">
- <intent-filter>
- <action android:name="android.provider.Telephony.SMS_RECEIVED" />
- </intent-filter>
- </receiver>
2. 动态方式, 在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。
- public class HelloDemo extends Activity {
- private BroadcastReceiver receiver;
- @Override
- protected void onStart() {
- super.onStart();
- receiver = new CallReceiver();
- registerReceiver(receiver, new IntentFilter("android.intent.action.PHONE_STATE"));
- }
- @Override
- protected void onStop() {
- unregisterReceiver(receiver);
- super.onStop();
- }
- }
一个receiver可以接收多个action的,即可以有多个intent-filter,需要在onReceive里面对intent.getAction(action name)进行判断。
个人推荐使用静态注册方式,由系统来管理receiver,而且程序里的所有receiver,可以在xml里面一目了然。而动态注册方式,隐藏在代码中,比较难发现。
而且动态注册,需要特别注意的是,在退出程序前要记得调用Context.unregisterReceiver()方法。一般在activity的onStart()里面进行注册, onStop()里面进行注销。官方提醒,如果在Activity.onResume()里面注册了,就必须在Activity.onPause()注销。
Permission权限
要接收某些action,需要在AndroidManifest.xml里面添加相应的permission。例如接收SMS:
- <uses-permission android:name="android.permission.RECEIVE_SMS" />
下面给出动态注册的接收来电的广播处理的CallReceiver的代码:
一种方式是直接读取intent.getStringExtra("incoming_number")来获取来电号码:
- public class CallReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- TelephonyManager teleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-
- switch(teleManager.getCallState()){
- case TelephonyManager.CALL_STATE_RINGING: //响铃
- Toast.makeText(context, "Ringing: " + intent.getStringExtra("incoming_number"), Toast.LENGTH_LONG).show();
- break;
- case TelephonyManager.CALL_STATE_OFFHOOK: //接听
- Toast.makeText(context, "OffHook: " + intent.getStringExtra("incoming_number"), Toast.LENGTH_LONG).show();
- break;
- case TelephonyManager.CALL_STATE_IDLE: //挂断
- Toast.makeText(m_context, "Idle: " + incomingNumber, Toast.LENGTH_LONG).show();
- break;
- }
- }
- }
在运行时,发现除了响铃时可以获取来电号码,接听和挂断都不能成功获取的,显示为null。
另一种方式是通过PhoneStateListener的onCallStateChanged来监听状态的变化:
- public class CallReceiver extends BroadcastReceiver {
- private Context m_context;
- @Override
- public void onReceive(Context context, Intent intent) {
- m_context = context;
- TelephonyManager teleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- teleManager.listen(new PhoneStateListener(){
- @Override
- public void onCallStateChanged(int state, String incomingNumber) {
- switch(state){
- case TelephonyManager.CALL_STATE_RINGING: //响铃
- Toast.makeText(m_context, "Ringing: " + incomingNumber, Toast.LENGTH_LONG)
- .show();
- break;
- case TelephonyManager.CALL_STATE_OFFHOOK: //接听
- Toast.makeText(m_context, "OffHook: " + incomingNumber, Toast.LENGTH_LONG)
- .show();
- break;
- case TelephonyManager.CALL_STATE_IDLE: //挂断
- Toast.makeText(m_context, "Idle: " + incomingNumber, Toast.LENGTH_LONG)
- .show();
- break;
- }
- }}, PhoneStateListener.LISTEN_CALL_STATE);
- }
- }
运行时也发现incomingNumber在接听和挂断时获取为blank。
因为这里监听的是通话的状态变化,所以这个receiver会被调用3次。
监听通话状态需要加上权限:
- <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
===========
小结:
1. 对于sendBroadCast的intent对象,需要设置其action name;
2. 推荐使用显式指明receiver,在配置文件AndroidManifest.xml指明;
3. 一个receiver可以接收多个action;
4. 每次接收广播都会重新生成一个接收广播的对象,再次调用onReceive;
5. 在BroadCast 中尽量不要处理太多逻辑问题,建议复杂的逻辑交给Activity 或者 Service 去处理。
相关推荐
文档主要是讲Android开发的四大组件详解,包含 Activity详解 ,Service详解,Broadcast Receiver详解,Content Provider详解 外加一个重要组件 intent的详解。 文章内容来自网络,本文是一个总结性文章。
四大组件 Activity Service content provider broadcast receiver
一个关于Android四大组件Broadcast Receiver的小demo
Android四大组件之Broadcast Receiver 作者:白璐 日期:2020/2/23 文章目录Android四大组件之Broadcast Receiver概述广播接收器(Broadcast Receiver)Broadcast Receiver简介Broadcast Receiver的注册一. 静态注册...
android 四大组件初学者必备,activity services等等
本篇文章主要介绍了Android开发应用中Broadcast Receiver组件详解,想要学习的同学可以了解一下。
学习Android的四大组件之一Broadcast时的练习!
Android新手Broadcast Receiver简单实现 发送广播并实现接收广播
Android系统中的广播Broadcast,Receiver例子,可以用LogCat察看整个运行的生命周期.MainActivity界面上有两个按钮,分别是Start Counter和Stop Counter按钮,点击前者开始计数,而点击后者则停止计数。
利用广播Broadcast Receiver,在2个不同的Activity传递数据
Android 应用案例——备忘录,通过一个Android基础应用项目综合应用了Android中的各种组件,包括Activity、Service、Broadcast Receiver、ContentProvider、Intent和View的应用 第18章 Android应用案例——无线点餐...
Android源代码 包含2个工程: 工程1:Broadcast的Sender,负责发送广播 工程2:Broadcast的Receiver,负责监听广播(2种注册方式:XML和代码动态注册),一旦监听到广播,弹出Activity,并显示广播携带的数据。 本...
第八章_Android广播事件处理Broadcast_Receiver 让你更快了解
Android几大组件源码分析 一、Activity详解 二、Service详解 三、Content Provider详解 四、Broadcast Receiver详解
《Android应用开发详解源码》目录第1章 Android概述 第2章 Android开发基础 第3章 Android中的资源访问 第4章 Android用户界面 第5章 Android基本程序单元Activity 第6章 Android组件之间的信使Intent 第7章 Android...
简要解释一下activity、 intent 、intent filter、service、Broadcast、BroadcaseReceiver
该文档是简单的介绍了其android中的广播机制的用法,比较通俗易懂。
介绍了andorid四大组件之一的BroadcastReceiver
本示例 利用Broadcast Receiver 启动Service,在这里同时又启动了一个Activity用于提示服务启动成功