根据Google提供的Android O迁移指南,大多数隐式广播意图不应在Manifest中注册(减去少数例外情况here),但显式广播意图保持不变。
我们希望将所有需要的广播从清单中移除。但是我们如何识别接收器是否隐含?有一般规则吗?
以下是我们在清单中注册的广播示例。我们是否应该只查看“操作”标记并查看是否将其列入白名单以将其保留在清单中?
<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”意图未列入白名单。我们应该在活动中注册吗?如果是这样,它不会被解雇,因为当我们注册它时,应用程序已经安装?当我试图理解广播接收器是隐式的还是显式的时,这让我感到困惑,因为我认为我只需要检查“动作”标签。
答案 0 :(得分:30)
但我们如何识别接收器是否隐含?
如果Intent
有ComponentName
,则Intent
是明确的。否则,它是隐含的。
可以通过以下几种方式之一获得ComponentName
,包括:
可以直接放在Intent
上(例如,new Intent(this, TheReallyAwesomeReceiver.class
)
使用Intent
和PackageManager
根据操作字符串等找到正确的文件后,可以直接将其放在queryIntentReceivers()
上。
它可以由系统从动作字符串等中加上通过setPackage()
定义的包
我们是否应仅查看“操作”标记,看看它是否已列入白名单以将其保留在清单中?
没有。您还需要考虑广播的性质:它是任何注册的接收器,还是仅限于特定应用?
例如,“com.android.vending.INSTALL_REFERRER”意图未列入白名单。我们应该在活动中注册吗?
没有。该广播只会转到最近安装的应用,因此它必须是明确的Intent
。动作字符串等可以帮助系统确定哪些已注册的接收者是相关的接收者。
与ACTION_PACKAGE_ADDED
对比。这是向任何注册接收者广播的;它不会只是一个特定的应用程序。因此,Intent
必须是隐式的(否则它会有ComponentName
标识特定应用中的特定接收者)。并且,由于ACTION_PACKAGE_ADDED
不在白名单中,因此假设您无法在Android 8.0 +的清单中注册此广播。