Android 廣播接收器(Broadcast Receivers)
廣播接收器用於回應來自其他應用程式或者系統的廣播消息。這些消息有時被稱為事件或者意圖。例如,應用程式可以初始化廣播來讓其他的應用程式知道一些數據已經被下載到設備,並可以為他們所用。這樣廣播接收器可以定義適當的動作來攔截這些通信。
有以下兩個重要的步驟來使系統的廣播意圖配合廣播接收器工作。
- 創建廣播接收器
- 註冊廣播接收器
還有一個附加的步驟,要實現自定義的意圖,你必須創建並廣播這些意圖。
創建廣播接收器
廣播接收器需要實現為BroadcastReceiver類的子類,並重寫onReceive()方法來接收以Intent對象為參數的消息。
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show(); } }
註冊廣播接收器
應用程式通過在AndroidManifest.xml中註冊廣播接收器來監聽制定的廣播意圖。假設我們將要註冊MyReceiver來監聽系統產生的ACTION_BOOT_COMPLETED事件。該事件由Android系統的啟動進程完成時發出。
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <receiver android:name="MyReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"> </action> </intent-filter> </receiver> </application>
現在,無論什麼時候Android設備被啟動,都將被廣播接收器MyReceiver所攔截,並且在onReceive()中實現的邏輯將被執行。
有許多系統產生的事件被定義為類Intent中的靜態常量值。下麵的表格列舉了重要的系統事件。
事件常量 | 描述 |
---|---|
android.intent.action.BATTERY_CHANGED | 持久的廣播,包含電池的充電狀態,級別和其他資訊。 |
android.intent.action.BATTERY_LOW | 標識設備的低電量條件。 |
android.intent.action.BATTERY_OKAY | 標識電池在電量低之後,現在已經好了。 |
android.intent.action.BOOT_COMPLETED | 在系統完成啟動後廣播一次。 |
android.intent.action.BUG_REPORT | 顯示報告bug的活動。 |
android.intent.action.CALL | 執行呼叫數據指定的某人。 |
android.intent.action.CALL_BUTTON | 用戶點擊"呼叫"按鈕打開撥號器或者其他撥號的合適介面。 |
android.intent.action.DATE_CHANGED | 日期發生改變。 |
android.intent.action.REBOOT | 設備重啟。 |
廣播自定義意圖
如果你想要應用程式中生成併發送自定義意圖,你需要在活動類中通過sendBroadcast()來創建併發送這些意圖。如果你使用sendStickyBroadcast(Intent)方法,則意圖是持久的(sticky),這意味者你發出的意圖在廣播完成後一直保持著。
public void broadcastIntent(View view) { Intent intent = new Intent(); intent.setAction("com.zaixian.CUSTOM_INTENT"); sendBroadcast(intent); }
com.zaixian.CUSTOM_INTENT的意圖可以像之前我們註冊系統產生的意圖一樣被註冊。
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <receiver android:name="MyReceiver"> <intent-filter> <action android:name="com.zaixian.CUSTOM_INTENT"> </action> </intent-filter> </receiver> </application>
實例
這個實例將解釋如何創建廣播接收器來攔截自定義意圖。一旦你熟悉自定義意圖,你可以為應用程式編程來攔截系統產生的意圖。讓我們按照下麵的步驟來修改Hello World實例章節中我們創建的Android應用程式。
步驟 | 描述 |
---|---|
1 | 使用Android Studio來創建Android應用程式並命名為broadcastreceiver,並放在Hello World實例章節中的com.zaixian.broadcastreceiver包下。 |
2 | 修改主要活動檔MainActivity.java來添加broadcastIntent()方法。 |
3 | 在com.zaixian.broadcastreceiver包下創建名為MyReceiver.java的新的Java檔來定義廣播接收器。 |
4 | 應用程式可以處理一個或多個自定義或者系統的意圖,沒有任何限制。每個你想攔截的意圖都需要使用<receiver.../>標籤在AndroidManifest.xml中註冊。 |
5 | 修改res/layout/activity_main.xml檔中的默認內容來包含一個廣播意圖的按鈕。 |
6 | 不需要修改字串檔,Android Studio會注意string.xml檔。 |
7 | 啟動Android模擬器來運行應用程式,並驗證應用程式所做改變的結果。 |
下麵是修改的主要活動檔src/com.zaixian.broadcastreceiver/MainActivity.java的內容。這個檔包含了每個基礎的生命週期方法。我們添加了broadcastIntent()方法來廣播自定義事件。
package com.zaixian.broadcastreceiver; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.content.Intent; import android.view.View; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } // 廣播自定義意圖 public void broadcastIntent(View view){ Intent intent = new Intent(); intent.setAction("cn.programmer.CUSTOM_INTENT"); sendBroadcast(intent); } }
下麵是src/com.zaixian.broadcastreceiver/MyReceiver.java的內容:
package com.zaixian.broadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "檢測到意圖。", Toast.LENGTH_LONG).show(); } }
接下來修改AndroidManifest.xml檔。這裏通過添加<receiver.../>標籤來包含我們的廣播接收器:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zaixian.broadcastreceiver" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="22" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <receiver android:name="MyReceiver"> <intent-filter> <action android:name="cn.programmer.CUSTOM_INTENT"> </action> </intent-filter> </receiver> </application> </manifest>
下麵是res/layout/activity_main.xml檔的內容,包含廣播自定義意圖的按鈕。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="廣播實例" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:textSize="30dp" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="www.xuhuhu.com" android:textColor="#ff87ff09" android:textSize="30dp" android:layout_above="@+id/imageButton" android:layout_centerHorizontal="true" android:layout_marginBottom="40dp" /> <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageButton" android:src="@drawable/ic_launcher" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button2" android:text="廣播意圖" android:onClick="broadcastIntent" android:layout_below="@+id/imageButton" android:layout_centerHorizontal="true" /> </RelativeLayout>
下麵是res/values/strings.xml檔的內容,定義了兩個新的常量。
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Android Broadcast Receiver</string> <string name="action_settings">Settings</string> <string name="menu_settings">Settings</string> <string name="title_activity_main">Main Activity</string> </resources>
讓我們運行剛剛修改的Hello World!應用程式。我假設你已經在安裝環境時創建了AVD。打開你的專案中的活動檔,點擊工具欄中的圖示來在Android Studio中運行應用程式。Android Studio在AVD上安裝應用程式並啟動它。如果一切順利,將在模擬器窗口上顯示如下:
現在點擊"廣播意圖"按鈕來廣播我們的自定義意圖。這將廣播我們的自定義意圖"cn.programmer.CUSTOM_INTENT",在我們註冊的廣播接收器MyReceiver中攔截並執行我們實現的邏輯。模擬器的底部將出現toast。如下:
你可以嘗試實現其他的廣播接收器來攔截系統產生的意圖,如系統啟動,日期改變和低電量等。