转载请注明出处:http://blog.csdn.net/qq_28305251/article/details/70255169
最近进行软件测试的时候,发现针对华为EMUI5.0(Android 7.0)机型,发送全局广播,会出现如下错误。
针对这个问题,进行了相关分析。
sendBroadcast
首先是一个很简单的广播接收器,接受广播时打印通知
public class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("broadcast receiver on receive");
}
}
然后是通过sendBroadcast发送广播
Intent clickIntent = new Intent(MenuActivity.this, NotificationReceiver.class);
clickIntent.setAction("this.is.a.test");
sendBroadcast(clickIntent);
该测试中行为被设为this.is.a.test
下面分别针对动态及静态两种方式给出代码及结果截图
动态注册
简单的动态注册及反注册
NotificationReceiver notificationReceiver=new NotificationReceiver();
IntentFilter intentFilter=new IntentFilter("this.is.a.test");
registerReceiver(notificationReceiver,intentFilter);
unregisterReceiver(notificationReceiver);
出现广播拦截,且不会出现打印通知
静态注册
简单的静态注册
<receiver android:name=".mvp.presenter.broadcastreceiver.NotificationReceiver">
<intent-filter>
<action android:name="this.is.a.test" />
</intent-filter>
</receiver>
出现广播拦截,但出现打印通知
分析
首先看广播拦截的日志,可以看出很明显是权限相关。
接着我观察了系统整体日志,发现有很多相关拦截。如下
很明显,应该是华为系统针对源码修改了一部分,拦截了部分广播机制。
这个时候我注意到了,静态注册时,系统管家中自启动项中出现了我们的App。
原来是华为在针对系统广播时,进行了限制,防止自启动或连锁启动。动态广播会被华为的系统管家禁止,静态广播虽然会限制,但不影响广播接受。
解决方案
本应用目的实际为应用内广播,即本地广播。
贴出官方文档所说
Note: To register for local broadcasts,
call LocalBroadcastManager.registerReceiver(BroadcastReceiver, IntentFilter) instead.
使用LocalBroadcastManager.getInstance().registerReceiver及
LocalBroadcastManager.getInstance().sendBroadcast来代替。
结果如下
成功接受。
PendingIntent
事实上,我的应用并不是简单的发送本地广播,而是通过通知点击事件,即通过PendingIntent发送广播。然而通知和APP并不在一个进程中,使用本地广播并不能解决,这个时候怎么办。
由于系统并没有彻底拦截静态注册的广播接收器,只是不允许自启动,所以可以通过静态注册的方式接受通知的PendingIntent点击发送广播事件。