現(xiàn)在你已經(jīng)學(xué)會(huì)了通過廣播接收器來接受系統(tǒng)廣播,接下來我們就要學(xué)習(xí)一下如何在應(yīng)用程序中發(fā)送自定義廣播。前面已經(jīng)介紹過了,廣播主要分為兩種類型:標(biāo)準(zhǔn)廣播和有序廣播,在本節(jié)中我們就將通過實(shí)踐的方式來看一下這兩種廣播具體的區(qū)別。
5.3.1 ? 發(fā)送標(biāo)準(zhǔn)廣播
在發(fā)送廣播之前,我們還需要先定義一個(gè)廣播接收器來準(zhǔn)備接收此廣播才行,不然發(fā)出去也是白發(fā)。因此新建一個(gè)MyBroadCastReceiver,代碼如下所示:


可以看到,這里MyBroadCastReceiver接收一條值為

的廣播。接下來修改activity_main.xml中代碼,如下所示

可以看到,我們?cè)诎粹o的點(diǎn)擊事件里面加入了發(fā)送了自定義廣播的邏輯。首先構(gòu)建了一個(gè)Intent對(duì)象,并把要發(fā)送的廣播的值傳入,然后調(diào)用了sendBroadcast方法將廣播發(fā)送出去,這樣所有監(jiān)聽"com.example.broadcasttest.My_BRODCAST"這條廣播的廣播接收重新運(yùn)行一下程序,并點(diǎn)擊一下 Send Broadcast按鈕,效果如圖:
這樣我們就成功完成了自定義廣播的功能。另外,由于廣播是使用Intent進(jìn)行傳遞的,因此你還可以在Intent中攜帶一些數(shù)據(jù)傳遞給廣播接收器。?
5.3.2 發(fā)送有序廣播
? ? ? ? ? 廣播 一種可以跨進(jìn)程的通訊方式,這一點(diǎn)從前面接收廣播就可以看出來。因此我們應(yīng)用程序類發(fā)出的廣播,其他的應(yīng)用程序也是可以接收的。為了驗(yàn)證這一點(diǎn),我們需要新建一個(gè)BroadCastTest2項(xiàng)目,(注冊(cè)靜態(tài)的廣播接收器)。
將項(xiàng)目創(chuàng)建好之后,還需要在項(xiàng)目下定義一個(gè)廣播接收器,用于接收上一節(jié)中的自定義廣播。新建AnotherBroadCastReceiver,代碼如下所示:

這里仍然是在廣播接收器的onReceive()方法中彈出以一段文本信息。然后在配置文件中AndroidManifest.xml中隊(duì)這個(gè)廣播接收器進(jìn)行修改,代碼如下所示:

可以看到,在AnotherBroadCastReceiver同樣接收的是

這條廣播?,F(xiàn)在運(yùn)行BroadCastTest2項(xiàng)目將這個(gè)程序安裝在模擬器上,然后重新回到BroadCastTest項(xiàng)目的的主界面,并點(diǎn)擊一下send Broadcast按鈕,就會(huì)分別彈出兩次提示信息,如圖所示:
這樣就強(qiáng)力證明了,我們的應(yīng)用程序發(fā)出的廣播是可以被其他的應(yīng)用程序接收到的。回到BroadCastTest項(xiàng)目,然后修改MainActivity中的代碼,如下所示:
發(fā)送有序廣播:

? ? ? ? ? ? ? 可以看到,發(fā)送有序廣播只需要改動(dòng)一行代碼,即將sendBroadcast()方法改成 sendOrderedBroadcast()方法。sendOrderedBroadcast()方法接收兩個(gè)參數(shù),第一個(gè)參數(shù)仍然是Intent,第二個(gè)參數(shù)是權(quán)限相關(guān)的字符串,這里傳入null就行了?,F(xiàn)在重新運(yùn)行程序點(diǎn)擊Send Broadcast按鈕,你會(huì)發(fā)現(xiàn),兩個(gè)應(yīng)用程序仍然都可以接收這條廣播。
? ? ? ? ? ? ? 看上去好像和標(biāo)準(zhǔn)廣播沒有什么區(qū)別嘛,不過別忘了,這個(gè)時(shí)候的廣播接收器是有先后順序的,而且前面的廣播接收器還可以將廣播截?cái)?,以阻止其繼續(xù)傳播。
那么該如何設(shè)定廣播接收器的先后順序啦?當(dāng)然是在注冊(cè)的時(shí)候進(jìn)行設(shè)定的了,修改AndroidManifest.xml中的代碼,如下所示:

可以看到,我們通過android:priority屬性給廣播接收器設(shè)置了優(yōu)先級(jí),優(yōu)先級(jí)比較高的廣播接收器就可以優(yōu)先收到廣播。這里講MyBroadcastReceiver就可以選擇是否允許廣播繼續(xù)傳遞了。修改MyBroadcastReceiver中的代碼,如下所示:

? ? ? ? ? ? ? ?如果onReceive()方法中調(diào)用了abortBroadcast()方法,就表示將這條廣播截?cái)啵竺娴膹V播接收器將無法再接收到這條廣播?,F(xiàn)在重新運(yùn)行程序,并點(diǎn)擊一下Send BroadcastReceiver之后確實(shí)是終止傳遞了。
5.4使用本地廣播
? ? ? ? ? ? ? ?前面我們發(fā)送和接收的廣播全部屬于系統(tǒng)全局廣播,即發(fā)出的廣播可以被其他任何應(yīng)用程序接收到,并且我們也可以接收來自于其他任何應(yīng)用程序的廣播。這樣就很容易硬氣安全性的問題,比如說我們發(fā)送的一些攜帶關(guān)鍵性數(shù)據(jù)的廣播有可能被其他的應(yīng)用程序截獲,或者其他的程序不停的向我們的廣播接收器里發(fā)送各種垃圾廣播。
? ? ? ? ? ? ? 為了能夠簡單的解決廣播安全性問題,Android映入了一套本地廣播機(jī)制,使用這個(gè)機(jī)制發(fā)出的廣播只能夠在應(yīng)用程序內(nèi)部傳遞信息,并且廣播接收器也只能接收來自本應(yīng)用程序發(fā)出的廣播,這樣所有的安全性問題就都不存在了。
本地廣播的用法并不簡單,主要就是使用了一個(gè)LocalBroadcastManager來對(duì)廣播進(jìn)行管理,并提供了發(fā)送廣播接收器的方法。下面我們就可以通過具體的實(shí)力來嘗試一下它的用法。修改MainActivity中的代碼,如下所示:


有沒有覺得這些代碼很熟悉?沒錯(cuò),其實(shí)這基本上就是和我們前面所學(xué)的動(dòng)態(tài)注冊(cè)廣播接收器以及發(fā)送廣播的代碼是一樣的。只不過現(xiàn)在首先通過LocalBroadcastManager的getInstance()方法得到了它的一個(gè)勢(shì)力,然后再注冊(cè)廣播接收器的時(shí)候調(diào)用的是LocalBroadcastManager的

在發(fā)送發(fā)送廣播的時(shí)候調(diào)用

方法,僅此而已。這里我們?cè)侔窗粹o的點(diǎn)擊事件里面發(fā)出一條com.example.broadcasttest.My_BRODCAST廣播,然后在NetworkChangeReceiver里面接收這條廣播。重新運(yùn)行程序,并點(diǎn)擊Send BroadCast按鈕,效果如圖所示:
? ? ? ? ?可以看到NetworkChangeReceiver成功的接收了這條廣播,并通過Toast提示了出來。如果你還有興趣進(jìn)行實(shí)驗(yàn),可以嘗試在BroadCastTest2中也去接收android.net.conn.CONNECTIVITY_CHANGE這條廣播,答案是顯而易見的,肯定無法接收到,因?yàn)檫@條廣播只會(huì)在BroadCastTest程序內(nèi)傳播。
? ? ? ? ?另外還有一點(diǎn)需要說明,本地廣播是無法通過靜態(tài)注冊(cè)來接收的。其實(shí)這也完全可以理解,因?yàn)殪o態(tài)注冊(cè)主要就是為了讓程序在未啟動(dòng)的情況下也能接收廣播,而發(fā)送本地廣播時(shí),我們的程序肯定已經(jīng)啟動(dòng)了,因此也完全不需要使用靜態(tài)注冊(cè)的功能。
? ? ? ? 最后我們?cè)賮肀P點(diǎn)一下使用本地廣播的幾點(diǎn)優(yōu)勢(shì)吧。
1 ? ?可以明確的知道正在發(fā)送的廣播不會(huì)離開離開我們的程序,因此不必?fù)?dān)心機(jī)密文件泄露。
2 ? ?其他的程序無法將廣播發(fā)送到我們的程序內(nèi)部,因此不必?fù)?dān)心會(huì)有安全漏洞的隱患。
3 ? ?發(fā)送本地廣播比發(fā)送系統(tǒng)全局廣播將會(huì)更加高效。