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 連接已經被斷開。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章