区分清单中的隐式广播接收器与显式广播接收器

Differentiate implicit broadcast receiver vs explicit broadcast receiver in the manifest

根据 Google 给出的 Android O 的迁移指南,大多数隐式广播意图不应在清单中注册(减去发现的一些例外情况 here)但明确的广播意图保持不变。

我们正在寻求将任何需要的广播从清单中移走。但是我们如何识别接收者是否是隐式的呢?有一般规则吗?

这是我们在清单中注册的广播示例。我们是否应该只查看 "action" 标记并查看它是否已列入白名单以将其保留在清单中?

<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>

例如,"com.android.vending.INSTALL_REFERRER" 意图未列入白名单。我们应该在 Activity 中注册它吗?如果是这样,它不会因为我们注册它时就永远不会被解雇,应用程序已经安装了吗?当我试图了解广播接收器是隐式还是显式时,这让我感到困惑,因为我认为我只需要检查 "action" 标签。

But how do we recognise if a receiver is implicit?

如果 IntentComponentName,则 Intent 是显式的。否则,它是隐式的。

ComponentName 可以通过以下几种方式之一获得,包括:

  • 可以直接放在Intent上(例如new Intent(this, TheReallyAwesomeReceiver.class

  • 在使用PackageManagerqueryIntentReceivers()后可以直接放在Intent上根据action strings等找到合适的

  • 可以由系统根据action字符串等加上setPackage()

  • 定义的包导出

Should we look only at the "action" tag and see if it is whitelisted to keep it in the manifest?

没有。您还需要考虑广播的性质:它是发送给 任何 注册的接收者,还是只发送给特定的应用程序?

For example, the "com.android.vending.INSTALL_REFERRER" intent is not whitelisted. Should we register it in an Activity?

没有。该广播只会转到最近安装的应用程序,因此它必须是显式 Intent。操作字符串等可帮助系统确定您注册的哪个接收器是相关的。

ACTION_PACKAGE_ADDED 对比。广播给任何已注册的接收者;它不会只是一个特定的应用程序。因此,Intent 必须是隐式的(否则它将有一个 ComponentName 来标识特定应用程序中的特定接收者)。而且,由于 ACTION_PACKAGE_ADDED 不在白名单中,因此假设您无法在 Android 8.0+ 的清单中注册此广播。