区分清单中的隐式广播接收器与显式广播接收器
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?
如果 Intent
有 ComponentName
,则 Intent
是显式的。否则,它是隐式的。
ComponentName
可以通过以下几种方式之一获得,包括:
可以直接放在Intent
上(例如new Intent(this, TheReallyAwesomeReceiver.class
)
在使用PackageManager
和queryIntentReceivers()
后可以直接放在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+ 的清单中注册此广播。
根据 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?
如果 Intent
有 ComponentName
,则 Intent
是显式的。否则,它是隐式的。
ComponentName
可以通过以下几种方式之一获得,包括:
可以直接放在
Intent
上(例如new Intent(this, TheReallyAwesomeReceiver.class
)在使用
PackageManager
和queryIntentReceivers()
后可以直接放在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+ 的清单中注册此广播。