BroadcastReceiver:廣播接收器,是一個專注於接收廣播通知信息,並做出對應處理的組件
1、應用程序可以擁有任意數量的廣播接收器以對所有它感興趣的通知信息予以響應。所有的接收器均繼承自BroadcastReceiver基類
2、廣播接收器沒有用戶界面。然而,它們可以啓動一個activity來響應它們收到的信息,或者用NotificationManager來通知用戶。通知可以用很多種方式來吸引用戶的注意力──閃動背燈、震動、播放聲音等等。一般來說是在狀態欄上放一個持久的圖標,用戶可以打開它並獲取消息
3、 Android中的廣播事件有兩種:
1)系統廣播事件,比如:ACTION_BOOT_COMPLETED(系統啓動完成後觸發),ACTION_TIME_CHANGED(系統時間改變時觸發),ACTION_BATTERY_LOW(電量低時觸發)等等2)我們自定義的廣播事件。
4、 廣播時間流程:
1)註冊廣播事件:註冊方式有兩種,
一種是靜態註冊,就是在AndroidManifest.xml文件中定義,註冊的廣播接收器必須要繼承BroadcastReceiver;靜態註冊的廣播,在程序結束時,仍會監聽符合的action
另一種是動態註冊,是在程序中使用Context.registerReceiver註冊,註冊的廣播接收器相當於一個匿名類。兩種方式都需要IntentFIlter。
2)發送廣播事件:通過Context.sendBroadcast來發送,由Intent來傳遞註冊時用到的Action。
3)接收廣播事件:當發送的廣播被接收器監聽到後,會調用它的onReceive()方法,並將包含消息的Intent對象傳給它。
注意:onReceive中代碼的執行時間不要超過5s,否則Android會彈出超時dialog。
5、廣播的生命週期
一個BroadcastReceiver 對象只有在被調用onReceive(Context, Intent)的纔有效的,
當從該函數返回後,該對象就無效的了,結束生命週期
下面通過代碼來實現廣播的註冊與發送、接收廣播
首先定義一個廣播接收器,創建一個類(MyReceiver)繼承BroadcastReceiver,實現其onReceive()方法
package com.BroadcastReceive.Archer; 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) { String action = intent.getAction(); if (action.equals("com.action.text")) { String msg = intent.getStringExtra("msg"); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } } }
一個廣播接收器可以接收來自四面八方發出的消息,所以可以在onReceive中通過intent.getAction判斷接收到的action來進行不同的操作,action爲系統的action或者我們自定義的action
然後需要註冊廣播了,有兩種註冊方式
靜態註冊:
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <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.action.text" /> //自定義的action,爲一個字符串 </intent-filter> </receiver> </application>
動態註冊:
private MyReceiver receiver = new MyReceiver(); //實例化廣播接收器
//動態註冊廣播 IntentFilter filter = new IntentFilter(); filter.addAction("com.action.text"); registerReceiver(receiver, filter);
在Activity或Service中註冊了一個BroadcastReceiver(動態註冊),
當這個Activity或Service被銷燬時如果沒有解除註冊,系統會報一個異常
我們可以在onStop()或者onDestroy()中進行解除註冊
@Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); }
發送廣播
Intent intent = new Intent(); intent.setAction("com.action.text");//爲廣播時間設置action intent.putExtra("msg", "接收廣播成功"); sendBroadcast(intent);
如果我們需要在發送廣播的同時,進行數據傳遞,可以通過intent來傳遞
無序廣播:
當發出廣播時,所有有註冊這個action的廣播接收器均會接收到這個廣播事件,且執行無先後順序,相互之間不會有影響;沒有註冊則不會接收到
有序廣播
當有多一個廣播接收器註冊這個action,且我們需要給他們設置接收的順序時,這時候就要用到有序廣播。
有序廣播比較特殊,它每次只發送到優先級較高的接收器那裏,然後由優先級高的接收器再傳播到優先級低的接收器那裏,優先級高的接收者有能力終止這個廣播。
先定義兩個廣播接收器,FirstReceiver爲優先級較高的接收器
public class FirstReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals("action")) { String msg = intent.getStringExtra("msg"); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); Bundle bundle = new Bundle(); bundle.putString("msg", "來自第一個廣播接收器的消息"); setResultExtras(bundle); //將一個Bundle對象設置爲結果集對象,傳遞到下一個接收者那裏 } } }
public class SecondReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals("action")) { String msg = getResultExtras(true).getString("msg"); //用getResultExtras獲取到經過處理的信息 Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } } }
註冊廣播時,需要給設置優先級 android:priority
<receiver android:name=".FirstReceiver"> <intent-filter android:priority="1000"> //這個屬性的範圍在-1000到1000,數值越大,優先級越高 <action android:name="com.action.text"/> </intent-filter> </receiver>
<receiver android:name=".FirstReceiver"> <intent-filter android:priority="1000"> //這個屬性的範圍在-1000到1000,數值越大,優先級越高 <action android:name="com.action.text"/> </intent-filter> </receiver>
<receiver android:name=".SecondReceiver"> <intent-filter android:priority="999"> <action android:name="com.action.text"/> </intent-filter> </receiver>
發送有序廣播
Intent intent = new Intent(); intent.setAction("com.action.text"); intent.putExtra("msg", "來自Activity的消息"); sendOrderedBroadcast(intent, "scott.permission.MYBROADCAST");
使用發送有序廣播,第二個參數爲自定義權限,爲null時,表示不需要聲明指定權限;不爲空,表示需要聲明指定權限,聲明如下權限 <permission android:protectionLevel="normal" android:name="scott.permission.MYBROADCAST" /> <uses-permission android:name="scott.permission.MYBROADCAST" />
這有發出廣播時,優先級最高的接收器就會先接收到廣播,然後再依次傳遞給優先級較低的接收器
如果我們需要在某一個接收器中終止廣播,可以在onReceiver()中調用如下代碼
abortBroadcast();