Background execution not allowed 广播无法接收问题的解决方法
出现此报错的原因是Android O中对隐式广播做了限制,请看源码如下:
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
829 final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
830 BroadcastRecord r;
...
1277 } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
1278 || (r.intent.getComponent() == null
1279 && r.intent.getPackage() == null
1280 && ((r.intent.getFlags()
1281 & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
1282 && !isSignaturePerm(r.requiredPermissions))) {
1283 mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
1284 component.getPackageName());
1285 Slog.w(TAG, "Background execution not allowed: receiving "
1286 + r.intent + " to "
1287 + component.flattenToShortString());
1288 skip = true;
1289 }
从代码中看,如下四个条件同时满足,则该广播不能被正常收到。
1.r.intent.getComponent() == null
2.r.intent.getPackage() == null
3.r.intent.getFlags() & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0
4.!isSignaturePerm(r.requiredPermissions)
解决办法:
1.因为这是静态广播注册才会有的问题,所以可以考虑将静态广播修改为动态广播。
2.这里的AndroidO并不是运行的Android版本,而是在AndroidManifest文件中定义的targetSdkVersion的值,因此我们第一种方法也是最稳定的方法即把项目文件中的targetSdkVersion设置为25及以下的版本号,重新编译即可,如果用的AndroidStudio,还要修改module/build.gradle中的该项配置.
AndroidManifest.xml
<uses-sdk android:minSdkVersion="13"/>
<uses-sdk android:targetSdkVersion="19"/>
3.如果发送广播的地方是自己可以控制的,那么可以将发送广播的地方加上需要的packageName。参考如下:
Intent playIntent = new Intent("com.android.wangwei.test");
playIntent.setPackage("com.example.wangwei.myapplication");
4.如果发送广播的地方是自己可以控制的,那么可以将发送广播的地方加上需要的flag。参考如下:
源码编译方式:
Intent playIntent = new Intent("com.android.wangwei.test");
playIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
或者:
Android Studio 方式:
Intent playIntent = new Intent("com.android.wangwei.test");
playIntent.addFlags(0x01000000); -> 使用需谨慎,万一谷歌修改了这个值的数字,就GG了。
此Flag的含义如下:
public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x02000000;
/**
* If set, the broadcast will always go to manifest receivers in background (cached
* or not running) apps, regardless of whether that would be done by default. By
* default they will only receive broadcasts if the broadcast has specified an
* explicit component or package name.
*
* NOTE: dumpstate uses this flag numerically, so when its value is changed
* the broadcast code there must also be changed to match.
*
* @hide
*/
public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;