BroadCast 專講

0. 前言

最近遇到一個問題,在作培訓時,屢試不爽的廣播消息居然存在接收不到廣播的狀況。經瞭解後發現,Android O 已對隱式廣播添加限制。so,下面總結下 Android 中廣播相關。android

1. 廣播註冊

廣播註冊分爲靜態註冊和動態註冊,靜態註冊的廣播,能夠在程序沒被啓動時,接收到全局廣播消息。而動態註冊廣播,只有在程序啓動後接收廣播消息。git

1.1 靜態註冊

定義好廣播消息後,在 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>
複製代碼

1.2 動態註冊

動態註冊指在 Activity 或 Service 中註冊,並在 Activity 或 Service 銷燬時,須要註銷。安全

// 註冊廣播
registerReceiver(testReceiver, new IntentFilter("com.flueky.demo.TEST_RECEIVER1"));
// 註銷廣播
unregisterReceiver(testReceiver);
複製代碼

因爲動態註冊的廣播能夠經過定義內部類的方式實現,所以,動態 註冊的廣播能夠同宿主 Activity 或 Service 進行交互。app

2. 廣播分類

2.1 無序廣播

應用發出廣播後,全部註冊了廣播 Action 接收到廣播的前後順序是未知的,則叫發送了無序廣播。this

Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
複製代碼

2.2 有序廣播

應用發出廣播後,全部註冊了廣播 Action 接收到廣播的前後順序是固定的,則叫發送了無序廣播。spa

Intent intent = new Intent("com.flueky.app.Demo_Receiver");
sendOrderedBroadcast(intent, "com.flueky.demo.permission.Demo_Receiver");
複製代碼
  1. 發送有序廣播須要指定一個權限。
  2. 優先級高的接收器,優先接收到消息,並能夠像優先級低的廣播傳遞數據,還能夠終止廣播繼續傳遞。
<!--定義優先級-->
<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();
複製代碼

2.3 本地廣播

發送有序廣播和無序廣播後,設備中的其餘應用只須要註冊了接收廣播的 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

3. 自定義權限

在 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

源碼地址

以爲有用?那打賞一個唄。去打賞

相關文章
相關標籤/搜索