安卓允許用戶發(fā)送自定義廣播(broadcast),滿足接收條件的接收器(receiver)就可以接受自定義廣播。
發(fā)送自定義廣播
自定義廣播分為標(biāo)準(zhǔn)(無序)自定義廣播以及有序自定義廣播:
sendBroadcast(Intent intent); //發(fā)送標(biāo)準(zhǔn)自定義廣播
sendOrderedBroadcast(Intent, null); //發(fā)送有序自定義廣播
標(biāo)準(zhǔn)自定義廣播是任何滿足條件的接收器都可以接受。
有序自定義廣播的第二個參數(shù)是接受權(quán)限,一般為null。有序廣播接收器可以設(shè)置接收優(yōu)先級priority,優(yōu)先級高的先收到廣播,并且可以設(shè)置截斷廣播,這樣之后的接收器就無法接受廣播。
接受自定義廣播
接受自定義廣播一般使用靜態(tài)接受,即在AndroidManifest.xml中注冊接收器,這樣應(yīng)用即使未運(yùn)行,也可以響應(yīng)廣播:
<manifest>
......
<application>
......
<receiver android:name=".MyBroadcast(接收器類)">
<intent-filter android:priority="100(優(yōu)先級)">
<action android:name="MY_BROADCAST(自定義的廣播)" />
</intent-filter>
</receiver>
......
</application>
</manifest>
示例
我們新建2個工程:BroadcastTest1和BroadcastTest2。BoardcastTest1的主活動中添加一個按鈕發(fā)送自定義的廣播"Example.MY_Broadcast",然后兩個工程中都添加接收器用來接收這個廣播,接收后彈出toast通知。項目1的toast要比項目2的先提示。
先來寫項目1發(fā)送廣播,發(fā)送廣播要利用Intent類的實(shí)例,如下:
//BroadcastTest1.MainActivity: 項目1的主活動發(fā)送廣播
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
... ...
Button button =(Button)findViewById(R.id.button_broadcast);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("Example.MY_BROADCAST");
sendOrderedBroadcast(intent, null);
}
});
... ...
}
}
第一個項目的接收器類,繼承BroadcastReceiver并重寫其中的onReceive()方法,這個方法就是接收器接收到廣播后要執(zhí)行的,注意的是不要寫太多內(nèi)容,如果onReceive()方法執(zhí)行時間過長會報錯:
//BroadcastTest1.MyBroadcastReceiver:項目1的接收器類
public class MyBoardcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "BroadcastTest1:Example.MY_BROADCAST", Toast.LENGTH_LONG).show;
}
}
之后要在項目1的主配置文件中注冊接收器,并設(shè)置優(yōu)先級為100:
<!--BraodcastTest1.AndroidManifest.xml-->
<manifest ......>
<application ......>
......
<receiver android:name=".MyBroadcastReceiver">
<intent-filter android:priority="100">
<action android:name="Example.MY_BROADCAST" />
<intent-filter>
</receicer>
......
</application>
</manifest>
接下來寫項目2的接收器,基本上與項目1相同,不過我們不設(shè)置優(yōu)先級,這樣一定會先提示項目1的toast。如下:
//BroadcastTest2.MyBroadcastReceiver:項目2的接收器類
public class MyBoardcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "BroadcastTest2:Example.MY_BROADCAST", Toast.LENGTH_LONG).show;
}
}
<!--BraodcastTest2.AndroidManifest.xml-->
<manifest ......>
<application ......>
......
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="Example.MY_BROADCAST" />
<intent-filter>
</receicer>
......
</application>
</manifest>
編譯下兩個工程測試吧,項目中其他的部分請自行完善。另外,一些非原生安卓ROM實(shí)現(xiàn)靜態(tài)接受廣播需要給應(yīng)用“自動運(yùn)行”權(quán)限。
關(guān)于截斷廣播
截斷廣播在接收器類中使用abortBroadcast()方法,我們修改項目1的接收器類,加上這個方法:
//BroadcastTest1.MyBroadcastReceiver:項目1的接收器類
public class MyBoardcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "BroadcastTest1:Example.MY_BROADCAST", Toast.LENGTH_LONG).show;
abortBroadcast();
}
}
再次編譯項目1測試,這次只有項目1的toast通知,沒有項目2的toast通知。