Android廣播接收器


廣播接收器(Broadcast)簡單地從其他應用程式或系統響應廣播訊息。這些訊息有時稱為事件或意圖。例如,應用程式也可以發起廣播,以讓其他應用程式知道某些資料已經被下載到裝置上,可供它們使用。廣播接收器會攔截此通訊,並會採取適當操作(動作)。

以下兩個重要的步驟,在使用廣播接收器工作系統及廣播意圖:

  • 建立廣播接收器

  • 註冊廣播接收器

還有一個附加的步驟,要實現自定義的意圖,那麼將必須建立並廣播意圖。

建立廣播接收器

實現廣播接收機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 裝置啟動,它會被截獲 BroadcastReceiverMyReceiverand 內實現邏輯,首先 onReceive() 將被執行。

有幾個系統產生的事件定義在最後意圖類的靜態欄位。下表列出了一些重要的系統事件。

事件常數 描述
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 顯示活動報告的錯誤。
android.intent.action.CALL 執行呼叫由資料指定某人。
android.intent.action.CALL_BUTTON 使用者按下“呼叫”按鈕進入撥號器或其他適當的使用者介面發出呼叫。
android.intent.action.DATE_CHANGED 日期改變。
android.intent.action.REBOOT 有裝置重新啟動。

廣播客製化意圖

如果希望應用程式本身生成並行送自定義意圖,那麼必須使用sendBroadcast()方法裡面活動類來建立和傳送這些的意圖。使用(意向)sendStickyBroadcast() 方法意圖是黏黏的,這意味著所傳送的意圖保持周廣圍播出後完成。

public void broadcastIntent(View view)
{
   Intent intent = new Intent();
   intent.setAction("com.yiibai.CUSTOM_INTENT");
   sendBroadcast(intent);
}

意圖 com.yiibai.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.yiibai.CUSTOM_INTENT">
      </action>
      </intent-filter>
   </receiver>

</application>

範例

這個例子將解釋如何建立BroadcastReceiver 攔截自定義意圖。熟悉自定義意圖後,就可以編寫應用程式來攔截系統生成的意圖。現在按照下面的步驟來修改前面建立的Hello World範例中 Android 應用程式:

步驟 描述
1 使用Eclipse IDE建立Android應用程式,並將其命名為HelloWorld在包com.example.helloworld下,類似Hello World範例章節中一樣。
2 修改主要活動檔案MainActivity.java新增broadcastIntent()方法。
3 在包com.example.helloworld下建立一個新的Java檔案 MyReceiver.java,並定義一個BroadcastReceiver。
4 應用程式可以處理一個或多個自定義和系統的意圖不受任何限制。要攔截每一個意圖,必須使用 <receiver.../>標籤並註冊在AndroidManifest.xml檔案中。
5 修改 res/layout/activity_main.xml 檔案的預設內容包括:一個按鈕廣播意圖。
6 定義常數 broadcast_inte 在 ntres/values/strings.xml檔案中
7 執行該應用程式啟動Android模擬器並驗證應用程式所做的修改結果。

以下是修改主要活動檔案 src/com.example.helloworld/MainActivity.java 後的內容。這個檔案包括每個生命周期方法。這裡新增了 broadcastIntent() 方法來廣播自定義的意圖。

package com.example.helloworld;

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.activity_main, menu);
      return true;
   }
   // broadcast a custom intent. 
   public void broadcastIntent(View view)
   {
      Intent intent = new Intent();
      intent.setAction("com.yiibai.CUSTOM_INTENT");
      sendBroadcast(intent);
   }
}

下面是 src/com.example.helloworld/MyReceiver.java 的內容:

package com.example.helloworld;

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, "Intent Detected.", Toast.LENGTH_LONG).show();
   }

}

下面將 AndroidManifest.xml 檔案的內容修改。在這裡新增 <service.../>標籤,包括服務:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.helloworld"
   android:versionCode="1"
   android:versionName="1.0" >
   <uses-sdk
      android:minSdkVersion="8"
      android:targetSdkVersion="15" />
   <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="com.yiibai.CUSTOM_INTENT">
          </action>
          </intent-filter>
      </receiver>
   </application>
</manifest>

以下將 res/layout/activity_main.xml 檔案的內容包括一個按鈕來廣播自定義意圖:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >

   <Button android:id="@+id/btnStartService"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="@string/broadcast_intent"
   android:onClick="broadcastIntent"/>

</LinearLayout>

下面將在 res/values/strings.xml 中定義兩個新的常數的內容: 

<resources>

    <string name="app_name">HelloWorld</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">MainActivity</string>
    <string name="broadcast_intent">Broadcast Intent</string>

</resources>

現在執行修改後的 Hello World!應用程式。假設建立了AVD並設定了環境。要從Eclipse執行的應用程式,首先開啟一個專案的活動檔案,從工具列單擊“run” Eclipse Run Icon 圖示。 Eclipse AVD安裝的應用程式,並啟動它,如果設定和應用都沒有問題,將會顯示以下模擬器視窗:

Android Broadcast Demo

現在廣播自定義的意圖,點選上廣播意圖按鈕,這將廣播自定義在 “com.yiibai.CUSTOM_INTENT”  註冊BroadcastReceiver 的意圖將被 MyReceiver攔截。 實現的邏輯如下出現底部的模擬器:

Android Broadcast Intent

可以嘗試執行其他 BroadcastReceiver 攔截系統的意圖,如系統啟動,更改日期,電池電量不足等。