最近遇到一個問題,在作培訓時,屢試不爽的廣播消息居然存在接收不到廣播的狀況。經瞭解後發現,Android O 已對隱式廣播添加限制。so,下面總結下 Android 中廣播相關。android
廣播註冊分爲靜態註冊和動態註冊,靜態註冊的廣播,能夠在程序沒被啓動時,接收到全局廣播消息。而動態註冊廣播,只有在程序啓動後接收廣播消息。git
定義好廣播消息後,在 AndroidManife.xml 中註冊便可,示例中,添加多個 Action。github
<receiver android:name="com.flueky.demo.DemoReceiver" android:permission="com.flueky.demo.permission.Demo_Receiver">
<intent-filter android:priority="999">
<action android:name="com.flueky.app.Demo_Receiver" />
</intent-filter>
<intent-filter>
<action android:name="com.flueky.demo.TEST_RECEIVER1" />
</intent-filter>
<intent-filter>
<action android:name="com.flueky.demo.TEST_RECEIVER2" />
</intent-filter>
</receiver>
複製代碼
動態註冊指在 Activity 或 Service 中註冊,並在 Activity 或 Service 銷燬時,須要註銷。安全
// 註冊廣播
registerReceiver(testReceiver, new IntentFilter("com.flueky.demo.TEST_RECEIVER1"));
// 註銷廣播
unregisterReceiver(testReceiver);
複製代碼
因爲動態註冊的廣播能夠經過定義內部類的方式實現,所以,動態 註冊的廣播能夠同宿主 Activity 或 Service 進行交互。app
應用發出廣播後,全部註冊了廣播 Action 接收到廣播的前後順序是未知的,則叫發送了無序廣播。this
Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
複製代碼
應用發出廣播後,全部註冊了廣播 Action 接收到廣播的前後順序是固定的,則叫發送了無序廣播。spa
Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendOrderedBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
複製代碼
<!--定義優先級-->
<intent-filter android:priority="999">
<action android:name="com.flueky.app.Demo_Receiver" />
</intent-filter>
複製代碼
有序廣播接收器中傳遞消息和終止廣播以下:code
//非有序廣播,不不作下面的操做
if (!isOrderedBroadcast())
return;
// 獲取前一個廣播傳遞的消息
Bundle bundle = getResultExtras(true);
String received = bundle.getString("received");
Log.d(TAG, "onReceive: 廣播發送 "+(received==null?"null":received));
// 將消息傳遞給下一個待接收的廣播。
bundle.putString("received","已被 send 接收");
setResultExtras(bundle);
// 終止廣播
abortBroadcast();
複製代碼
發送有序廣播和無序廣播後,設備中的其餘應用只須要註冊了接收廣播的 Action ,均可以接收到廣播消息。爲了只在本身應用中接收到廣播消息,Google 前後給出了兩種方案。其中一種是本地廣播,經過 v4 包提供了 LocalBroadcastManager 類,註冊、註銷和發送廣播。xml
// 註冊本地廣播
LocalBroadcastManager.getInstance(this).registerReceiver(testReceiver, new IntentFilter("com.flueky.demo.TEST_RECEIVER2"));
// 發送本地廣播
LocalBroadcastManager.getInstance(this).sendBr oadcast(new Intent("com.flueky.demo.TEST_RECEIVER2"));
// 註銷本地廣播
LocalBroadcastManager.getInstance(this).unregisterReceiver(testReceiver);
複製代碼
本地廣播只能經過動態註冊的方式,並且由 LocalBroadcastManager 註冊的廣播只能接收 LocalBroadcastManager 發送的廣播。get
在 Android 8.0 以上,使用全局廣播必須給廣播接收器添加上權限。發送廣播時須要使用廣播接收器申明的權限,並且,發送廣播的應用須要在 AndroidManifest.xml 中申明權限。
具體作法是:發送廣播的應用清單文件類容以下:
<!--定義一個權限-->
<permission android:name="com.flueky.demo.permission.Demo_Receiver" android:protectionLevel="signature" />
<!--申明使用這個權限-->
<uses-permission android:name="com.flueky.demo.permission.Demo_Receiver" />
複製代碼
代碼以下:
// 發送帶權限的廣播,有序廣播和無序廣播都行。
Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
複製代碼
接收廣播應用的清單文件以下:
<!--使用自定義的權限,包括下面註冊廣播時,使用的 permission 屬性。-->
<uses-permission android:name="com.flueky.demo.permission.Demo_Receiver" />
<receiver android:name="com.flueky.demo.DemoReceiver" android:permission="com.flueky.demo.permission.Demo_Receiver">
<intent-filter android:priority="1000">
<action android:name="com.flueky.app.Demo_Receiver" />
</intent-filter>
</receiver>
複製代碼
最後,發送廣播和接收廣播的應用必須使用同一個簽名文件。由於自定義權限的安全級別是 signature。
源碼地址。
以爲有用?那打賞一個唄。去打賞