AndroidWay大前端-BFEAndroid

Android O 广播限制

2018-07-29  本文已影响478人  最忆是深秋

背景

如何确定一个action是否不支持静态注册?

    /**
     * You <em>cannot</em> receive this through components declared in
     * manifests, only by explicitly registering for it with
     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
     * Context.registerReceiver()}.
     */
    public static final String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
    public static final String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON";
    public static final String ACTION_TIME_TICK = "android.intent.action.TIME_TICK";
    public static final String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
    public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";

其他的 Action 不确定的可以在源码下查找发送该 Action 对应广播的地方,看 Intent 有没有带上Intent.FLAG_RECEIVER_REGISTERED_ONLY这个flag,也就是声明了这个 Action 只允许动态注册的 receiver 接收。

    /**
     * If set, when sending a broadcast only registered receivers will be
     * called -- no BroadcastReceiver components will be launched.
     */
    public static final int FLAG_RECEIVER_REGISTERED_ONLY = 0x40000000;

Android O(8.0)上对隐式广播的限制

    Intent intent = new Intent();
    intent.setAction("com.broadcast.test.action");
    sendBroadcast(intent);

而B中只需要注册一个 监听了 "com.broadcast.test.action"的广播即可,无论静态注册还是动态注册。
而在Android O的机器上,这样操作B无论如何都是收不到消息的。
07-27 15:58:57.653: W/BroadcastQueue(4268): Background execution not allowed: receiving Intent { act=com.broadcast.test.action flg=0x4000010 (has extras) } to com.broadcast.test.demo/.MyReceiver
当然这也同时取决于 B 应用的 targetVersion , 经过试验,只有当 B 的 targetVersion 是 26 (Android 8.0)时才会有问题。所以这种情况是出现在 targetVersion 在26及以上的APP 运行在 Android 8.0及以上版本的机器上时,在接收隐式intent时会出现问题

  1. 接收方APP targetVersion改成低于 26 的,就直接没有这个问题了
  2. 系统需要明确知道你到底是想发送给谁?用以下几种方式都可以,我都实操过
Intent intent = new Intent();
方法1:
intent.setAction("com.broadcast.test.action");
intent.setPackage("com.broadcast.test.demo");
方法2:
intent.setClassName("com.broadcast.test.demo", "com.broadcast.test.demo.MyReceiver");
方法3:
intent.setComponent(new ComponentName("com.broadcast.test.demo", "com.broadcast.test.demo.MyReceiver"));
getApplicationContext().sendBroadcast(intent);
,
上一篇下一篇

猜你喜欢

热点阅读