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(自定义的权限都需要先声明),例如:
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权限。
例如:
name = "com.android.permission.RECV.XXX"/>
第二种场景: 谁有权给我发广播?
在这种情况下,需要在Receiver app的 tag中声明一下Sender app应该具有的权限。
首先同上,在AndroidManifest.xml中定义新的权限SEND_XXX,例如:
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中也声明使用该权限即可,如下:
name = "com.android.permission.SEND.XXX"/>
动态注册广播添加权限
第一步:自己定义权限,并且使用自定义权限
给这个应用程序定义了一个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权限,如果第二个参数去掉,则说明广播监听器不需要任何权限就能收到这个消息。