在Android系統(tǒng)中,BroadcastReceiver的設(shè)計初衷就是從全局考慮的,可以方便應用程序和系統(tǒng)玉罐、應用程序之間屈嗤、應用程序內(nèi)的通信,所以對單個應用程序而言BroadcastReceiver是存在安全性問題的吊输,相應問題及解決如下:
- 當應用程序發(fā)送某個廣播時系統(tǒng)會將發(fā)送的Intent與系統(tǒng)中所有注冊的BroadcastReceiver的IntentFilter進行匹配饶号,若匹配成功則執(zhí)行相應的onReceive函數(shù)〖韭欤可以通過類似sendBroadcast(Intent, String)的接口在發(fā)送廣播時指定接收者必須具備的permission茫船±攀或通過Intent.setPackage設(shè)置廣播僅對某個程序有效。
- 當應用程序注冊了某個廣播時算谈,即便設(shè)置了IntentFilter還是會接收到來自其他應用程序的廣播進行匹配判斷涩禀。對于動態(tài)注冊的廣播可以通過類似registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)的接口指定發(fā)送者必須具備的permission,對于靜態(tài)注冊的廣播可以通過android:exported="false"屬性表示接收者對外部應用程序不可用然眼,即不接受來自外部的廣播艾船。
上面兩個問題其實都可以通過LocalBroadcastManager來解決:
Android v4 兼容包提供android.support.v4.content.LocalBroadcastManager工具類,幫助大家在自己的進程內(nèi)進行局部廣播發(fā)送與注冊高每,使用它比直接通過sendBroadcast(Intent)發(fā)送系統(tǒng)全局廣播有以下幾點好處屿岂。
- 因廣播數(shù)據(jù)在本應用范圍內(nèi)傳播,你不用擔心隱私數(shù)據(jù)泄露的問題鲸匿。
- 不用擔心別的應用偽造廣播爷怀,造成安全隱患。
- 相比在系統(tǒng)內(nèi)發(fā)送全局廣播晒骇,它更高效霉撵。
使用方法:
注冊
public class MainActivity extents Activity{
IntentFilter filter;
LocalBroadcastManager mLocalBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
... ...
filter = new IntentFilter();
filter.addAction(action);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);//獲得實例
mLocalBroadcastManager.registerReceiver(receiver, filter);//注冊監(jiān)聽
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(action)) {
//do someting
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
mLocalBroadcastManager.unregisterReceiver(receiver);//取消監(jiān)聽,注意unregisterReceiver()方法來 自LocalBroadcastManager;
}
}
發(fā)送廣播
public class SecondActivity extends Activity{
LocalBroadcastManager lbm;
@Override
protected void onCreate(Bundle savedInstanceState) {
... ...
lbm = LocalBroadcastManager.getInstance(this);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.action);
lbm.sendBroadcast(intent);
}
});
}
}