在Android系統中,BroadcastReceiver的設計初衷就是從全域考慮的,可以方便應用程式和系統、應用程式之間、應用程式內的通訊,所以對單個應用程式而言BroadcastReceiver是存在安全性問題的,相應問題及解決如下:
1、當應用程式發送某個廣播時系統會將發送的Intent與系統中所有註冊的BroadcastReceiver的IntentFilter進行匹配,若匹配成功則執行相應的onReceive函數。可以通過類似sendBroadcast(Intent, String)的介面在發送廣播時指定接收者必須具備的permission。或通過Intent.setPackage設定廣播僅對某個程式有效。
2. 當應用程式註冊了某個廣播時,即便設定了IntentFilter還是會接收到來自其他應用程式的廣播進行匹配判斷。對於動態註冊的廣播可以通過類似registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)的介面指定寄件者必須具備的permission,對於靜態註冊的廣播可以通過android:exported="false"屬性工作表示接收者對外部應用程式不可用,即不接受來自外部的廣播。
上面兩個問題其實都可以通過LocalBroadcastManager來解決:
Android v4 相容包提供android.support.v4.content.LocalBroadcastManager工具類,協助大家在自己的進程內進行局部廣播發送與註冊,使用它比直接通過sendBroadcast(Intent)發送系統全域廣播有以下幾點好處。
1 因廣播資料在本應用範圍內傳播,你不用擔心隱私資料泄露的問題。
2 不用擔心別的應用偽造廣播,造成安全隱患。
3 相比在系統內發送全域廣播,它更高效。
其使用方法也和正常註冊廣播類似:
LocalBroadcastManager mLocalBroadcastManager; BroadcastReceiver mReceiver; IntentFilter filter = new IntentFilter(); filter.addAction("test"); <PRE class=java name="code"> mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("test")) { //Do Something } } }; </PRE> mLocalBroadcastManager.registerReceiver(mReceiver, filter);<PRE></PRE><P></P><PRE></PRE>當然,和正常廣播一樣,也要在對應的生命週期中反註冊掉:<P></P><P></P><P></P><PRE class=java name="code"> @Overrideprotected void onDestroy() { super.onDestroy(); mLocalBroadcastManager.unregisterReceiver(mReceiver);} </PRE><P></P><PRE></PRE><PRE></PRE><PRE></PRE>