安卓8.0后,对静态广播进行了限制,必须指定包名和类名,才能发送广播给其它应用
新安卓系统广播特性
- 动态注册的接收器,必须在应用启动后通过代码注册,才能接收到广播。只要Action匹配,不管应用内还是应用外的广播都能收到
- 静态注册的接收器,除了Action匹配,还要PackageName和ClassName匹配,才能收到广播。也就是说,静态接收器收到的都是定点广播,而不是群发广播,在发送时就要通过PackageName和ClassName指定发给哪个接收器
- 通过静态注册广播接收器,监听操作系统或其它常见应用的群发广播,来达到应用自启动的时代,已经一去不复返了。除非你在另一个常驻应用内,一直给自己的应用发送定点广播
- 一般只有具备自己软件生态圈的巨型互联网公司才有这种可能,要不哪个常用的APP会刻意给你的APP发送广播呢,但是微信就可以给QQ或者自己的其它软件发送广播,因为一般的手机厂商在定制系统时,都会允许这些主流通讯应用在后台运行,而且一般人都会安装微信
- 静态接收器每次处理广播的都是一个新的BroadcastReceiver对象,因此不要在Receiver中保存数值
BroadcastReceiver 代码
public class KeepAliveReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//收到广播时,提示进程名称和进程ID
TipBox.tip(Applications.currentProcessName(), Applications.currentProcessId());
}
}
动态注册BroadcastReceiver
//动态注册广播接收器
//动态注册的广播接收器是可以收到外部广播的
KeepAliveReceiver receiver = new KeepAliveReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.android.demo.ABCDEFG");
registerReceiver(receiver, filter);
静态注册BroadcastReceiver
发送Broadcast
//发送广播
Intent intent = new Intent();
intent.setAction("com.android.demo.ABCDEFG");
sendBroadcast(intent);
//如果有许多应用,都静态注册了相同Action的广播,那么一个广播发出,就会导致一批应用启动,极其影响性能和续航
//所以安卓在8.0后开始规定,广播如果想要被静态接收器收到,必须在Intent中指定接收器的PackageName和ClassName
intent.setComponent(new ComponentName("com.android.architecture", "com.android.architecture.KeepAliveReceiver"));