廣播接收器用于響應(yīng)來(lái)之其他應(yīng)用程序或者系統(tǒng)的廣播消息。這些消息有時(shí)被稱(chēng)為事件或者意圖。例如,應(yīng)用程序可以初始化廣播來(lái)讓其他的應(yīng)用程序指導(dǎo)一些數(shù)據(jù)已經(jīng)被下載到設(shè)備,并可以為他們所用。這樣廣播接收器可以定義適當(dāng)?shù)膭?dòng)作來(lái)攔截這些通信。
有以下兩個(gè)重要的步驟來(lái)使系統(tǒng)的廣播意圖配合廣播接收器工作。
還有一個(gè)附加的步驟,要實(shí)現(xiàn)自定義的意圖,你必須創(chuàng)建并廣播這些意圖。
廣播接收器需要實(shí)現(xiàn)為BroadcastReceiver類(lèi)的子類(lèi),并重寫(xiě)onReceive()方法來(lái)接收以Intent對(duì)象為參數(shù)的消息。
public class MyReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show(); } }
應(yīng)用程序通過(guò)在AndroidManifest.xml中注冊(cè)廣播接收器來(lái)監(jiān)聽(tīng)制定的廣播意圖。假設(shè)我們將要注冊(cè)MyReceiver來(lái)監(jiān)聽(tīng)系統(tǒng)產(chǎn)生的ACTION_BOOT_COMPLETED事件。該事件由Android系統(tǒng)的啟動(dòng)進(jìn)程完成時(shí)發(fā)出。
<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>
現(xiàn)在,無(wú)論什么時(shí)候Android設(shè)備被啟動(dòng),都將被廣播接收器MyReceiver所攔截,并且在onReceive()中實(shí)現(xiàn)的邏輯將被執(zhí)行。
有許多系統(tǒng)產(chǎn)生的事件被定義為類(lèi)Intent中的靜態(tài)常量值。下面的表格列舉了重要的系統(tǒng)事件。
事件常量 | 描述 |
---|---|
android.intent.action.BATTERY_CHANGED | 持久的廣播,包含電池的充電狀態(tài),級(jí)別和其他信息。 |
android.intent.action.BATTERY_LOW | 標(biāo)識(shí)設(shè)備的低電量條件。 |
android.intent.action.BATTERY_OKAY | 標(biāo)識(shí)電池在電量低之后,現(xiàn)在已經(jīng)好了。 |
android.intent.action.BOOT_COMPLETED | 在系統(tǒng)完成啟動(dòng)后廣播一次。 |
android.intent.action.BUG_REPORT | 顯示報(bào)告bug的活動(dòng)。 |
android.intent.action.CALL | 執(zhí)行呼叫數(shù)據(jù)指定的某人。 |
android.intent.action.CALL_BUTTON | 用戶點(diǎn)擊"呼叫"按鈕打開(kāi)撥號(hào)器或者其他撥號(hào)的合適界面。 |
android.intent.action.DATE_CHANGED | 日期發(fā)生改變。 |
android.intent.action.REBOOT | 設(shè)備重啟。 |
如果你想要應(yīng)用程序中生成并發(fā)送自定義意圖,你需要在活動(dòng)類(lèi)中通過(guò)sendBroadcast()來(lái)創(chuàng)建并發(fā)送這些意圖。如果你使用sendStickyBroadcast(Intent)方法,則意圖是持久的(sticky),這意味者你發(fā)出的意圖在廣播完成后一直保持著。
public void broadcastIntent(View view) { Intent intent = new Intent(); intent.setAction("cn.uprogrammer.CUSTOM_INTENT"); sendBroadcast(intent); }
cn.uprogrammer.CUSTOM_INTENT的意圖可以像之前我們注冊(cè)系統(tǒng)產(chǎn)生的意圖一樣被注冊(cè)。
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <receiver android:name="MyReceiver"> <intent-filter> <action android:name="cn.uprogrammer.CUSTOM_INTENT"> </action> </intent-filter> </receiver> </application>
這個(gè)實(shí)例將解釋如何創(chuàng)建廣播接收器來(lái)攔截自定義意圖。一旦你熟悉自定義意圖,你可以為應(yīng)用程序編程來(lái)攔截系統(tǒng)產(chǎn)生的意圖。讓我們按照下面的步驟來(lái)修改Hello World實(shí)例章節(jié)中我們創(chuàng)建的Android應(yīng)用程序。
步驟 | 描述 |
---|---|
1 | 使用Android Studio來(lái)創(chuàng)建Android應(yīng)用程序并命名為broadcastreceiver,并放在Hello World實(shí)例章節(jié)中的cn.uprogrammer.broadcastreceiver包下。 |
2 | 修改主要活動(dòng)文件MainActivity.java來(lái)添加broadcastIntent()方法。 |
3 | 在cn.uprogrammer.broadcastreceiver包下創(chuàng)建名為MyReceiver.java的新的Java文件來(lái)定義廣播接收器。 |
4 | 應(yīng)用程序可以處理一個(gè)或多個(gè)自定義或者系統(tǒng)的意圖,沒(méi)有任何限制。每個(gè)你想攔截的意圖都需要使用<receiver.../>標(biāo)簽在AndroidManifest.xml中注冊(cè)。 |
5 | 修改res/layout/activity_main.xml文件中的默認(rèn)內(nèi)容來(lái)包含一個(gè)廣播意圖的按鈕。 |
6 | 不需要修改字符串文件,Android Studio會(huì)注意string.xml文件。 |
7 | 啟動(dòng)Android模擬器來(lái)運(yùn)行應(yīng)用程序,并驗(yàn)證應(yīng)用程序所做改變的結(jié)果。 |
下面是修改的主要活動(dòng)文件src/cn.uprogrammer.broadcastreceiver/MainActivity.java的內(nèi)容。這個(gè)文件包含了每個(gè)基礎(chǔ)的生命周期方法。我們添加了broadcastIntent()方法來(lái)廣播自定義事件。
package cn.uprogrammer.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/cn.uprogrammer.broadcastreceiver/MyReceiver.java的內(nèi)容:
package cn.uprogrammer.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, "檢測(cè)到意圖。", Toast.LENGTH_LONG).show(); } }
接下來(lái)修改AndroidManifest.xml文件。這里通過(guò)添加<receiver.../>標(biāo)簽來(lái)包含我們的廣播接收器:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cn.uprogrammer.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文件的內(nèi)容,包含廣播自定義意圖的按鈕。
<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="廣播實(shí)例" 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.uprogrammer.cn" 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文件的內(nèi)容,定義了兩個(gè)新的常量。
<?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>
讓我們運(yùn)行剛剛修改的Hello World!應(yīng)用程序。我假設(shè)你已經(jīng)在安裝環(huán)境時(shí)創(chuàng)建了AVD。打開(kāi)你的項(xiàng)目中的活動(dòng)文件,點(diǎn)擊工具欄中的圖標(biāo)來(lái)在Android Studio中運(yùn)行應(yīng)用程序。Android Studio在AVD上安裝應(yīng)用程序并啟動(dòng)它。如果一切順利,將在模擬器窗口上顯示如下:
現(xiàn)在點(diǎn)擊"廣播意圖"按鈕來(lái)廣播我們的自定義意圖。這將廣播我們的自定義意圖"cn.programmer.CUSTOM_INTENT",在我們注冊(cè)的廣播接收器MyReceiver中攔截并執(zhí)行我們實(shí)現(xiàn)的邏輯。模擬器的底部將出現(xiàn)toast。如下:
你可以嘗試實(shí)現(xiàn)其他的廣播接收器來(lái)攔截系統(tǒng)產(chǎn)生的意圖,如系統(tǒng)啟動(dòng),日期改變和低電量等。