BroadcastReceiver廣播接聽器的初步認識,廣播優先級,中斷,權限,廣播暴露(3)
/**
* 按廣播類型分:
* 1.無序廣播,廣播接收器收到的廣播順序時隨機的,沒有順序可循
* 2.有序廣播(你懂的)
*/
從一個應用A中發送廣播給另一個應用B的代碼操作工程。
首先,在清單文件中聲明定義一個廣播權限,兩個應用的清單文件都要有
<permission
android:name="custom.permission"
android:protectionLevel="normal"
/>
<uses-permission android:name="custom.permission"
/>
應用A中設置的代碼邏輯如下:點擊Button按鈕方法發送一個廣播
sendBroadcast(1,2)裏面的兩個參數,第一個參數是意圖名稱,第二個人蔘數就是應用廣播訪問權限
public void
send(View view){
sendBroadcast(new
Intent("weihuan.weigongcheng"),"custom.permission");
}
在該方法執行後,B應用中所有設置爲該意圖名稱的廣播接收器都會接收到廣播消息。
效果如下Log.d的打印結果:
06-02 14:42:12.193 1957-1957/project.wgc.mybroadcastreceiver02 D/weihuan: onReceive2: null
06-0214:42:12.1931957-1957/project.wgc.mybroadcastreceiver02D/weihuan:onReceive5:resultData:null;resultCode:-1;nickname:null
06-0214:42:12.2091957-1957/project.wgc.mybroadcastreceiver02D/weihuan:onReceive4:resultData:null;resultCode:0;nickname:null
06-02 14:42:12.218 1957-1957/project.wgc.mybroadcastreceiver02 D/weihuan: onReceive3: 3
五個自定義廣播器的代碼如下:
public class MyReceiver1 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("weihuan", "MyReceiver1: ++++++++++++++++");
}
}
public class MyReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String username = intent.getStringExtra("username");
Log.d("weihuan", "onReceive2: "+username);
}
}
public class MyReceiver3 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("weihuan", "onReceive3: 3");
}
}
public class MyReceiver4 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData();
int resultCode = getResultCode();
//參數表示如果廣播發送者傳遞的bundle爲null,則系統自動創建新的Bundle
Bundle resultExtras = getResultExtras(true);
String nickname = resultExtras.getString("nickname");
Log.d("weihuan", "onReceive4: resultData:" + resultData + ";resultCode:" + resultCode + ";nickname:" + nickname);
//中斷廣播
abortBroadcast();
}
}
public class MyReceiver5 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData();
int resultCode = getResultCode();
//參數表示如果廣播發送者傳遞的bundle爲null,則系統自動創建新的Bundle
Bundle resultExtras = getResultExtras(true);
String nickname = resultExtras.getString("nickname");
Log.d("weihuan", "onReceive5: resultData:" + resultData + ";resultCode:" + resultCode + ";nickname:" + nickname);
setResultData("lisi");
setResultCode(28);
resultExtras.putString("nickname", "里斯");
setResultExtras(resultExtras);
}
}
在清單文件中靜態註冊四個廣播接收器,二號廣播接收器在代碼中動態註冊
<!--
android:exported="false"是否將廣播接收器暴露給第三方應用,上面應用A發送的廣播信息,一號廣播接收器就不會收到了
-->
<receiver android:name=".MyReceiver1"
android:exported="false">
<intent-filter>
<action android:name="weihuan.weigongcheng" />
</intent-filter>
</receiver>
<receiver android:name=".MyReceiver3">
<intent-filter android:priority="1">
<action android:name="weihuan.weigongcheng" />
</intent-filter>
</receiver>
<receiver android:name=".MyReceiver4">
<intent-filter android:priority="2">
<action android:name="weihuan.weigongcheng" />
</intent-filter>
</receiver>
<!--
android:priority="3" 表示廣播的優先級,優先級越高的廣播接收器越先收到廣播,最低優先級爲-999
-->
<receiver android:name=".MyReceiver5">
<intent-filter android:priority="3">
<action android:name="weihuan.weigongcheng" />
</intent-filter>
</receiver>
B應用中的主要代碼如下:
public class
MainActivity extends
AppCompatActivity {
private
MyReceiver2 receiver;
@Override
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver
= new
MyReceiver2();
IntentFilter intentFilter =
new IntentFilter();
intentFilter.addAction("weihuan.weigongcheng");
//"custom.permission“第三個參數表示要監聽的權限
registerReceiver(receiver,intentFilter,"custom.permission",null);
}
public void
send1(View view) {//發送無序廣播
Intent intent = new
Intent("weihuan.weigongcheng");
intent.putExtra("username",
"zhangsan");
sendBroadcast(intent);
}
@Override
protected void
onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
public void
send2(View view) {//發送有序廣播
// Intent intent = new Intent("android.android");
// intent.putExtra("age", 18);
// sendOrderedBroadcast(intent, null);
Bundle bundle =
new Bundle();
bundle.putString("nickname",
"張三");
sendOrderedBroadcast(new
Intent("weihuan.weigongcheng"), null, new
MyReceiver3(), null,
18,
"zhangsan",
bundle);
// sendOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData, initialExtras)
// receiverPermission 這是權限,一個接收器必須持以接收您的廣播。如果爲 null ,不經許可的要求。
// resultReceiver 您自己 BroadcastReceiver 來當作最後的廣播接收器。
// 調度自定義處理程序,用以安排 resultReceiver 回調 ; 如果爲 null 將語境中的主線程舉行。
// initialCode 一種結果代碼的初始值。通常爲 Activity.RESULT_OK 。這個值是 -1 ;爲其他 int 型 也可以,如 0,1,2 ;
// initialData 一種結果數據的初始值。通常情況下爲空 , 是 String 類型 ;
// initialExtras 一種結果額外的初始值。通常情況下爲空 , 是 Bundle;
}
}
點擊方法一send1發送無序廣播,效果如下2-5-4-3-1:
06-02 15:08:15.024 19631-19631/project.wgc.mybroadcastreceiver02 D/weihuan: onReceive2: zhangsan
06-0215:08:15.02519631-19631/project.wgc.mybroadcastreceiver02D/weihuan:onReceive5:resultData:null;resultCode:-1;nickname:null
06-0215:08:15.04019631-19631/project.wgc.mybroadcastreceiver02D/weihuan:onReceive4:resultData:null;resultCode:0;nickname:null
06-02 15:08:15.043 19631-19631/project.wgc.mybroadcastreceiver02 D/weihuan: onReceive3: 3
06-02 15:08:15.047 19631-19631/project.wgc.mybroadcastreceiver02 D/weihuan: MyReceiver1: ++++++
點擊方法二send2中,
sendOrderedBroadcast(new Intent("weihuan.weigongcheng"), null, null, null, 18, "zhangsan", bundle);
// sendOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData, initialExtras)
// receiverPermission 這是權限,一個接收器必須持以接收您的廣播。如果爲 null ,不經許可的要求。
// resultReceiver 您自己 BroadcastReceiver 來當作最後的廣播接收器。
// 調度自定義處理程序,用以安排 resultReceiver 回調 ; 如果爲 null 將語境中的主線程舉行。
// initialCode 一種結果代碼的初始值。通常爲 Activity.RESULT_OK 。這個值是 -1 ;爲其他 int 型 也可以,如 0,1,2 ;
// initialData 一種結果數據的初始值。通常情況下爲空 , 是 String 類型 ;
// initialExtras 一種結果額外的初始值。通常情況下爲空 , 是 Bundle;
第三個參數如果設置有receiver,則該方法發送的廣播信息最後結束的時候一定會在該receiver結束。下面是有與沒有的結果對比
1、設置有receiver:從優先級高到低:5-4-3-2-1-3(3是設置的receiver)
D/weihuan:onReceive5:resultData:zhangsan;resultCode:18;nickname:張三
D/weihuan: onReceive4: resultData:lisi;resultCode:28;nickname:里斯
D/weihuan: onReceive3: 3
D/weihuan: onReceive2: null
D/weihuan: MyReceiver1: +++
D/weihuan: onReceive3: 3
2、沒設置有receiver:從優先級高到低:5-4-3-2-1
D/weihuan: onReceive5: resultData:zhangsan;resultCode:18;nickname:張三
D/weihuan: onReceive4: resultData:lisi;resultCode:28;nickname:里斯
D/weihuan: onReceive3: 3
D/weihuan: onReceive2: null
D/weihuan: MyReceiver1: +++
在方法send2中時初始發送數據如下:
Bundle bundle = new Bundle();
bundle.putString("nickname", "張三");
sendOrderedBroadcast(new Intent("weihuan.weigongcheng"), null, new MyReceiver3(), null, 18, "zhangsan", bundle);
根據優先級大小,會從依次54321。
在監聽器5中更改了初始數據,所以監聽器4接收到更改後的數據
public class MyReceiver5 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData();
int resultCode = getResultCode();
//參數表示如果廣播發送者傳遞的bundle爲null,則系統自動創建新的Bundle
Bundle resultExtras = getResultExtras(true);
String nickname = resultExtras.getString("nickname");
Log.d("weihuan", "onReceive5: resultData:" + resultData + ";resultCode:" + resultCode + ";nickname:" + nickname);
setResultData("lisi");//重新設置結果數據爲lisi
setResultCode(28);//重新設置結果代碼爲28
resultExtras.putString("nickname", "里斯");//重新設置結果Bundle中的暱稱爲"里斯"
setResultExtras(resultExtras);
}
}
public class MyReceiver4 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData();
int resultCode = getResultCode();
//參數表示如果廣播發送者傳遞的bundle爲null,則系統自動創建新的Bundle
Bundle resultExtras = getResultExtras(true);
String nickname = resultExtras.getString("nickname");
Log.d("weihuan", "onReceive4: resultData:" + resultData + ";resultCode:" + resultCode + ";nickname:" + nickname);
//中斷廣播
// abortBroadcast();
}
}
監聽器4中的abortBroadcast();代表中斷廣播的意思,即執行後,廣播就會停止,不會再往下傳播。從5到4就完了。
監聽器5到4的log.d的結果顯示
D/weihuan:onReceive5:resultData:zhangsan;resultCode:18;nickname:張三
D/weihuan: onReceive4: resultData:lisi;resultCode:28;nickname:里斯