【问题标题】:Manifest-declared BroadcastReceiver not picking up explicit broadcast when app is not running当应用程序未运行时,清单声明的 BroadcastReceiver 未接收显式广播
【发布时间】:2018-12-03 09:16:47
【问题描述】:

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

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() 方法在调用时会写入一个日志条目。

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

我特意为 Intent 设置了一个包名,以避免从 Android 8 开始出现manifest-declared receivers no longer receiving implicit broadcasts 的问题。此外,我运行的是 Android 7,这两个应用程序都针对 API 23,因此 Android 8 中的任何限制在此设置中都不重要。

我遇到了comment,其作者建议某些风格的 Android 可能不会唤醒应用程序进行广播,这似乎是我在这里遇到的情况(运行 LineageOS 14.1)——尽管该评论不是很具体而且我还没有发现任何其他支持这一说法的东西。

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

【问题讨论】:

  • 而不是setPackage()try setComponent(),看看是否有帮助。请参阅this blog post 和底部的代码 sn-p。另外,请记住,问题可能出在WhateverReceiver 正在做的事情上(例如,如果您尝试启动服务,除非您使用startForegroundService() 并在启动时将服务设为前台,否则这将无法正常工作) .
  • @CommonsWare 确实,这可以解决问题。为什么不把这个作为答案?

标签: android android-broadcast android-broadcastreceiver


【解决方案1】:

为了明确的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 标准。显然在这种情况下,它没有。 ¯\_(ツ)_/¯

【讨论】:

  • 你知道为什么 setPackage() 在这里不起作用吗?
  • @JeganBabu:不,抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多