Android複習之旅--BroadcastReceiver
在Android系統中,廣播(Broadcast)是一種運用在應用程式之間傳遞訊息的機制,廣播接收者(BroadcastReceiver)是用來過濾、接收並響應廣播的一類元件。通過廣播接收者可以監聽系統中的廣播資訊,在不同元件之間進行通訊。
收音機 –> 廣播接收者
電臺基站 –> 廣播
為了在某個事件發生後執行某些操作,所以應用中要定義一個廣播接收者,用來監聽某個事件。
廣播接收者
建立
建立一個類繼承BroadcastReceiver,讓後重寫onReceiver()方法onReceiver()方法執行在主執行緒,儘量不要再onReceiver()方法裡進行耗時的操作,因為該方法的執行時間不能超過10秒,否則會ANR。複雜的業務處理可以開啟一個服務或進入到另一個應用中。此方法執行完畢會自動銷燬
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceiver(Context context, Intent intent) { // TODO 事件發生後回撥此方法 } }
註冊
註冊廣播有兩種方式:常駐型廣播、非常駐型廣播
- 常駐型廣播
當應用程式關閉後,如果接收到其他應用程式發出的廣播,那麼該程式會自動重新啟動。需要在清單檔案中註冊
<receiver android:name="cn.rixin.myreceiver.MyReceiver"> <intent-filter> <!-- 簡訊接收 --> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
其他系統廣播事件參考百度文庫
- 非常駐型廣播
依賴於註冊廣播的元件的生命週期,如在Activity中註冊的廣播接收者在Activity銷燬後廣播也會隨之被移除。需要在程式碼中動態註冊,最好在Activity的onResume()和onPause()方法中進行註冊移除。
// 在onResume()方法中 MyBroadcastReceiver receiver = new MyBroadcastReceiver(); // 例項化過濾器並設定要過濾的廣播 String action = "android.provider.Telephony.SMS_RECEIVED"; IntentFilter intentFilter = new IntentFilter(action); // 註冊廣播 registerReceiver(receiver, intentFilter); // 在onPause()方法中 // 移除廣播 unregisterReceiver(receiver);
安全升級
4.0以下的版本,任何廣播接收者apk只要被裝到手機就立刻生效。不管應用程式程序是否執行。
4.0以及4.0以上的版本,要求應用程式必須有UI介面(Activity) 廣播接收者才能生效,如果使用者點選了強行停止,應用程式就完全關閉了,廣播接收者就失效了。如果使用者沒有點選過強行停止,即使應用程式程序不存在,也會自動的執行起來。
Android系統把許多常用的事件內建成了廣播機制,一旦事件產生了就會向全系統傳送一個廣播訊息。例如手機電量不足、有人給你傳送了簡訊、你向外撥打了電話、手機啟動完畢等等,系統都會發送一條相應的廣播。當然,也可以自定義廣播事件,主要用於應用內的通訊。
既然有廣播接收者,那自然是得有廣播才行的,因為得要知道廣播後才能建立相應的廣播接收者
廣播
系統廣播
Android系統中內建了許多的廣播事件,只要是涉及到手機的基本操作(如開機關機、網路狀態、拍照等)都會發送相應的廣播Intent intent = new Intent(); // 定義廣播的事件型別 intent.setAction("android.provider.Telephony.SMS_RECEIVED"); // 可攜帶資料 // intent.putExtra(key, value); // 傳送廣播 sendBroadcast(intent);
系統中的廣播事件 – 參考百度文庫,或者自己google搜尋
注意:有些廣播事件是需要註冊相應的許可權的自定義廣播
Intent intent = new Intent(); // 定義廣播的事件型別,字串(自定義,最好包名+字串) intent.setAction("com.rixin.sendBroadcast.FRX"); // 可攜帶資料 // intent.putExtra(key, value); // 傳送廣播 sendBroadcast(intent); // 傳送帶許可權的廣播(許可權自定義) sendBroadcast(intent, "com.rixin.sendBroadcast.KEY"); // 廣播接收者接收帶許可權的廣播時需要註冊許可權 <permission android:label="key" android:name="cn.rixin.sendBroadcast.KEY"></permission> <uses-permission android:name="cn.rixin.sendBroadcast.KEY"/>
廣播型別
Android系統中根據廣播的執行順序不同分為無序廣播和有序廣播。
- 無序廣播(非同步執行)
廣播發送的時候,接收者接收沒有先後順序,無序廣播不可以被攔截,不可以修改結果資料
中央人民廣播電臺:每晚7點整 –> sendBroadcast() —>所有人 有序廣播(同步執行)
廣播發送的時候,接收者是按照優先順序先後順序接收的,有序廣播可以被攔截,可以修改結果資料。如果指定了最終的接收者,最終的接收者一定會收到訊息。
中央向地方下達檔案:中央–>省–>市–>鄉–>農民Intent intent = new Intent(); intent.setAction("cn.rixin.zhongyang.bokuan"); // 傳送無許可權的有序廣播 sendOrderedBroadcast(intent, null); /** 傳送帶資料的有序廣播 * * intent:意圖 * receiverPermission:接收者的許可權 * resultReceiver:指定接收者(設定為null後無論什麼情況,都會接收到廣播資訊) * scheduler:訊息處理者(一般設定為null) * initialCode:初始碼 * initialData:資料 * initialExtras:intent裡面攜帶的額外引數 */ sendOrderedBroadcast(intent, "cn.rixin.orderbroadcast.shoukuan", null, null, 8, "撥款100萬元", null);
高優先順序的廣播接收者接收到廣播後可以對廣播進行一些操作,比如修改資料,終止廣播等。
setResultData(String data); // 修改有序廣播中的資料
abortBroadcast(); // 終止有序廣播有序廣播的優先順序是在intent-filter過濾器裡設定priority屬性,屬性值範圍在-1000~1000之間。如果兩個廣播接收者的優先順序相同,則先註冊的元件優先收到廣播;如果兩個應用監聽了同一個廣播事件並設定了相同的優先順序,則先安裝的應用優先接收到廣播。
<receiver android:name="cn.rixin.orderbroadcast.ShengReceiver"> <intent-filter android:priority="1000"> <action android:name="cn.rixin.zhongyang.bokuan"/> </intent-filter> </receiver>
最後,獻上一些常用的系統廣播事件吧
- 網路狀態
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"></action>
</intent-filter>
// 記得新增許可權
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
- 電量不足和電量充足
<intent-filter>
<action android:name="Intent.ACTION_BATTERY_LOW"></action>
<action android:name="Intent.ACTION_BATTERY_OKAY"></action>
</intent-filter>
- 插入耳機
<intent-filter>
<action android:name="Intent.ACTION_HEADSET_PLUG"></action>
</intent-filter>
// 記得新增許可權
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
- 開機,關機,重啟裝置
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
<action android:name="Intent.ACTION_SHUTDOWN"></action>
<action android:name="Intent.ACTION_REBOOT"></action>
</intent-filter>
// 記得新增許可權
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- 應用程式的安裝、解除安裝、替換
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"></action>
<action android:name="android.intent.action.PACKAGE_REMOVED"></action>
<action android:name="android.intent.action.PACKAGE_REPLACED"></action>
<!-- 資料的型別是一個apk的包 package:// -->
<data android:scheme="package"></data>
</intent-filter>
- SD卡的狀態(裝載,解除安裝,不存在)
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED"></action>
<action android:name="android.intent.action.MEDIA_REMOVED"></action>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"></action>
<!-- 資料的型別是一個檔案 -->
<data android:scheme="file"></data>
</intent-filter>
- 螢幕鎖屏和解鎖
這是一組特殊的廣播事件,接收這些廣播事件採用清單檔案Mainfast.xml配置是不生效的。需要在程式碼中動態註冊
ScreenOnReceiver receiver = new ScreenOnReceiver()
registerReceiver(receiver, new IntentFilter("android.intent.action.SCREEN_ON"));
ScreenOffReceiver receiver = new ScreenOffReceiver()
registerReceiver(receiver, new IntentFilter("android.intent.action.SCREEN_OFF"));
// 記得移除
unregisterReceiver(receiver);
如果這個廣播事件經常發生,一般就不允許採用清單檔案註冊,只能採用程式碼註冊的方式註冊才會生效。程式執行生效–程式停止執行失效。
希望對您有所幫助,歡迎指(吐)正(嘈)