web-dev-qa-db-fra.com

Différencier le récepteur de diffusion implicite et le récepteur de diffusion explicite dans le manifeste

Selon le guide de migration vers Android O donné par Google, la plupart des intentions de diffusion implicites ne devraient pas être enregistrées dans le manifeste (sauf quelques exceptions trouvées ici ) mais les intentions de diffusion explicites restent intactes.

Nous cherchons à éloigner toute diffusion nécessaire du manifeste. Mais comment reconnaître si un récepteur est implicite? Existe-t-il une règle générale?

Voici un échantillon des émissions que nous enregistrons dans le manifeste. Faut-il regarder uniquement la balise "action" et voir si elle est en liste blanche pour la conserver dans le manifeste?

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

Par exemple, l'intention "com.Android.vending.INSTALL_REFERRER" n'est pas sur liste blanche. Faut-il l'enregistrer dans une activité? Si tel n'est pas le cas, il ne sera jamais déclenché car lorsque nous l'enregistrons, l'application est déjà installée? C'est ce qui m'embrouille lorsque j'essaie de comprendre si un récepteur de diffusion est implicite ou explicite car je pensais que je n'avais qu'à vérifier cette balise "action".

19
Gauthier

Mais comment reconnaître si un récepteur est implicite?

Si le Intent a un ComponentName, le Intent est explicite. Sinon, c'est implicite.

Ce ComponentName peut être obtenu de plusieurs manières, notamment:

  • Il peut être directement placé sur le Intent (par exemple, new Intent(this, TheReallyAwesomeReceiver.class)

  • Il peut être placé directement sur Intent après avoir utilisé PackageManager et queryIntentReceivers() pour trouver la bonne en fonction des chaînes d'action, etc.

  • Il peut être dérivé par le système de la chaîne d'action, etc. plus le package défini via setPackage()

Faut-il regarder uniquement la balise "action" et voir si elle est en liste blanche pour la conserver dans le manifeste?

Non. Vous devez également réfléchir à la nature de la diffusion: va-t-elle tout récepteur enregistré, ou uniquement vers une application spécifique?

Par exemple, l'intention "com.Android.vending.INSTALL_REFERRER" n'est pas sur liste blanche. Faut-il l'enregistrer dans une activité?

Non. Cette diffusion ira uniquement à l'application qui a été récemment installée, et il doit donc s'agir d'un Intent explicite. La chaîne d'action et autres sont là pour aider le système à déterminer lequel de vos récepteurs enregistrés est le récepteur approprié.

Comparez cela avec ACTION_PACKAGE_ADDED. Qui est diffusé à tout récepteur enregistré; il ne va pas à une seule application spécifique. Par conséquent, ce Intent doit être implicite (sinon, il aurait un ComponentName identifiant un récepteur spécifique dans une application spécifique). Et, puisque ACTION_PACKAGE_ADDED N'est pas sur la liste blanche, l'hypothèse devrait être que vous ne pouvez pas vous inscrire à cette diffusion dans le manifeste sur Android 8.0+.

31
CommonsWare