和活動、服務及ContentProvider一樣BroadcastReceiver也是Android組件之一,它是可以對客戶端發送的廣播消息作出響應。消息本身是一個Android廣播Intent,廣播消息可以被多個接收程序接收。
在Android系統中,廣播體現在方方面面,例如當開機完成後系統會產生一條廣播,接收到這條廣播就能實現開機啟動服務的功能;當網絡狀態改變時系統會產生一條廣播,接收到這條廣播就能及時地做出提示和保存數據等操作;當電池電量改變時,系統會產生一條廣播,接收到這條廣播就能在電量低時告知用戶及時保存進度,等等。
下面我們就對BroadcastReceiver進行全面的介紹,以了解和掌握它的各種功能和用法。
首先,我們來看一下如何發送廣播:
- private void testSendBroadcast(Activity activity){
- //create an intent with an action
- String uniqueActionString = "com.test.broadcast";
- Intent intent = new Intent(uniqueActionString);
- intent.putExtra("message","HelloWoreld!");
- //send Broadcast
- activity.sendBroadcast(intent);
- }
在上面的代碼中,我們創建了一個唯一、特定操作的Intet,並向其中添加了一個extra消息,然後調用sendBroadcast()方法,發送了一條廣播。
那麼如何接收廣播呢?看代碼
- public class TestReceiver extends BroadcastReceiver{
- private static final String tag = "TestReceiver";
- public void onReceive(Context context,Intent intent){
- Log.i(tag,"intent" + intent);
- String message = intent.getStringExtra("message");
- Log.i(tag,message);
- }
- }
創建廣播接收程序非常簡單,只需擴展BroadcastReceiver類並改寫onReceive()方法。我們可以在接收程序中通過Intent取得廣播發送的具體消息內容。
最後,我們還必須在描述文件中注冊我們編寫的接收程序,否則你將無法收到廣播。
- <receiver android:name=".TestReceiver">
- <intent-filter>
- <action android:name="com.test.broadcast"/>
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </receiver>
這種在描述文件中注冊的方式我們稱之為:靜態方式。這種方式的注冊是常駐型的,也就是說當應用關閉後,如果有廣播信息傳來,TestReceiver也會被系統調用而自動運行,從而接收到廣播消息。
還有一種代碼中實現的動態注冊方式,具體代碼為:
- TestReceiver receiver = new TestReceiver();
- IntentFilter filter = new IntentFilter();
- filter.addAction("com.test.broadcast");
- registerReceiver(receiver, filter);
registerReceiver是android.content.ContextWrapper類中的方法,Activity和Service都繼承了ContextWrapper,所以可以直接調用。在實際應用中,我們在Activity或Service中注冊了一個BroadcastReceiver,當這個Activity或Service被銷毀時如果沒有解除注冊,系統會報一個異常,提示我們是否忘記解除注冊了。可以通過在onDestory()方法中解除注冊來解決這個問題:
- protected void onDestroy() {
- super.onDestroy();
- unregisterReceiver(receiver);
- }
動態注冊與靜態注冊不同的是:它不是常駐的,一旦程序結束,廣播接收也將結束。
下面我們看一個發送接收廣播的完整例子:
首先來看主活動類:
- public class MainActivity extends Activity
- {
- private static final String TAG = "MainActivity";
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- //創建菜單
- @Override
- public boolean onCreateOptionsMenu(Menu menu)
- {
- super.onCreateOptionsMenu(menu);
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.main_menu, menu);
- return true;
- }
- //綁定菜單事件
- @Override
- public boolean onOptionsItemSelected(MenuItem item)
- {
- appendMenuItemText(item);
- //清空textview
- if (item.getItemId() == R.id.menu_clear)
- {
- this.emptyText();
- return true;
- }
- //發送廣播
- if (item.getItemId() == R.id.menu_menu_send_broadcast)
- {
- this.testSendBroadcast();
- return true;
- }
- return true;
- }
- private TextView getTextView()
- {
- return (TextView)findViewById(R.id.text1);
- }
- private void appendMenuItemText(MenuItem item)
- {
- String title = item.getTitle().toString();
- TextView tv = getTextView();
- tv.setText(tv.getText() + "\n" + title);
- }
- private void emptyText()
- {
- TextView tv = getTextView();
- tv.setText("");
- }
- private void testSendBroadcast()
- {
- //create an intent with an action
- String uniqueActionString = "com.test.intents.broadcast";
- Intent intent = new Intent(uniqueActionString);
- intent.putExtra("message","廣播消息發送!");
- //send Broadcast
- this.sendBroadcast(intent);
- }
- }
廣播接收器類:
- public class TestReceiver extends BroadcastReceiver{
- private static final String tag = "TestReceiver";
- public void onReceive(Context context,Intent intent){
- Log.i(tag,"intent" + intent);
- String message = intent.getStringExtra("message");
- Log.i(tag,message);
- }
- }
下來是布局文件:
layout/main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:id="@+id/text1"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Your debug will appear here"
- />
- </LinearLayout>
菜單資源文件:
menu/main_menu.xml
- <?xml version="1.0" encoding="utf-8"?>
- <menu xmlns:android="http://schemas.android.com/apk/res/android">
- <group android:id="@+id/menuGroup_Main">
- <item android:id="@+id/menu_clear" android:title="clear"/>
- <item android:id="@+id/menu_menu_send_broadcast" android:title="broadcast"/>
- </group>
- </menu>