我們學完了Android四大組件的Activity和Service了,接下來我們一起來學習Android四大組件的第三個吧:BroadcastReceiver(廣播接收者),計划如下圖:
一.BroadcastReceiver的基本概念
舉個形象的例子來理解下BroadcastReceiver,記得以前讀書 的時候,每個班級都會有一個掛在牆上的大喇叭,用來廣播一些通知,比如,開學要去搬書,廣播: "每個班級找幾個同學去教務處拿書",發出這個廣播后,所有同學都會在同一時刻收到這條廣播通知, 收到,但不是每個同學都會去搬書,一般去搬書的都是班里的"大力士",這群"大力士"接到這條 廣播后就會動身去把書搬回可是!
其實BroadcastReceiver就是應用程序間的全局大喇叭,即通信的一個手段, 系統自己在很多時候都會發送廣播,程序就只會接收到自己所關心的廣播內容,這些廣播可能來自於系統,也可能來自於其他應用程序。比如電量低或者充足,剛啟動完,插入耳機,輸入法改變等, 發生這些事件,系統都會發送廣播,這個叫系統廣播,每個APP都會收到,如果你想讓你的應用在接收到 這個廣播的時候做一些操作,比如:系統開機后,偷偷后台跑服務,這個時候你只需要為你的應用 注冊一個用於監視開機的BroadcastReceiver,當接收到開機廣播就做些偷偷摸摸的勾當。
二.廣播的使用示例
2.1 動態注冊監聽網絡變化
廣播的動態注冊就是在java代碼中指定IntentFilter,然后添加不同的Action即可,想監聽什么廣播就寫什么Action,另外動態注冊的廣播,一定要調用unregisterReceiver()這個方法,讓廣播取消注冊。
在onReceive()方法中完成廣播要處理的事務,比如這里的提示Toast信息,如下:
1 package com.nyl.broadcasttest; 2 3 import android.app.Activity; 4 import android.content.BroadcastReceiver; 5 import android.content.Context; 6 import android.content.Intent; 7 import android.content.IntentFilter; 8 import android.support.v7.app.AppCompatActivity; 9 import android.os.Bundle; 10 import android.widget.Toast; 11 12 public class MainActivity extends Activity { 13 14 private IntentFilter intentFilter; 15 private NetworkChangeReceiver networkChangeReceiver; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 21 //創建IntentFilter的實例 22 intentFilter = new IntentFilter(); 23 /** 24 * 當網絡狀態發生變化時,系統發出的正是一條值為android.net.conn.CONNECTIVITY_CHANGE的廣播 25 * 也就是我們廣播接收器想要監聽什么廣播,在這里添加相對應的Action就行了 26 */ 27 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); 28 /** 29 * 實例化NetworkChangeReceiver的實例和IntentFilter的實例都傳了進去, 30 * NetworkChangeReceiver就會收到所有值為android.net.conn.CONNECTIVITY_CHANGE的廣播, 31 * 也就實現了監聽網絡變化的功能 32 */ 33 networkChangeReceiver = new NetworkChangeReceiver(); 34 registerReceiver(networkChangeReceiver,intentFilter); 35 } 36 37 /** 38 * 動態注冊的廣播接收器一定都要取消注冊才行,這里是在onDestroy()方法中通過調用 39 * unregisterReceiver()方法來實現的 40 */ 41 @Override 42 protected void onDestroy() { 43 super.onDestroy(); 44 unregisterReceiver(networkChangeReceiver); 45 } 46 47 //定義一個廣播,繼承自BroadcastReceiver 48 private class NetworkChangeReceiver extends BroadcastReceiver{ 49 /** 50 * 重寫了父類的onReceive()方法, 51 * 每當網絡請求發生變化時,onReceive()方法就會得到執行 52 * @param context 53 * @param intent 54 */ 55 @Override 56 public void onReceive(Context context, Intent intent) { 57 Toast.makeText(context,"沒有網絡,請連接網絡!",Toast.LENGTH_SHORT).show(); 58 } 59 } 60 }
代碼注釋得很詳細,現在運行一下程序,先把網絡給關了,效果圖如下:
2.2 靜態注冊實現開機啟動
動態注冊需程序啟動后才能接受到廣播,靜態廣播就彌補了這個短板,在AndroidManifest.xml中制定<IntentReceiver>就可以讓程序在未啟動的情況下接受到了廣播。
程序接收一條開機廣播,當收到這個廣播時就可以在onReceive()方法里執行相應的邏輯,從而實現開機啟動的功能。代碼如下:
package com.nyl.broadcasttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class BootCompleteReceiver extends BroadcastReceiver{ private final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED"; @Override public void onReceive(Context context, Intent intent) { if (ACTION_BOOT.equals(intent.getAction())){ Toast.makeText(context,"開機完畢",Toast.LENGTH_SHORT).show(); } } }
在AndroidManifest.xml中對該BroadcastReceiver進行注冊,添加開機廣播的intent-filter!對了,別忘了加上android.permission.RECEIVE_BOOT_COMPLETED的權限哦!
把App安裝到手機上,安裝好之后我們的程序就可以接收開機廣播了,為了看到效果,我把我的手機重新啟動,當手機重新啟動開機完畢后,我們的App就會收到系統的開機廣播,彈出一個"開機完畢"的toast消息,效果如下:
這就是表示我們的App已經自動啟動運行了。