Android 廣播(讓其他應用無法接收)
android 廣播實現讓其他應用無法接受的廣播有兩種方法:
- 本地廣播
為廣播新增許可權
本地廣播
本地廣播:
只在程式內部進行傳遞的廣播,傳送和接收都只在本程式有效。
示例程式碼:
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
//本地廣播資料型別例項。
private LocalBroadcastManager localBroadcastManager;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//獲取本地廣播例項。
localBroadcastManager=LocalBroadcastManager.getInstance(this );
Button button=(Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.example.tangyi.receiver5.LOCAL_BROADCAST");
//傳送本地廣播。
localBroadcastManager.sendBroadcast(intent);
}
});
//新建intentFilter並給其action標籤賦值。
intentFilter=new IntentFilter();
intentFilter.addAction("com.example.tangyi.receiver5.LOCAL_BROADCAST");
//建立廣播接收器例項,並註冊。將其接收器與action標籤進行繫結。
localReceiver=new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
}
@Override
public void onDestroy(){//在onDestroy()方法中取消註冊。
super.onDestroy();
//取消註冊呼叫的是unregisterReceiver()方法,並傳入接收器例項。
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
Toast.makeText(context,"這是本地廣播接收器",Toast.LENGTH_SHORT).show();
}
}
}
**本地廣播是無法通過靜態註冊來實現的。
因為靜態註冊是為了讓程式未啟動也能接收廣播。本地廣播是在本程式內進行
傳遞,肯定是已經啟動了,因此也完全不需要靜態註冊。**
給廣播新增許可權
在Android應用開發中,有時會遇到以下兩種情況,
一些敏感的廣播並不想讓第三方的應用收到 ;
要限制自己的Receiver接收某廣播來源,避免被惡意的同樣的ACTION的廣播所幹擾。
在這些場景下就需要用到廣播的許可權限制:
第一種場景: 誰有權收我的廣播?
在這種情況下,可以在自己應用發廣播時新增引數宣告Receiver所需的許可權。
首先,在Androidmanifest.xml中定義新的許可權RECV_XXX(自定義的許可權都需要先宣告),例如:
<permission android:name = "com.android.permission.RECV.XXX"/>
然後,在Sender app傳送廣播時將此許可權作為引數傳入,如下:
sendBroadcast("com.andoird.XXX_ACTION", "com.android.permission.RECV_XXX");
這樣做之後就使得只有具有permission許可權的Receiver才能接收此廣播要接收該廣播,在Receiver應用的AndroidManifest.xml中要新增對應的RECV_XXX許可權。
例如:
<users-permission android:name = "com.android.permission.RECV.XXX"/>
第二種場景: 誰有權給我發廣播?
在這種情況下,需要在Receiver app的 tag中宣告一下Sender app應該具有的許可權。
首先同上,在AndroidManifest.xml中定義新的許可權SEND_XXX,例如:
<permission android:name = "com.android.permission.SEND.XXX"/>
然後,在Receiver app的Androidmanifest.xml中的tag裡新增許可權SEND_XXX的宣告,如下:
<receiver android:name=".XXXReceiver"
android:permission="com.android.permission.SEND_XXX">
<intent-filter>
<action android:name="com.android.XXX_ACTION" />
</intent-filter>
</receiver>
這樣一來,該Receiver便只能接收來自具有該send_permission許可權的應用發出的廣播。
要傳送這種廣播,需要在Sender app的AndroidManifest.xml中也宣告使用該許可權即可,如下:
<users-permission android:name = "com.android.permission.SEND.XXX"/>
動態註冊廣播新增許可權
第一步:自己定義許可權,並且使用自定義許可權
<uses-permission android:name="com.cn.customview.permissions.MY_BROADCAST" />
<permission
android:name="com.cn.customview.permissions.MY_BROADCAST"
android:protectionLevel="signature" >
</permission>
給這個應用程式定義了一個permissions並且uses-permission申明使用,這是這個應用就有了這個許可權,並且應用內部的註冊的動態廣播也擁有了這個許可權。
第二步:定義註冊廣播
private static final String BROADCAST_PERMISSION_DISC = "com.cn.customview.permissions.MY_BROADCAST";
private static final String BROADCAST_ACTION_DISC = "com.cn.customview.permissions.my_broadcast";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.broadcast_permissions_activity);
ButterKnife.bind(this);
// 註冊廣播接收
BroadcastReceiver receiveBroadCast = new ReceiveBroadCast();
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_ACTION_DISC); // 只有持有相同的action的接受者才能接收此廣播
registerReceiver(receiveBroadCast, filter,BROADCAST_PERMISSION_DISC,null);
}
public class ReceiveBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(BroadcastPermissionsActivity.this,
"receive broadcast", 0).show();
}
}
註冊一個廣播,並且申明,這個廣播需要BROADCAST_PERMISSION_DISC許可權才能收到訊息。但是我們應用程式已經註冊了這個許可權。所以是有這個許可權的。
第三步: 傳送廣播
@OnClick(R.id.btn_send_broadcast)
public void sendBroadcastWithPermissions() {
Intent intent = new Intent(); //Itent就是我們要傳送的內容
intent.putExtra("data", "this is data from broadcast "+Calendar.getInstance().get(Calendar.SECOND));
intent.setAction(BROADCAST_ACTION_DISC); //設定你這個廣播的action,只有和這個action一樣的接受者才能接受者才能接收廣播
sendBroadcast(intent,BROADCAST_PERMISSION_DISC); //傳送廣播
}
代表接收訊息的廣播需要BROADCAST_PERMISSION_DISC許可權,其實跟上一種方式的定義效果一樣。
至此,安全檢查工具報錯消除。
注意:
1.registerReceiver(receiveBroadCast, filter,BROADCAST_PERMISSION_DISC,null);如果改為registerReceiver(receiveBroadCast, filter); 照樣能夠收到第三步傳送的訊息,因為我們在xml裡面已經申請了BROADCAST_PERMISSION_DISC許可權,所以sendBroadcast(intent,BROADCAST_PERMISSION_DISC);傳送廣播我們依然能收到。
2.sendBroadcast(intent,BROADCAST_PERMISSION_DISC); 改為sendBroadcast(intent);也同樣能收到這個訊息。因為第一個的意思是收到這個訊息的廣播監聽器必須有BROADCAST_PERMISSION_DISC許可權,如果第二個引數去掉,則說明廣播監聽器不需要任何許可權就能收到這個訊息。