12

I have registered following receiver which is not getting called in Android Oreo but works on lower version devices.

<receiver
     android:name=".common.receiver.ConsultReceiver"
     android:exported="false">
       <intent-filter>
            <action android:name="APP_STARTED" />
            <action android:name="APP_STARTED_FROM_ORGANIC" />
       </intent-filter>
</receiver>  

Any help would be appreciated?

Goku
  • 9,102
  • 8
  • 50
  • 81
Ragini
  • 765
  • 1
  • 11
  • 29

4 Answers4

11

In general, you cannot use an implicit Intent (e.g., one with just an action string) for a broadcast on Android 8.0+.

Your <receiver> is not exported. This suggests one of three things:

  1. You are using this with a PendingIntent, such as for a Notification. If so, get rid of the <intent-filter> and use an explicit Intent (new Intent(this, ConsultReceiver.class)) as part of creating your PendingIntent that points to this receiver.

  2. You are using this as part of some IPC between multiple app processes in your app. In that case, also use an explicit Intent.

  3. You are using this receiver purely within one process within your app. In that case, get rid of the <receiver> and use something else (LocalBroadcastManager, an event bus, RxJava, LiveData, etc.).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • But it is not implicit broadcast receiver – Ragini Dec 01 '17 at 12:28
  • 1
    @Ragini: A *receiver* is neither implicit nor explicit. An `Intent` is implicit or explicit. An explicit `Intent` identifies the Java class of the component; an implicit `Intent` does not. – CommonsWare Dec 01 '17 at 12:33
  • @CommonsWare for explicit intent , dont we need to `register` the receiver ?? (if we remove `` from manifest) – Santanu Sur Mar 10 '18 at 00:34
  • @SantanuSur: You need a `` element. It does not need an ``. – CommonsWare Mar 10 '18 at 00:35
  • just the `` in the manifest and `explicit intent` to call the receiver is enough ryt (in 8.0+) ?? And then for `push notification` if i want to launch an `explicit intent` to an actvity from that particular `receiver` wil also work in all versions of android ryt ?? (just to make my concept clear) @CommonsWare – Santanu Sur Mar 10 '18 at 00:40
  • 1
    @SantanuSur: I am not aware that FCM changes anything regarding how explicit `Intents` work, if that is what you are asking. Nothing changed with respect to starting activities in Android 8.x. – CommonsWare Mar 10 '18 at 00:54
  • Can we start an `explicit intent` to an activity directly from FCM ( `onMessageReceived` ) or do we need to broadcast it to a receiver and from the receiver we need to start the activity ...( indirectly ) OR `implicit intent directly to an activity` is still allowed in `8.x` ? ( from `onMessageReceived` ) – Santanu Sur Mar 10 '18 at 01:02
  • **Nothing changed with respect to starting activities in Android 8.x** got it thanks :) @CommonsWare ( just the receiver (call should be through explicit intent) is all that changed in `8.x` ) – Santanu Sur Mar 10 '18 at 01:16
  • 1
    @SantanuSur: correct. Note that starting an activity from a push message may not make the user happy, if that interrupts what they are doing. Consider raising a notification instead. – CommonsWare Mar 10 '18 at 01:41
  • Away from Android programming for a while, very late to the party and this happened :( I think I need to update some of my apps now. 1. As for the Implicit Intents, is the same true for something like Intent.ACTION_CALL too? 2. Will be static registration in AndroidManifest.xml still valid such as ? – Jenix Jun 08 '18 at 10:45
  • 1
    @Jenix: "As for the Implicit Intents, is the same true for something like Intent.ACTION_CALL too?" -- that is not used for broadcasts. "Will be static registration in AndroidManifest.xml still valid such as ?" -- only if the action is on [the whitelist](https://developer.android.com/guide/components/broadcast-exceptions.html). `android.intent.action.BOOT_COMPLETED` happens to be on the whitelist, but most actions are not. – CommonsWare Jun 08 '18 at 10:55
  • Oh, you said "you cannot use an implicit Intent (e.g., one with just an action string) for a *broadcast*", not an activity, I see! Now I know what to do. Thanks as always! :) – Jenix Jun 08 '18 at 11:09
6

If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for implicit broadcasts (broadcasts that do not target your app specifically), except for a few implicit broadcasts that are exempted from that restriction. In most cases, you can use scheduled jobs instead.

Nirmal Prajapat
  • 1,735
  • 1
  • 12
  • 23
3

In Android 8.0 and above, use the following code to check when some app is installed or uninstalled.

class MainActivity : AppCompatActivity() {

    private val receiver = YourBroadcastReceiverClass()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val filter = IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_ADDED)
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED)
        filter.addDataScheme("package")

        registerReceiver(receiver, filter)
    }

    override fun onDestory() {
        unregisterReceiver(receiver)
        super.onDestroy()
    }
}
Bugs Happen
  • 2,169
  • 4
  • 33
  • 59
2

Restrict the Intent to your package with setPackage.

artkoenig
  • 7,117
  • 2
  • 40
  • 61