清单声明的BroadcastReceiver在应用未运行时未获取明确的广播 [英] Manifest-declared BroadcastReceiver not picking up explicit broadcast when app is not running

查看:170
本文介绍了清单声明的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风格可能无法唤醒广播应用程序,这似乎就是我在这里遇到的问题(运行LineageOS 14.1),尽管该评论不是很具体,我还没有找到其他支持这一点的东西.索赔.

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

解决方案

要明确显示Intent,我通常

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

I am trying to get two apps to communicate via broadcasts. The first app sends a broadcast using code like the following:

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);
    }

The receiving end registers a BroadcastReceiver in its manifest:

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

The onReceive() method writes a log entry when invoked.

When the receiving app is running (i.e. I’ve had its main activity on screen, then navigated away from it), it processes the broadcast. However, if the receiver app is not running (which I ensure by long-pressing Back, having activated "Long-press Back to kill app" in Developer Settings), it is not woken up by the broadcast.

I am deliberately setting a package name for the intent, to avoid issues with manifest-declared receivers no longer receiving implicit broadcasts from Android 8 onwards. Besides, I am running Android 7, with both apps targeting API 23, thus any restrictions in Android 8 should not matter in this setup anyway.

I’ve come across a comment whose author suggests that certain flavors of Android may not wake applications for broadcasts, which seems to be what I am experiencing here (running LineageOS 14.1)—though that comment isn’t very specific and I haven’t found anything else backing this claim.

Is this what is happening here? If so, how can I ensure the receiver app is woken up by the broadcast (at least if it is directed)? If not, what’s wrong here?

解决方案

To make an explicit Intent, I usually use setComponent(), as it is guaranteed to work (as much as anything is):

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);
    }

In some cases, setPackage() makes an Intent "explicit enough" to satisfy some Android criterion. Apparently in this case, it does not. ¯\_(ツ)_/¯

这篇关于清单声明的BroadcastReceiver在应用未运行时未获取明确的广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆