Comment démarrerActivityForResult sur Android 11?

Oct 15 2020

Je charge des images dans mon application en utilisant startActivityForResult()en faisant quelque chose comme ceci:

val intentForLoadingImage = Intent(Intent.ACTION_GET_CONTENT)
intentForLoadingImage.type = "image/*"
if (intentForLoadingImage.resolveActivity(packageManager) != null) {
    startActivityForResult(intentForLoadingImage, IMAGE_REQUEST_CODE)
}

J'ai remplacé onActivityResult()ma logique de chargement de l'image dans un ImageView. Cela fonctionne sur toutes les versions d'Android (minSdkVersion de mon application est 21) mais il ne fait absolument rien sur Android 11. Parce que intentForLoadingImage.resolveActivity(packageManager)retourne null et l'activité de chargement d'images ne démarre pas.

Réponses

1 ianhanniballake Oct 15 2020 at 05:46

Selon la ACTION_GET_CONTENTdocumentation , la chaîne réelle est android.intent.action.GET_CONTENTet non android.media.action.GET_CONTENT celle que vous avez dans votre code. Par conséquent, la requête de visibilité de package correcte est

<queries>
    <intent>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:mimeType="image/*"/>
    </intent>
</queries>

Comme alternative, vous pouvez également attraper le ActivityNotFoundExceptionqui se produit dans les rares cas où le Storage Access Framework (qui est ce qui gère ACTION_GET_CONTENT) a été désactivé dans le cadre d'une ROM personnalisée. Cette approche ne nécessite aucune balise de visibilité du package:

val intentForLoadingImage = Intent(Intent.ACTION_GET_CONTENT)
intentForLoadingImage.type = "image/*"
try {
    startActivityForResult(intentForLoadingImage, IMAGE_REQUEST_CODE)
} catch (e: ActivityNotFoundException) {
}
1 AbhishekChoudhary Oct 18 2020 at 07:13

J'ai appris les mises à jour de confidentialité de la visibilité des packages sur Android 11 . Ce qui dit,

Android 11 change la manière dont les applications peuvent interroger et interagir avec d'autres applications que l'utilisateur a installées sur un appareil. À l'aide de l'élément, les applications peuvent définir l'ensemble des autres packages auxquels elles peuvent accéder. Cet élément aide à encourager le principe du moindre privilège en indiquant au système les autres packages à rendre visibles pour votre application, et il aide les magasins d'applications comme Google Play à évaluer la confidentialité et la sécurité que votre application offre aux utilisateurs.

Si votre application cible Android 11 ou une version ultérieure, vous devrez peut-être ajouter l'élément dans le fichier manifeste de votre application. Dans l'élément, vous pouvez spécifier des packages par nom, par signature d'intention ou par autorité de fournisseur.

J'ai donc ajouté les balises suivantes dans mon fichier manifeste:

<queries>
    <intent>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:mimeType="image/*"/>
    </intent>
</queries>

Et c'est tout!