在应用未运行时,清单声明的BroadcastReceiver无法接收明确的广播

时间:2018-06-24 18:01:09

标签: android android-broadcast android-broadcastreceiver

我正在尝试让两个应用程序通过广播进行通信。第一个应用程序使用以下代码发送广播:

Intent outIntent = new Intent("org.example.WHATEVER");
PackageManager pm = this.getPackageManager();
List<ResolveInfo> receivers = pm.queryBroadcastReceivers(outIntent, 0);
if (receivers != null)
    for (ResolveInfo receiver : receivers) {
        Log.d("Sender", String.format("Polling %s", receiver.activityInfo.packageName));
        outIntent = new Intent("org.example.WHATEVER");
        outIntent.setPackage(receiver.activityInfo.packageName);
        sendBroadcast(outIntent);
    }

接收端在其清单中注册BroadcastReceiver

<receiver android:name="org.example.receiverapp.WhateverReceiver" >
    <intent-filter>
        <action android:name="org.example.WHATEVER" />
    </intent-filter>
</receiver>

onReceive()方法在被调用时会写一个日志条目。

正在运行接收应用程序(即,我的主要活动显示在屏幕上,然后离开它进行导航),它会处理广播。但是,如果接收器应用程序没有运行(我通过长按“后退”并在“开发人员设置”中激活了“长按后退以杀死应用程序”来确保),则广播不会将其唤醒。

我有意为此设置软件包名称,以避免从Android 8起manifest-declared receivers no longer receiving implicit broadcasts出现问题。此外,我正在运行Android 7,两个应用程序均以API 23为目标,因此无论如何,Android 8的任何限制在此设置中都无关紧要。

我遇到过一个comment的作者,他的作者暗示,某些Android风格可能无法唤醒广播应用程序,这似乎就是我在这里遇到的问题(运行LineageOS 14.1),尽管该评论并未非常具体,我还没有发现任何其他证据来支持这一主张。

这是这里发生的事情吗?如果是这样,如何确保广播唤醒了接收器应用程序(至少在定向的情况下)?如果没有,这是怎么了?

1 个答案:

答案 0 :(得分:4)

为了做出明确的Intent,我通常会use setComponent(),因为它可以保证正常工作(无论如何):

Intent outIntent = new Intent("org.example.WHATEVER");
PackageManager pm = this.getPackageManager();
List<ResolveInfo> receivers = pm.queryBroadcastReceivers(outIntent, 0);
if (receivers != null)
    for (ResolveInfo receiver : receivers) {
        Log.d("Sender", String.format("Polling %s/%s",
                receiver.activityInfo.applicationInfo.packageName,
                receiver.activityInfo.name));
        ComponentName cn = new ComponentName(
                receiver.activityInfo.applicationInfo.packageName,
                receiver.activityInfo.name);
        outIntent = new Intent("org.example.WHATEVER");
        outIntent.setComponent(cn);
        sendBroadcast(outIntent);
    }

在某些情况下,setPackage()使Intent足够“显式”以满足某些Android标准。显然,在这种情况下,事实并非如此。 ¯\_(ツ)_/¯