現在你已經學會了通過廣播接收器來接受系統廣播,接下來我們就要學習一下如何在應用程序中發送自定義廣播。前面已經介紹過了,廣播主要分為兩種類型:標準廣播和有序廣播,在本節中我們就將通過實踐的方式來看一下這兩種廣播具體的區別。
5.3.1 ? 發送標準廣播
在發送廣播之前,我們還需要先定義一個廣播接收器來準備接收此廣播才行,不然發出去也是白發。因此新建一個MyBroadCastReceiver,代碼如下所示:
可以看到,這里MyBroadCastReceiver接收一條值為
的廣播。接下來修改activity_main.xml中代碼,如下所示
可以看到,我們在按鈕的點擊事件里面加入了發送了自定義廣播的邏輯。首先構建了一個Intent對象,并把要發送的廣播的值傳入,然后調用了sendBroadcast方法將廣播發送出去,這樣所有監聽"com.example.broadcasttest.My_BRODCAST"這條廣播的廣播接收重新運行一下程序,并點擊一下 Send Broadcast按鈕,效果如圖:
這樣我們就成功完成了自定義廣播的功能。另外,由于廣播是使用Intent進行傳遞的,因此你還可以在Intent中攜帶一些數據傳遞給廣播接收器。?
5.3.2 發送有序廣播
? ? ? ? ? 廣播 一種可以跨進程的通訊方式,這一點從前面接收廣播就可以看出來。因此我們應用程序類發出的廣播,其他的應用程序也是可以接收的。為了驗證這一點,我們需要新建一個BroadCastTest2項目,(注冊靜態的廣播接收器)。
將項目創建好之后,還需要在項目下定義一個廣播接收器,用于接收上一節中的自定義廣播。新建AnotherBroadCastReceiver,代碼如下所示:
這里仍然是在廣播接收器的onReceive()方法中彈出以一段文本信息。然后在配置文件中AndroidManifest.xml中隊這個廣播接收器進行修改,代碼如下所示:
可以看到,在AnotherBroadCastReceiver同樣接收的是
這條廣播?,F在運行BroadCastTest2項目將這個程序安裝在模擬器上,然后重新回到BroadCastTest項目的的主界面,并點擊一下send Broadcast按鈕,就會分別彈出兩次提示信息,如圖所示:
這樣就強力證明了,我們的應用程序發出的廣播是可以被其他的應用程序接收到的。回到BroadCastTest項目,然后修改MainActivity中的代碼,如下所示:
發送有序廣播:
? ? ? ? ? ? ? 可以看到,發送有序廣播只需要改動一行代碼,即將sendBroadcast()方法改成 sendOrderedBroadcast()方法。sendOrderedBroadcast()方法接收兩個參數,第一個參數仍然是Intent,第二個參數是權限相關的字符串,這里傳入null就行了?,F在重新運行程序點擊Send Broadcast按鈕,你會發現,兩個應用程序仍然都可以接收這條廣播。
? ? ? ? ? ? ? 看上去好像和標準廣播沒有什么區別嘛,不過別忘了,這個時候的廣播接收器是有先后順序的,而且前面的廣播接收器還可以將廣播截斷,以阻止其繼續傳播。
那么該如何設定廣播接收器的先后順序啦?當然是在注冊的時候進行設定的了,修改AndroidManifest.xml中的代碼,如下所示:
可以看到,我們通過android:priority屬性給廣播接收器設置了優先級,優先級比較高的廣播接收器就可以優先收到廣播。這里講MyBroadcastReceiver就可以選擇是否允許廣播繼續傳遞了。修改MyBroadcastReceiver中的代碼,如下所示:
? ? ? ? ? ? ? ?如果onReceive()方法中調用了abortBroadcast()方法,就表示將這條廣播截斷,后面的廣播接收器將無法再接收到這條廣播?,F在重新運行程序,并點擊一下Send BroadcastReceiver之后確實是終止傳遞了。
5.4使用本地廣播
? ? ? ? ? ? ? ?前面我們發送和接收的廣播全部屬于系統全局廣播,即發出的廣播可以被其他任何應用程序接收到,并且我們也可以接收來自于其他任何應用程序的廣播。這樣就很容易硬氣安全性的問題,比如說我們發送的一些攜帶關鍵性數據的廣播有可能被其他的應用程序截獲,或者其他的程序不停的向我們的廣播接收器里發送各種垃圾廣播。
? ? ? ? ? ? ? 為了能夠簡單的解決廣播安全性問題,Android映入了一套本地廣播機制,使用這個機制發出的廣播只能夠在應用程序內部傳遞信息,并且廣播接收器也只能接收來自本應用程序發出的廣播,這樣所有的安全性問題就都不存在了。
本地廣播的用法并不簡單,主要就是使用了一個LocalBroadcastManager來對廣播進行管理,并提供了發送廣播接收器的方法。下面我們就可以通過具體的實力來嘗試一下它的用法。修改MainActivity中的代碼,如下所示:
有沒有覺得這些代碼很熟悉?沒錯,其實這基本上就是和我們前面所學的動態注冊廣播接收器以及發送廣播的代碼是一樣的。只不過現在首先通過LocalBroadcastManager的getInstance()方法得到了它的一個勢力,然后再注冊廣播接收器的時候調用的是LocalBroadcastManager的
在發送發送廣播的時候調用
方法,僅此而已。這里我們再按按鈕的點擊事件里面發出一條com.example.broadcasttest.My_BRODCAST廣播,然后在NetworkChangeReceiver里面接收這條廣播。重新運行程序,并點擊Send BroadCast按鈕,效果如圖所示:
? ? ? ? ?可以看到NetworkChangeReceiver成功的接收了這條廣播,并通過Toast提示了出來。如果你還有興趣進行實驗,可以嘗試在BroadCastTest2中也去接收android.net.conn.CONNECTIVITY_CHANGE這條廣播,答案是顯而易見的,肯定無法接收到,因為這條廣播只會在BroadCastTest程序內傳播。
? ? ? ? ?另外還有一點需要說明,本地廣播是無法通過靜態注冊來接收的。其實這也完全可以理解,因為靜態注冊主要就是為了讓程序在未啟動的情況下也能接收廣播,而發送本地廣播時,我們的程序肯定已經啟動了,因此也完全不需要使用靜態注冊的功能。
? ? ? ? 最后我們再來盤點一下使用本地廣播的幾點優勢吧。
1 ? ?可以明確的知道正在發送的廣播不會離開離開我們的程序,因此不必擔心機密文件泄露。
2 ? ?其他的程序無法將廣播發送到我們的程序內部,因此不必擔心會有安全漏洞的隱患。
3 ? ?發送本地廣播比發送系統全局廣播將會更加高效。