当应用程序未运行时,清单声明的 BroadcastReceiver 不会接收显式广播

2024-01-21

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

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>

The onReceive()方法在调用时写入日志条目。

当接收应用程序运行时(即我已将其主要活动显示在屏幕上,然后导航离开它),它会处理广播。但是,如果接收器应用程序未运行(我通过长按“返回”来确保这一点,并在开发人员设置中激活“长按返回杀死应用程序”),则它不会被广播唤醒。

我特意为意图设置了一个包名称,以避免出现问题清单声明的接收者不再接收隐式广播 https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers从 Android 8 开始。此外,我运行的是 Android 7,两个应用程序都针对 API 23,因此 Android 8 中的任何限制在此设置中都无关紧要。

我遇到过一个comment https://stackoverflow.com/questions/41766788/android-broadcastreceiver-not-triggering-when-app-is-not-running#comment80856311_41766788其作者建议某些 Android 风格可能不会唤醒应用程序进行广播,这似乎就是我在这里遇到的情况(运行 LineageOS 14.1)——尽管该评论不是很具体,而且我没有找到任何其他支持这一说法的内容。

这就是这里发生的事情吗?如果是这样,我如何确保接收器应用程序被广播唤醒(至少如果是定向的)?如果不是,这里出了什么问题?


为了明确Intent, 我通常use setComponent() https://developer.android.com/reference/android/content/Intent.html#setComponent(android.content.ComponentName),因为它保证可以工作(尽可能多):

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 标准。显然在这种情况下,事实并非如此。¯\_(ツ)_/¯

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当应用程序未运行时,清单声明的 BroadcastReceiver 不会接收显式广播 的相关文章

随机推荐