Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manifest-declared BroadcastReceiver not picking up explicit broadcast when app is not running

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?

like image 276
user149408 Avatar asked Jun 24 '18 18:06

user149408


People also ask

Does broadcast receiver work in background?

A broadcast receiver will always get notified of a broadcast, regardless of the status of your application. It doesn't matter if your application is currently running, in the background or not running at all.

Which method will be called when intent broadcast shall be received by BroadcastReceiver?

The onReceiver() method is first called on the registered Broadcast Receivers when any event occurs. The intent object is passed with all the additional data. A Context object is also available and is used to start an activity or service using context.

How do I know if my broadcast receiver is registered?

A simple solution to this problem is to call the registerReceiver() in your Custom Application Class. This will ensure that your Broadcast receiver will be called only one in your entire Application lifecycle.


1 Answers

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. ¯\_(ツ)_/¯

like image 152
CommonsWare Avatar answered Nov 02 '22 11:11

CommonsWare