近期做项目的时候发现一个问题,我项目的app先前是跑在Android 6.0系统上的,静态广播能正常接收没问题,移植到Android 7.0 系统上广播也没问题也能正常接收,但是到了Android 8.0的系统之后,发现广播失效,怎么都接收不了广播,于是疯狂的找度娘,然后又看了一下Android 8.0的api,才知道原因:在Android 8.0系统上,为了提高电池续航时间,提高设备性能,系统会限制未在前台运行的应用的某些行为,如:
- 在后台运行的应用对后台服务的访问受到限制
应用无法使用其清单注册大部分隐式广播(即并非专门针对次应用的广播)
对广播的限制具体可以查看一下Android 8.0 API 介绍 https://developer.android.google.cn/about/versions/oreo/background
解决方法:
- 尽量使用动态广播代替静态广播
- 如果动态广播不能满足你的需求,必须要使用静态广播的话,那么就得在 Intent 中设置参数 Component参数,然后其他注册广播的步骤和原来在 Android 6.0 系统以下注册的方法一样。
举个栗子:
假如我有两个应用 A 和 B,A 应用的包名为:com.chen.testbroadcast1, 然后 B 应用的包名为:com.chen.testbroadcast2 ,现在要求是: A 应用向 B 应用发送广播,那么在 B 中 注册静态广播接收广播,接收的广播的路径是com.chen.testbroadcast2.broadcast.MyBroadCastReciver,接收的广播的 action 为 com.chen.broadcastrevicer
在应用 A 中发送广播:
Intent intent = new Intent("com.chen.broadcastrevicer");
intent.setComponent(new ComponentName("com.chen.testbroadcast2",
"com.chen.testbroadcast2.broadcast.MyBroadCastReciver"));
// 携带数据
intent.putExtra("test","我是来测 A 应用的Android 8.0 系统静态广播的测试数据");
// 启动发送广播
sendBroadcast(intent);
new ComponentName(参数1,参数2)详解:
参数1:广播接收器应用的包名,如此例子的 B 应用的包名:com.chen.testbroadcast2
参数2:广播接收器所在的完整路径,如此例子的 B 应用的广播接收器:com.chen.testbroadcast2.broadcast.MyBroadCastReciver
在应用 B 中接收 A 中发送过来的广播:
public class MyBroadCastReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("test");
Log.i("MyBroadCastReciver"," -- 接收到的消息 -- = "+message);
}
}
注意:intent.setComponent()方法一定是要在 sendBroadcast(intent) 之前调用。
至此,Android 8.0 的静态广播适配就完成了,亲测有效!求赞