BroadcastReceiver應(yīng)用詳解和舉例_第1頁
BroadcastReceiver應(yīng)用詳解和舉例_第2頁
BroadcastReceiver應(yīng)用詳解和舉例_第3頁
BroadcastReceiver應(yīng)用詳解和舉例_第4頁
BroadcastReceiver應(yīng)用詳解和舉例_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、BroadcastReceiver應(yīng)用詳解據(jù)說程序員是最愛學(xué)習(xí)的群體,IT男都知道,這個(gè)行業(yè)日新月異,必須不斷地學(xué)習(xí)新知識(shí),不斷地為自己注入新鮮的血液,才能使自己跟上技術(shù)的步伐。今天我們來講一下Android中BroadcastReceiver的相關(guān)知識(shí)。BroadcastReceiver也就是“廣播接收者”的意思,顧名思義,它就是用來接收來自系統(tǒng)和應(yīng)用中的廣播。在Android系統(tǒng)中,廣播體現(xiàn)在方方面面,例如當(dāng)開機(jī)完成后系統(tǒng)會(huì)產(chǎn)生一條廣播,接收到這條廣播就能實(shí)現(xiàn)開機(jī)啟動(dòng)服務(wù)的功能;當(dāng)網(wǎng)絡(luò)狀態(tài)改變時(shí)系統(tǒng)會(huì)產(chǎn)生一條廣播,接收到這條廣播就能及時(shí)地做出提示和保存數(shù)據(jù)等操作;當(dāng)電池電量改變時(shí),系統(tǒng)會(huì)產(chǎn)

2、生一條廣播,接收到這條廣播就能在電量低時(shí)告知用戶及時(shí)保存進(jìn)度,等等。Android中的廣播機(jī)制設(shè)計(jì)的非常出色,很多事情原本需要開發(fā)者親自操作的,現(xiàn)在只需等待廣播告知自己就可以了,大大減少了開發(fā)的工作量和開發(fā)周期。而作為應(yīng)用開發(fā)者,就需要數(shù)練掌握Android系統(tǒng)提供的一個(gè)開發(fā)利器,那就是BroadcastReceiver。下面我們就對BroadcastReceiver逐一地分析和演練,了解和掌握它的各種功能和用法。首先,我們來演示一下創(chuàng)建一個(gè)BroadcastReceiver,并讓這個(gè)BroadcastReceiver能夠根據(jù)我們的需要來運(yùn)行。要?jiǎng)?chuàng)建自己的BroadcastReceiver對象

3、,我們需要繼承android.content.BroadcastReceiver,并實(shí)現(xiàn)其onReceive方法。下面我們就創(chuàng)建一個(gè)名為MyReceiver廣播接收者:1. package com.scott.receiver;  2.   3. import android.content.BroadcastReceiver;  4. import android.content.Context;  5. import android.content.Intent;

4、0; 6. import android.util.Log;  7.   8. public class MyReceiver extends BroadcastReceiver   9.       10.     private static final String TAG = "MyRece

5、iver"  11.       12.     Override  13.     public void onReceive(Context context, Intent intent)   14.         String ms

6、g = intent.getStringExtra("msg");  15.         Log.i(TAG, msg);  16.       17.   18.   在onReceive方法內(nèi),我們可以獲取隨廣播而來的Intent中的數(shù)據(jù),這非常重要,就像無線電一樣,包含很多有用的信息。在創(chuàng)建完我們的BroadcastR

7、eceiver之后,還不能夠使它進(jìn)入工作狀態(tài),我們需要為它注冊一個(gè)指定的廣播地址。沒有注冊廣播地址的BroadcastReceiver就像一個(gè)缺少選臺(tái)按鈕的收音機(jī),雖然功能俱備,但也無法收到電臺(tái)的信號。下面我們就來介紹一下如何為BroadcastReceiver注冊廣播地址。靜態(tài)注冊靜態(tài)注冊是在AndroidManifest.xml文件中配置的,我們就來為MyReceiver注冊一個(gè)廣播地址:1. <receiver android:name=".MyReceiver">  2.     &#

8、160;       <intent-filter>  3.                 <action android:name="ent.action.MY_BROADCAST"/>  4.     

9、60;           <category android:name="ent.category.DEFAULT" />  5.             </intent-filter>  6.    

10、0;    </receiver>  配置了以上信息之后,只要是ent.action.MY_BROADCAST這個(gè)地址的廣播,MyReceiver都能夠接收的到。注意,這種方式的注冊是常駐型的,也就是說當(dāng)應(yīng)用關(guān)閉后,如果有廣播信息傳來,MyReceiver也會(huì)被系統(tǒng)調(diào)用而自動(dòng)運(yùn)行。動(dòng)態(tài)注冊動(dòng)態(tài)注冊需要在代碼中動(dòng)態(tài)的指定廣播地址并注冊,通常我們是在Activity或Service注冊一個(gè)廣播,下面我們就來看一下注冊的代碼:1. MyReceiver receiver = n

11、ew MyReceiver();  2.           3. IntentFilter filter = new IntentFilter();  4. filter.addAction("ent.action.MY_BROADCAST");  5.        

12、60;  6. registerReceiver(receiver, filter);  注意,registerReceiver是android.content.ContextWrapper類中的方法,Activity和Service都繼承了ContextWrapper,所以可以直接調(diào)用。在實(shí)際應(yīng)用中,我們在Activity或Service中注冊了一個(gè)BroadcastReceiver,當(dāng)這個(gè)Activity或Service被銷毀時(shí)如果沒有解除注冊,系統(tǒng)會(huì)報(bào)一個(gè)異常,提示我們是否忘記解除注冊了。所以,記得在特定的地方執(zhí)行解除注冊操作:1. Ov

13、erride  2. protected void onDestroy()   3.     super.onDestroy();  4.     unregisterReceiver(receiver);  5.   執(zhí)行這樣行代碼就可以解決問題了。注意,這種注冊方式與靜態(tài)注冊相反,不是常駐型的,也就是說廣播會(huì)跟隨程序的生命周期。我們可以根據(jù)以上任意一種方法完成注冊,當(dāng)注冊完成之后,這

14、個(gè)接收者就可以正常工作了。我們可以用以下方式向其發(fā)送一條廣播:1. public void send(View view)   2.     Intent intent = new Intent("ent.action.MY_BROADCAST");  3.     intent.putExtra("msg", "h

15、ello receiver.");  4.     sendBroadcast(intent);  5.   注意,sendBroadcast也是android.content.ContextWrapper類中的方法,它可以將一個(gè)指定地址和參數(shù)信息的Intent對象以廣播的形式發(fā)送出去。點(diǎn)擊發(fā)送按鈕,執(zhí)行send方法,控制臺(tái)打印如下:看到這樣的打印信息,表明我們的廣播已經(jīng)發(fā)出去了,并且被MyReceiver準(zhǔn)確無誤的接收到了。上面的例子只是一個(gè)接收者來接收廣播,如果有多個(gè)接收

16、者都注冊了相同的廣播地址,又會(huì)是什么情況呢,能同時(shí)接收到同一條廣播嗎,相互之間會(huì)不會(huì)有干擾呢?這就涉及到普通廣播和有序廣播的概念了。普通廣播(Normal Broadcast)普通廣播對于多個(gè)接收者來說是完全異步的,通常每個(gè)接收者都無需等待即可以接收到廣播,接收者相互之間不會(huì)有影響。對于這種廣播,接收者無法終止廣播,即無法阻止其他接收者的接收動(dòng)作。為了驗(yàn)證以上論斷,我們新建三個(gè)BroadcastReceiver,演示一下這個(gè)過程,F(xiàn)irstReceiver、SecondReceiver和ThirdReceiver的代碼如下:1. package com.scott.receiver;

17、  2.   3. import android.content.BroadcastReceiver;  4. import android.content.Context;  5. import android.content.Intent;  6. import android.util.Log;  7.   8. public class FirstReceiver extends

18、 BroadcastReceiver   9.       10.     private static final String TAG = "NormalBroadcast"  11.       12.     Override  1

19、3.     public void onReceive(Context context, Intent intent)   14.         String msg = intent.getStringExtra("msg");  15.        

20、 Log.i(TAG, "FirstReceiver: " + msg);  16.       17.   18.   1. public class SecondReceiver extends BroadcastReceiver   2.       3.  &#

21、160;  private static final String TAG = "NormalBroadcast"  4.       5.     Override  6.     public void onReceive(Context context, Intent

22、60;intent)   7.         String msg = intent.getStringExtra("msg");  8.         Log.i(TAG, "SecondReceiver: " + msg);  9.  

23、60;    10.   11.   1. public class ThirdReceiver extends BroadcastReceiver   2.       3.     private static final String TAG = "NormalBroadc

24、ast"  4.       5.     Override  6.     public void onReceive(Context context, Intent intent)   7.         String msg

25、0;= intent.getStringExtra("msg");  8.         Log.i(TAG, "ThirdReceiver: " + msg);  9.       10.   11.   然后再次點(diǎn)擊發(fā)送按鈕,發(fā)送一條廣播,控制臺(tái)打印如下:看來這三個(gè)接收者都接收到這條

26、廣播了,我們稍微修改一下三個(gè)接收者,在onReceive方法的最后一行添加以下代碼,試圖終止廣播:1. abortBroadcast();  再次點(diǎn)擊發(fā)送按鈕,我們會(huì)發(fā)現(xiàn),控制臺(tái)中三個(gè)接收者仍然都打印了自己的日志,表明接收者并不能終止廣播。有序廣播(Ordered Broadcast)有序廣播比較特殊,它每次只發(fā)送到優(yōu)先級較高的接收者那里,然后由優(yōu)先級高的接受者再傳播到優(yōu)先級低的接收者那里,優(yōu)先級高的接收者有能力終止這個(gè)廣播。為了演示有序廣播的流程,我們修改一下上面三個(gè)接收者的代碼,如下:1. package com.scott.receiver; &#

27、160;2.   3. import android.content.BroadcastReceiver;  4. import android.content.Context;  5. import android.content.Intent;  6. import android.os.Bundle;  7. import android.util.Log;  8.   9. public 

28、class FirstReceiver extends BroadcastReceiver   10.       11.     private static final String TAG = "OrderedBroadcast"  12.       13.  

29、   Override  14.     public void onReceive(Context context, Intent intent)   15.         String msg = intent.getStringExtra("msg");  16. 

30、60;       Log.i(TAG, "FirstReceiver: " + msg);  17.           18.         Bundle bundle = new Bundle();  

31、19.         bundle.putString("msg", msg + "FirstReceiver");  20.         setResultExtras(bundle);  21.       22.   23.  

32、 1. public class SecondReceiver extends BroadcastReceiver   2.       3.     private static final String TAG = "OrderedBroadcast"  4.     

33、60; 5.     Override  6.     public void onReceive(Context context, Intent intent)   7.         String msg = getResultExtras(true).getString("msg&

34、quot;);  8.         Log.i(TAG, "SecondReceiver: " + msg);  9.           10.         Bundle bundle = new&#

35、160;Bundle();  11.         bundle.putString("msg", msg + "SecondReceiver");  12.         setResultExtras(bundle);  13.       

36、14.   15.   1. public class ThirdReceiver extends BroadcastReceiver   2.       3.     private static final String TAG = "OrderedBroadcast"  4. &#

37、160;     5.     Override  6.     public void onReceive(Context context, Intent intent)   7.         String msg = getResultExtras(t

38、rue).getString("msg");  8.         Log.i(TAG, "ThirdReceiver: " + msg);  9.       10.   11.   我們注意到,在FirstReceiver和SecondReceiver中最后都使用了setResultExtra

39、s方法將一個(gè)Bundle對象設(shè)置為結(jié)果集對象,傳遞到下一個(gè)接收者那里,這樣以來,優(yōu)先級低的接收者可以用getResultExtras獲取到最新的經(jīng)過處理的信息集合。代碼改完之后,我們需要為三個(gè)接收者注冊廣播地址,我們修改一下AndroidMainfest.xml文件:1. <receiver android:name=".FirstReceiver">  2.     <intent-filter android:priority="1000">

40、60; 3.         <action android:name="ent.action.MY_BROADCAST"/>  4.         <category android:name="ent.category.DEFAULT" />  

41、5.     </intent-filter>  6. </receiver>  7. <receiver android:name=".SecondReceiver">  8.     <intent-filter android:priority="999">  9.      

42、;   <action android:name="ent.action.MY_BROADCAST"/>  10.         <category android:name="ent.category.DEFAULT" />  11.     </intent-

43、filter>  12. </receiver>  13. <receiver android:name=".ThirdReceiver">  14.     <intent-filter android:priority="998">  15.         <action a

44、ndroid:name="ent.action.MY_BROADCAST"/>  16.         <category android:name="ent.category.DEFAULT" />  17.     </intent-filter>  18. </recei

45、ver>  我們看到,現(xiàn)在這三個(gè)接收者的<intent-filter>多了一個(gè)android:priority屬性,并且依次減小。這個(gè)屬性的范圍在-1000到1000,數(shù)值越大,優(yōu)先級越高。現(xiàn)在,我們需要修改一下發(fā)送廣播的代碼,如下:1. public void send(View view)   2.     Intent intent = new Intent("ent.action

46、.MY_BROADCAST");  3.     intent.putExtra("msg", "hello receiver.");  4.     sendOrderedBroadcast(intent, "scott.permission.MY_BROADCAST_PERMISSION");  5.   注意,使用sendOrder

47、edBroadcast方法發(fā)送有序廣播時(shí),需要一個(gè)權(quán)限參數(shù),如果為null則表示不要求接收者聲明指定的權(quán)限,如果不為null,則表示接收者若要接收此廣播,需聲明指定權(quán)限。這樣做是從安全角度考慮的,例如系統(tǒng)的短信就是有序廣播的形式,一個(gè)應(yīng)用可能是具有攔截垃圾短信的功能,當(dāng)短信到來時(shí)它可以先接受到短信廣播,必要時(shí)終止廣播傳遞,這樣的軟件就必須聲明接收短信的權(quán)限。所以我們在AndroidMainfest.xml中定義一個(gè)權(quán)限:1. <permission android:protectionLevel="normal"  2.  &#

48、160;          android:name="scott.permission.MY_BROADCAST_PERMISSION" />  然后聲明使用了此權(quán)限:1. <uses-permission android:name="scott.permission.MY_BROADCAST_PERMISSION" />  關(guān)于這部分如果有不明白的地方可以參考我之前

49、寫過的一篇文章:Android聲明和使用權(quán)限然后我們點(diǎn)擊發(fā)送按鈕發(fā)送一條廣播,控制臺(tái)打印如下:我們看到接收是按照順序的,第一個(gè)和第二個(gè)都在結(jié)果集中加入了自己的標(biāo)記,并且向優(yōu)先級低的接收者傳遞下去。既然是順序傳遞,試著終止這種傳遞,看一看效果如何,我們修改FirstReceiver的代碼,在onReceive的最后一行添加以下代碼:1. abortBroadcast();  然后再次運(yùn)行程序,控制臺(tái)打印如下:此次,只有第一個(gè)接收者執(zhí)行了,其它兩個(gè)都沒能執(zhí)行,因?yàn)閺V播被第一個(gè)接收者終止了。上面就是BroadcastReceiver的介紹,下面我將會(huì)舉幾個(gè)常見的例子加深一下大家對

50、廣播的理解和應(yīng)用:1.開機(jī)啟動(dòng)服務(wù)我們經(jīng)常會(huì)有這樣的應(yīng)用場合,比如消息推送服務(wù),需要實(shí)現(xiàn)開機(jī)啟動(dòng)的功能。要實(shí)現(xiàn)這個(gè)功能,我們就可以訂閱系統(tǒng)“啟動(dòng)完成”這條廣播,接收到這條廣播后我們就可以啟動(dòng)自己的服務(wù)了。我們來看一下BootCompleteReceiver和MsgPushService的具體實(shí)現(xiàn):1. package com.scott.receiver;  2.   3. import android.content.BroadcastReceiver;  4. import android.conte

51、nt.Context;  5. import android.content.Intent;  6. import android.util.Log;  7.   8. public class BootCompleteReceiver extends BroadcastReceiver   9.       10.     p

52、rivate static final String TAG = "BootCompleteReceiver"  11.       12.     Override  13.     public void onReceive(Context context, Intent intent

53、)   14.         Intent service = new Intent(context, MsgPushService.class);  15.         context.startService(service);  16.       

54、;  Log.i(TAG, "Boot Complete. Starting MsgPushService.");  17.       18.   19.   1. package com.scott.receiver;  2.   3. import android.app.Service;  4. import&

55、#160;android.content.Intent;  5. import android.os.IBinder;  6. import android.util.Log;  7.   8. public class MsgPushService extends Service   9.   10.     private static fin

56、al String TAG = "MsgPushService"  11.       12.     Override  13.     public void onCreate()   14.         super.on

57、Create();  15.         Log.i(TAG, "onCreate called.");  16.       17.       18.     Override  19.     public&#

58、160;int onStartCommand(Intent intent, int flags, int startId)   20.         Log.i(TAG, "onStartCommand called.");  21.         return super.

59、onStartCommand(intent, flags, startId);  22.       23.   24.     Override  25.     public IBinder onBind(Intent arg0)   26.       

60、  return null;  27.       28.   然后我們需要在AndroidManifest.xml中配置相關(guān)信息:1. <!- 開機(jī)廣播接受者 ->  2. <receiver android:name=".BootCompleteReceiver">  3.     <intent-fil

61、ter>  4.         <!- 注冊開機(jī)廣播地址->  5.         <action android:name="ent.action.BOOT_COMPLETED"/>  6.        

62、60;<category android:name="ent.category.DEFAULT" />  7.     </intent-filter>  8. </receiver>  9. <!- 消息推送服務(wù) ->  10. <service android:name=".MsgPushService"/&

63、gt;  我們看到BootCompleteReceiver注冊了“ent.action.BOOT_COMPLETED”這個(gè)開機(jī)廣播地址,從安全角度考慮,系統(tǒng)要求必須聲明接收開機(jī)啟動(dòng)廣播的權(quán)限,于是我們再聲明使用下面的權(quán)限:1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />  經(jīng)過上面的幾個(gè)步驟之后,我們就完成了開機(jī)啟動(dòng)的功能,將應(yīng)用運(yùn)行在模擬器上,然后重啟模擬器,控制臺(tái)打印如

64、下:如果我們查看已運(yùn)行的服務(wù)就會(huì)發(fā)現(xiàn),MsgPushService已經(jīng)運(yùn)行起來了。2.網(wǎng)絡(luò)狀態(tài)變化在某些場合,比如用戶瀏覽網(wǎng)絡(luò)信息時(shí),網(wǎng)絡(luò)突然斷開,我們要及時(shí)地提醒用戶網(wǎng)絡(luò)已斷開。要實(shí)現(xiàn)這個(gè)功能,我們可以接收網(wǎng)絡(luò)狀態(tài)改變這樣一條廣播,當(dāng)由連接狀態(tài)變?yōu)閿嚅_狀態(tài)時(shí),系統(tǒng)就會(huì)發(fā)送一條廣播,我們接收到之后,再通過網(wǎng)絡(luò)的狀態(tài)做出相應(yīng)的操作。下面就來實(shí)現(xiàn)一下這個(gè)功能:1. package com.scott.receiver;  2.   3. import android.content.BroadcastReceiver; 

65、0;4. import android.content.Context;  5. import android.content.Intent;  6. import .ConnectivityManager;  7. import .NetworkInfo;  8. import android.util.Log;  9. import android.widget.Toast;  10.   1

66、1. public class NetworkStateReceiver extends BroadcastReceiver   12.       13.     private static final String TAG = "NetworkStateReceiver"  14.    &#

67、160;  15.     Override  16.     public void onReceive(Context context, Intent intent)   17.         Log.i(TAG, "network state changed."

68、);  18.         if (!isNetworkAvailable(context)   19.             Toast.makeText(context, "network disconnected!", 0).show();  20. 

69、60;         21.       22.       23.     /* 24.      * 網(wǎng)絡(luò)是否可用 25.      *  26.     

70、; * param context 27.      * return 28.      */  29.     public static boolean isNetworkAvailable(Context context)   30.      

71、0;  ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  31.         NetworkInfo info = mgr.getAllNetworkInfo();  32.     &

72、#160;   if (info != null)   33.             for (int i = 0; i < info.length; i+)   34.         &#

73、160;       if (infoi.getState() = NetworkInfo.State.CONNECTED)   35.                     return true;  36.   &

74、#160;               37.               38.           39.         r

75、eturn false;  40.       41.   42.   再注冊一下這個(gè)接收者的信息:1. <receiver android:name=".NetworkStateReceiver">  2.     <intent-filter>  3.       

76、60; <action android:name=".conn.CONNECTIVITY_CHANGE"/>  4.         <category android:name="ent.category.DEFAULT" />  5.     </intent-filter>  

77、;6. </receiver>  因?yàn)樵趇sNetworkAvailable方法中我們使用到了網(wǎng)絡(luò)狀態(tài)相關(guān)的API,所以需要聲明相關(guān)的權(quán)限才行,下面就是對應(yīng)的權(quán)限聲明:1. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  我們可以測試一下,比如關(guān)閉WiFi,看看有什么效果。3.電量變化如果我們閱讀軟件,可能是全屏閱讀,這個(gè)時(shí)候用戶就看不到剩余的電量,我們就可以為他們提供電量的信息。要想做到這一點(diǎn),我們需要接收一條電量變化的廣播,然后獲取百分比信息,這聽上去挺簡單的,我們就來實(shí)現(xiàn)以下:1. package com.scott.receiver;  2.   3. import android.content.BroadcastReceiver;  4. import android.content.Context;  5. im

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論