Android BroadcastReceiver广播

 


BroadcastReceiver


一.广播简介:

(一)、广播传播机制:
广播接收器,也被称为全局事件,或系统事件。

在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理。这个广播跟我们传统意义中的电台广播有些相似之处。之所以叫做广播,就是因为它只负责“说”而不管你“听不听”,也就是不管你接收方如何处理。另外,广播可以被不只一个应用程序所接收,当然也可能不被任何应用程序所接收。
广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。
Android中广播的是操作系统中产生的各种各样的事件。例如,收到一条短信就会产生一个收到短信息的事件。而Android操作系统一旦内部产生了这些事件,就会向所有的广播接收器对象来广播这些事件。

(二)、广播机制的三要素:

Android广播机制包含三个基本要素:
1、广播(Broadcast) - 用于发送广播;
2、广播接收器(BroadcastReceiver) - 用于接收广播;
3、意图内容(Intent)-用于保存广播相关信息的媒介。
Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的Broadcast进行过滤接受并响应的一类组件。

(三)、广播的生命周期:

1、广播接收器仅在它执行这个方法时处于活跃状态。当onReceive()返回后,它即为失活状态。
2、拥有一个活跃状态的广播接收器的进程被保护起来而不会被杀死,但仅拥有失活状态组件的进程则会在其它进程需要它所占有的内存的时候随时被杀掉。
3、如果响应一个广播信息需要很长的一段时间,一般会将其纳入一个衍生的线程中去完成,而不是在主线程内完成它,从而保证用户交互过程的流畅。


二、 广播接收器BroadcastReceiver:
(一)、概念:
BroadcastReceiver(广播接收器)是为了实现系统广播而提供的一种组件,并且广播事件处理机制是系统级别的。比如,我们可以发出一种广播来测试是否收到短信,这时候就可以定义一个BraodcastReceiver来接受广播,当收到短信时提示用户。我们既可以用Intent来启动一个组件,也可以用sendBroadcast()方法发起一个系统级别的事件广播来传递消息。
我们也可以在自己的应用程序中开发BroadcastReceiver,然后把广播接收器这个类或者对象注册到Android操作系统上去,让操作系统知道现在有这样一个广播接收器正在等待接收Android操作系统的广播,即在自己的应用程序中实现BroadcastReceiver来监听和响应广播的Intent。
当有广播事件产生时,Android操作系统首先告诉注册到其上面的广播接收器产生了一个怎么样的事件,每个接收器首先判断是不是我这个接收器需要的事件,如果是它所需要的事件,再进行相应的处理。
例子,我们把骚扰电话的黑名单放到数据库中去,当接到电话时会产生一个接电话事件,事先在Android操作系统中注册一个BroadcastReceiver的对象,当产生事件的时候,会通知我们的广播接收器对象,接收器对象接收到消息之后,就会到数据库里面去取所有黑名单电话和接到的这个电话号码进行比较,如果匹配就直接挂掉。

(二)、 注册BroadcastReceiver的方法
BroadcastReceiver用于监听被广播的事件(Intent),为了达到这个目的,BroadcastReceiver必须进行注册,注册的方法有以下两种:
1、静态注册:
静态注册方式是在AndroidManifest.xml的application里面定义receiver并设置要接收的action。
静态注册方式的特点:不管该应用程序是否处于活动状态,都会进行监听。
<receiver 
    android:name=".CallReceiver"
    android:enabled="true">
    <intent-filter > 
 <action android:name="android.intent.action.PHONE_STATE"/>
    </intent-filter>
</receiver>
其中,MyReceiver为继承BroadcastReceiver的类,重写了onReceiver方法,并在onReceiver方法中对广播进行处理。<intent-filter>标签设置过滤器,接收指定action广播。

2、动态注册:
动态注册方式是在activity里面调用当前上下文对象的registerReceiver() 方法 来注册,和静态的内容差不多。一个形参是receiver对象,另一个是IntentFilter对象。而IntentFilter构造方法的参数是要接收的action。
动态注册方式特点:在代码中进行注册后,当应用程序关闭后,就不再进行监听。

MyReceiver receiver = new MyReceiver();
//创建过滤器,并指定action,使之用于接收同action的广播
IntentFilter filter = new IntentFilter("android.intent.action.PHONE_STATE");
//注册广播接收器
registerReceiver(receiver, filter);

 ( 三 )、广播接收器的优先级:

(四)、发送广播:

// 指定广播目标Action
Intent intent = new Intent("MyReceiver_Action");
// 可通过Intent携带消息
intent.putExtra("msg", "发送广播");
// 发送广播消息
sendBroadcast(intent);


(五)、注销BroadcastReceiver:
1、一般在onStart中注册BroadcastReceiver,在onStop中取消BroadcastReceiver。
2、一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)时才有效,当从该函数返回后,该对象就无效的了,结束生命周期。

//注销广播接收器
unregisterReceiver(receiver);

三、接收系统广播:
广播接收器最大的用途就是接受系统发出的消息。例如:截获短信,截获来电等等。

(一)、短信拦截:
(二)、来去电拦截:
(三)、截获屏幕休眠与唤醒:
(四)、开机自动运行:
(五)、手机电池当前电量:

四.BroadcastReceiver所对应的广播分两类:普通广播和有序广播。

1、普通广播通过Context.sendBroadcast()方法来发送。它是完全异步的。
      所有的receivers接收器的执行顺序不确定。因此,所有的receivers接收器接收broadcast的顺序不确定。
     这种方式效率更高。但是BroadcastReceiver无法使用setResult系列,getResult系列及abort系列API。

2、有序广播是通过Context.sendOrderedBroadcast来发送。所有的receiver依次执行。
      BroadcastReceiver可以使用setResult系列函数来将结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以用abort系列函数来让系统丢弃该广播,使该广播不再传送到别的BroadcastReceiver。
      可以通过在intent-filter中设置android:priority属性来设置receiver的优先级。优先级相同的receiver其执行顺序不确定。
      如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。
      有序广播,即从优先级别最高的广播接收器开始接收,接收完了如果没有丢弃,就下传给下一个次高优先级别的广播接收器进行处理,依次类推,直到最后。

3、实例

程序效果:点击按钮,两个Receiver接收同一条广播,在logcat中打印出数据(按照Receiver的优先顺序,Receiver2先,Receiver1后)  

//1,Manifest.xml

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
     ...  
     <application  
         android:icon="@drawable/ic_launcher"  
         android:label="@string/app_name" >  
         ... 
         <receiver android:name=".MyReceiver1">  
             <intent-filter android:priority="200">  
                <action android:name="com.song.123"/>  
             </intent-filter>  
         </receiver>  

         <receiver android:name=".MyReceiver2">  
             <intent-filter android:priority="1000">  
                <action android:name="com.song.123"/>  
             </intent-filter>  
         </receiver>  
     </application>    
</manifest>  

----------------------------------------------------------------------------------------
//2,主Activity  

public class C48_BroadcastActivity extends Activity {  
     /** Called when the activity is first created. */  
     Button button;  
     @Override  
     public void onCreate(Bundle savedInstanceState) {  
         super.onCreate(savedInstanceState);  
         setContentView(R.layout.main);  
         button=(Button)findViewById(R.id.button);  
         button.setOnClickListener(new OnClickListener() {  
              
             @Override  
             public void onClick(View v) {            
                Intent intent=new Intent("com.song.123");  
                 Bundle bundle=new Bundle();  
                 bundle.putString("a", "aaa");  
                 intent.putExtras(bundle);  
                 //有序广播  
                 sendOrderedBroadcast(intent, null);  
             }  
         });            
     }  
}  

----------------------------------------------------------------------------------------
//3,Receiver2

public class MyReceiver2 extends BroadcastReceiver{    
     @Override  
     public void onReceive(Context context, Intent intent) {  
         System.out.println("receiver2");  
//      context.getSystemService(name);  
         Bundle bundle=intent.getExtras();  
         bundle.putString("b", "bbb");  
         System.out.println("a="+bundle.get("a"));  
         setResultExtras(bundle);  
         //终止广播  
//      abortBroadcast();  
     }   
}

//4,Receiver1
public class MyReceiver1 extends BroadcastReceiver{  
  
     @Override  
     public void onReceive(Context context, Intent intent) {  
        
         System.out.println("receiver1");  
         //要不要接受上一个广播接收器receiver2传来的的数据  
         Bundle bundle=getResultExtras(true);  
         System.out.println("a="+bundle.getString("a")+",b="+bundle.getString("b"));  
     } 
     }

----------------------------------------------------------------------------------------
//4,结果

receiver2
a=aaa
receiver1
a=aaa,b=bbb

五、参考:【Android系统广播大全】
    1. String ADD_SHORTCUT_ACTION 动作:在系统中添加一个快捷方式。 
    2. String ALL_APPS_ACTION 动作:列举所有可用的应用。输入:无。 
    3. String ALTERNATIVE_CATEGORY 类别:说明 activity 是用户正在浏览的数据的一个可选操作。 
    4. String ANSWER_ACTION 动作:处理拨入的电话。 
    5. String BATTERY_CHANGED_ACTION 广播:充电状态,或者电池的电量发生变化。 
    6. String BOOT_COMPLETED_ACTION 广播:在系统启动后,这个动作被广播一次(只有一次)。 
    7. String BROWSABLE_CATEGORY 类别:能够被浏览器安全使用的 activities 必须支持这个类别。 
    8. String BUG_REPORT_ACTION 动作:显示 activity 报告错误。 
    9. String CALL_ACTION 动作:拨打电话,被呼叫的联系人在数据中指定。 
    10. String CALL_FORWARDING_STATE_CHANGED_ACTION 广播:语音电话的呼叫转移状态已经改变。 
    11. String CLEAR_CREDENTIALS_ACTION 动作:清除登陆凭证 (credential)。 
    12. String CONFIGURATION_CHANGED_ACTION 广播:设备的配置信息已经改变,参见 Resources.Configuration. 
    13. Creator CREATOR 无 无 
    14. String DATA_ACTIVITY_STATE_CHANGED_ACTION 广播:电话的数据活动(data activity)状态(即收发数据的状态)已经改变。 
    15. String DATA_CONNECTION_STATE_CHANGED_ACTION 广播:电话的数据连接状态已经改变。 
    16. String DATE_CHANGED_ACTION 广播:日期被改变。 
    17. String DEFAULT_ACTION 动作:和 VIEW_ACTION 相同,是在数据上执行的标准动作。 
    18. String DEFAULT_CATEGORY 类别:如果 activity 是对数据执行确省动作(点击, center press)的一个选项,需要设置这个类别。 
    19. String DELETE_ACTION 动作:从容器中删除给定的数据。 
    20. String DEVELOPMENT_PREFERENCE_CATEGORY 类别:说明 activity 是一个设置面板 (development preference panel). 
    21. String DIAL_ACTION 动作:拨打数据中指定的电话号码。 
    22. String EDIT_ACTION 动作:为制定的数据显示可编辑界面。 
    23. String EMBED_CATEGORY 类别:能够在上级(父)activity 中运行。 
    24. String EMERGENCY_DIAL_ACTION 动作:拨打紧急电话号码。 
    25. int FORWARD_RESULT_LAUNCH 启动标记:如果这个标记被设置,而且被一个已经存在的 activity 用来启动新的 activity,已有 activity 的回复目标 (reply target) 会被转移给新的 activity。 
    26. String FOTA_CANCEL_ACTION 广播:取消所有被挂起的 (pending) 更新下载。 
    27. String FOTA_INSTALL_ACTION 广播:更新已经被确认,马上就要开始安装。 
    28. String FOTA_READY_ACTION 广播:更新已经被下载,可以开始安装。 
    29. String FOTA_RESTART_ACTION 广播:恢复已经停止的更新下载。 
    30. String FOTA_UPDATE_ACTION 广播:通过 OTA 下载并安装操作系统更新。 
    31. String FRAMEWORK_INSTRUMENTATION_TEST_CATEGORY 类别:To be used as code under test for framework instrumentation tests. 
    32. String GADGET_CATEGORY 类别:这个 activity 可以被嵌入宿主 activity (activity that is hosting gadgets)。 
    33. String GET_CONTENT_ACTION 动作:让用户选择数据并返回。 
    34. String HOME_CATEGORY 类别:主屏幕 (activity),设备启动后显示的第一个 activity。 
    35. String INSERT_ACTION 动作:在容器中插入一个空项 (item)。 
    36. String INTENT_EXTRA 附加数据:和 PICK_ACTIVITY_ACTION 一起使用时,说明用户选择的用来显示的 activity;和 ADD_SHORTCUT_ACTION 一起使用的时候,描述要添加的快捷方式。 
    37. String LABEL_EXTRA 附加数据:大写字母开头的字符标签,和 ADD_SHORTCUT_ACTION 一起使用。 
    38. String LAUNCHER_CATEGORY 类别:Activity 应该被显示在顶级的 launcher 中。 
    39. String LOGIN_ACTION 动作:获取登录凭证。 
    40. String MAIN_ACTION 动作:作为主入口点启动,不需要数据。 
    41. String MEDIABUTTON_ACTION 广播:用户按下了“Media Button”。 
    42. String MEDIA_BAD_REMOVAL_ACTION 广播:扩展介质(扩展卡)已经从 SD 卡插槽拔出,但是挂载点 (mount point) 还没解除 (unmount)。 
    43. String MEDIA_EJECT_ACTION 广播:用户想要移除扩展介质(拔掉扩展卡)。 
    44. String MEDIA_MOUNTED_ACTION 广播:扩展介质被插入,而且已经被挂载。 
    45. String MEDIA_REMOVED_ACTION 广播:扩展介质被移除。 
    46. String MEDIA_SCANNER_FINISHED_ACTION 广播:已经扫描完介质的一个目录。 
    47. String MEDIA_SCANNER_STARTED_ACTION 广播:开始扫描介质的一个目录。 
    48. String MEDIA_SHARED_ACTION 广播:扩展介质的挂载被解除 (unmount),因为它已经作为 USB 大容量存储被共享。 
    49. String MEDIA_UNMOUNTED_ACTION 广播:扩展介质存在,但是还没有被挂载 (mount)。 
    50. String MESSAGE_WAITING_STATE_CHANGED_ACTION 广播:电话的消息等待(语音邮件)状态已经改变。 
    51. int MULTIPLE_TASK_LAUNCH 启动标记:和 NEW_TASK_LAUNCH 联合使用,禁止将已有的任务改变为前景任务 (foreground)。 
    52. String NETWORK_TICKLE_RECEIVED_ACTION 广播:设备收到了新的网络 "tickle" 通知。 
    53. int NEW_TASK_LAUNCH 启动标记:设置以后,activity 将成为历史堆栈中的第一个新任务(栈顶)。 
    54. int NO_HISTORY_LAUNCH 启动标记:设置以后,新的 activity 不会被保存在历史堆栈中。 
    55. String PACKAGE_ADDED_ACTION 广播:设备上新安装了一个应用程序包。 
    56. String PACKAGE_REMOVED_ACTION 广播:设备上删除了一个应用程序包。 
    57. String PHONE_STATE_CHANGED_ACTION 广播:电话状态已经改变。 
    58. String PICK_ACTION 动作:从数据中选择一个项目 (item),将被选中的项目返回。 
    59. String PICK_ACTIVITY_ACTION 动作:选择一个 activity,返回被选择的 activity 的类(名)。 
    60. String PREFERENCE_CATEGORY 类别:activity是一个设置面板 (preference panel)。 
    61. String PROVIDER_CHANGED_ACTION 广播:更新将要(真正)被安装。 
    62. String PROVISIONING_CHECK_ACTION 广播:要求 polling of provisioning service 下载最新的设置。 
    63. String RUN_ACTION 动作:运行数据(指定的应用),无论它(应用)是什么。 
    64. String SAMPLE_CODE_CATEGORY 类别:To be used as an sample code example (not part of the normal user experience). 
    65. String SCREEN_OFF_ACTION 广播:屏幕被关闭。 
    66. String SCREEN_ON_ACTION 广播:屏幕已经被打开。 
    67. String SELECTED_ALTERNATIVE_CATEGORY 类别:对于被用户选中的数据,activity 是它的一个可选操作。 
    68. String SENDTO_ACTION 动作:向 data 指定的接收者发送一个消息。 
    69. String SERVICE_STATE_CHANGED_ACTION 广播:电话服务的状态已经改变。 
    70. String SETTINGS_ACTION 动作:显示系统设置。输入:无。 
    71. String SIGNAL_STRENGTH_CHANGED_ACTION 广播:电话的信号强度已经改变。 
    72. int SINGLE_TOP_LAUNCH 启动标记:设置以后,如果 activity 已经启动,而且位于历史堆栈的顶端,将不再启动(不重新启动) activity。 
    73. String STATISTICS_REPORT_ACTION 广播:要求 receivers 报告自己的统计信息。 
    74. String STATISTICS_STATE_CHANGED_ACTION 广播:统计信息服务的状态已经改变。 
    75. String SYNC_ACTION 动作:执行数据同步。 
    76. String TAB_CATEGORY 类别:这个 activity 应该在 TabActivity 中作为一个 tab 使用。 
    77. String TEMPLATE_EXTRA 附加数据:新记录的初始化模板。 
    78. String TEST_CATEGORY 类别:作为测试目的使用,不是正常的用户体验的一部分。 
    79. String TIMEZONE_CHANGED_ACTION 广播:时区已经改变。 
    80. String TIME_CHANGED_ACTION 广播:时间已经改变(重新设置)。 
    81. String TIME_TICK_ACTION 广播:当前时间已经变化(正常的时间流逝)。 
    82. String UMS_CONNECTED_ACTION 广播:设备进入 USB 大容量存储模式。 
    83. String UMS_DISCONNECTED_ACTION 广播:设备从 USB 大容量存储模式退出。 
    84. String UNIT_TEST_CATEGORY 类别:应该被用作单元测试(通过 test harness 运行)。 
    85. String VIEW_ACTION 动作:向用户显示数据。 
    86. String WALLPAPER_CATEGORY 类别:这个 activity 能过为设备设置墙纸。 
    87. String WALLPAPER_CHANGED_ACTION 广播:系统的墙纸已经改变。 
    88. String WALLPAPER_SETTINGS_ACTION 动作:显示选择墙纸的设置界面。输入:无。 
    89. String WEB_SEARCH_ACTION 动作:执行 web 搜索。 
    90. String XMPP_CONNECTED_ACTION 广播:XMPP 连接已经被建立。 
    91. String XMPP_DISCONNECTED_ACTION 广播:XMPP 连接已经被断开。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章