According to the migration guide to Android O given by Google, most of the implicit broadcast intent should not be registered in the Manifest (minus a few exceptions found here) but explicit broadcast intents remain untouched.
We are looking to move any needed broadcast away from the manifest. But how do we recognise if a receiver is implicit? Is there a general rule?
Here is a sample of the broadcasts we register in the manifest. Should we look only at the "action" tag and see if it is whitelisted to keep it in the manifest?
<receiver android:name=".receiver.ImageBroadcastReceiver" android:enabled="true" > <intent-filter> <action android:name="android.hardware.action.NEW_PICTURE" /> <category android:name="android.intent.category.OPENABLE" /> <data android:mimeType="image/*" /> </intent-filter> </receiver> <receiver android:name=".receiver.InstallReferrerReceiver" android:exported="true"> <intent-filter> <action android:name="com.android.vending.INSTALL_REFERRER" /> </intent-filter> </receiver> <receiver android:name=".receiver.JoinEventReceiver" > <intent-filter> <action android:name="JOIN_ACTION" /> <action android:name="CANCEL_ACTION" /> <action android:name="DECLINE_ACTION" /> </intent-filter> </receiver>
For example, the "com.android.vending.INSTALL_REFERRER" intent is not whitelisted. Should we register it in an Activity? If so wouldn't it be never fired as when we register it the app is already installed? This is what confuses me when trying to understand if a broadcast receiver is implicit or explicit as I thought I only had to check that "action" tag.
An example for an implicit broadcast would be an action of an incoming SMS message. An explicit broadcast is one that is targeted specifically for your application on a component that is known in advance. This happens due to the target attribute that contains the application's package name or a component class name.
A Service receives intents that were sent specifically to your application, just like an Activity. A Broadcast Receiver receives intents that were broadcast system-wide to all apps installed on the device.
An IntentFilter specifies the types of intents to which an activity, service, or broadcast receiver can respond to by declaring the capabilities of a component. BroadcastReceiver does not allows an app to receive video streams from live media sources.
But how do we recognise if a receiver is implicit?
If the Intent
has a ComponentName
, the Intent
is explicit. Otherwise, it is implicit.
That ComponentName
can be obtained in one of a few ways, including:
It can be directly put on the Intent
(e.g., new Intent(this, TheReallyAwesomeReceiver.class
)
It can be directly put on the Intent
after using PackageManager
and queryIntentReceivers()
to find the right one based on action strings, etc.
It can be derived by the system from the action string, etc. plus the package defined via setPackage()
Should we look only at the "action" tag and see if it is whitelisted to keep it in the manifest?
No. You also need to think about the nature of the broadcast: is it going to any registered receiver, or only to a specific app?
For example, the "com.android.vending.INSTALL_REFERRER" intent is not whitelisted. Should we register it in an Activity?
No. That broadcast will only go to the app that was recently installed, and so it must be an explicit Intent
. The action string and such are there to help the system determine which of your registered receivers is the relevant one.
Contrast that with ACTION_PACKAGE_ADDED
. That is broadcast to any registered receiver; it is not going to just one specific app. Hence, that Intent
must be implicit (as otherwise it would have a ComponentName
identifying a specific receiver in a specific app). And, since ACTION_PACKAGE_ADDED
is not on the whitelist, the assumption should be that you cannot register for this broadcast in the manifest on Android 8.0+.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With