Accorder un accès limité aux photos et aux vidéos

Android 14 introduit l'accès aux photos sélectionnées, qui permet aux utilisateurs d'autoriser des applications à accéder à des images et des vidéos spécifiques de leur bibliothèque, plutôt que d'accorder l'accès à tous les contenus multimédias d'un type donné.

Cette modification n'est activée que si votre application cible Android 14 (niveau d'API 34) ou version ultérieure. Si vous n'utilisez pas encore le sélecteur de photos, nous vous recommandons de le mettre en œuvre dans votre application pour offrir une expérience cohérente de sélection d'images et de vidéos, tout en améliorant la confidentialité des utilisateurs sans avoir à demander d'autorisations de stockage.

Si vous gérez votre propre sélecteur de galerie à l'aide d'autorisations de stockage et que vous devez garder un contrôle total sur votre implémentation, adaptez votre implémentation pour utiliser la nouvelle autorisation READ_MEDIA_VISUAL_USER_SELECTED. Si votre application n'utilise pas la nouvelle autorisation, le système l'exécute en mode de compatibilité.

SDK cible READ_MEDIA_VISUAL_USER_SELECTED déclaré Accès aux photos sélectionnées activé Comportement de l'expérience utilisateur
SDK 33 Non Non N/A
Oui Oui Contrôlées par l'application
SDK 34 Non Oui Contrôlées par le système (compat comportement)
Oui Oui Contrôlées par l'application

La création de votre propre sélecteur de galerie nécessite un développement et une maintenance poussés. Votre application doit demander des autorisations de stockage pour obtenir le consentement explicite de l'utilisateur. Les utilisateurs peuvent refuser ces requêtes ou, si votre application s'exécute sur un appareil équipé d'Android 14 et qu'elle cible Android 14 (niveau d'API 34) ou version ultérieure, limiter l'accès au contenu multimédia sélectionné. L'image suivante montre un exemple de demande d'autorisations et de sélection de contenus multimédias à l'aide des nouvelles options.

L'extension .
Figure 1. La nouvelle boîte de dialogue permet à l'utilisateur de sélectionner les photos et vidéos spécifiques qu'il souhaite mettre à la disposition de votre application, en plus des options habituelles permettant d'accorder ou de refuser l'accès complet.

Cette section illustre l'approche recommandée pour créer votre propre sélecteur de galerie à l'aide de MediaStore. Si vous disposez déjà d'un sélecteur de galerie pour votre application et que vous devez garder le contrôle total, vous pouvez utiliser ces exemples pour adapter votre implémentation. Si vous ne mettez pas à jour votre implémentation pour gérer l'accès aux photos sélectionnées, le système exécute votre application en mode de compatibilité.

Demander des autorisations

Commencez par demander les autorisations de stockage appropriées dans le fichier manifeste Android, en fonction de la version de l'OS:

<!-- Devices running Android 12L (API level 32) or lower  -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

<!-- Devices running Android 13 (API level 33) or higher -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

<!-- To handle the reselection within the app on devices running Android 14
     or higher if your app targets Android 14 (API level 34) or higher.  -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />

Demandez ensuite les autorisations d'exécution appropriées, également en fonction de la version du système d'exploitation:

// Register ActivityResult handler
val requestPermissions = registerForActivityResult(RequestMultiplePermissions()) { results ->
    // Handle permission requests results
    // See the permission example in the Android platform samples: https://github.com/android/platform-samples
}

// Permission request logic
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO))
} else {
    requestPermissions.launch(arrayOf(READ_EXTERNAL_STORAGE))
}

Certaines applis n'ont pas besoin d'autorisations

À partir d'Android 10 (niveau d'API 29), les applications n'ont plus besoin d'autorisations de stockage pour ajouter des fichiers à l'espace de stockage partagé. Cela signifie que les applications peuvent ajouter des images à la galerie, enregistrer des vidéos et les enregistrer sur un espace de stockage partagé, ou télécharger des factures au format PDF sans avoir à demander des autorisations de stockage. Si votre application n'ajoute que des fichiers à l'espace de stockage partagé et n'interroge pas les images ni les vidéos, vous devez cesser de demander des autorisations de stockage et définir une maxSdkVersion sur l'API 28 dans votre AndroidManifest.xml:

<!-- No permission is needed to add files to shared storage on Android 10 (API level 29) or higher  -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

Gérer la resélection des contenus multimédias

Avec la fonctionnalité Accès aux photos sélectionnées dans Android 14, votre application doit adopter la nouvelle autorisation READ_MEDIA_VISUAL_USER_SELECTED pour contrôler la resélection des contenus multimédias et mettre à jour l'interface de votre application pour permettre aux utilisateurs d'autoriser votre application à accéder à un autre ensemble d'images et de vidéos. L'image suivante montre un exemple de demande d'autorisations et de nouvelle sélection de contenus multimédias:

L&#39;extension .
Figure 2. La nouvelle boîte de dialogue permet également à l'utilisateur de sélectionner à nouveau les photos et vidéos qu'il souhaite mettre à la disposition de votre application.

À l'ouverture de la boîte de dialogue de sélection, des photos, des vidéos ou les deux s'affichent en fonction des autorisations demandées. Par exemple, si vous demandez l'autorisation READ_MEDIA_VIDEO sans l'autorisation READ_MEDIA_IMAGES, seules les vidéos apparaissent dans l'interface utilisateur pour que les utilisateurs puissent sélectionner des fichiers.

// Allow the user to select only videos
requestPermissions.launch(arrayOf(READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))

Vous pouvez vérifier si votre application dispose d'un accès complet, partiel ou refusé à la bibliothèque photo de l'appareil, et mettre à jour votre interface en conséquence. Demandez ces autorisations lorsque l'application a besoin d'accéder à l'espace de stockage, et non au démarrage. N'oubliez pas que l'autorisation peut être modifiée entre les rappels de cycle de vie de l'application onStart et onResume, car l'utilisateur peut modifier l'accès dans les paramètres sans fermer votre application.

if (
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
    (
        ContextCompat.checkSelfPermission(context, READ_MEDIA_IMAGES) == PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(context, READ_MEDIA_VIDEO) == PERMISSION_GRANTED
    )
) {
    // Full access on Android 13 (API level 33) or higher
} else if (
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
    ContextCompat.checkSelfPermission(context, READ_MEDIA_VISUAL_USER_SELECTED) == PERMISSION_GRANTED
) {
    // Partial access on Android 14 (API level 34) or higher
}  else if (ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
    // Full access up to Android 12 (API level 32)
} else {
    // Access denied
}

Interroger la bibliothèque de l'appareil

Après avoir vérifié que vous disposez des autorisations de stockage appropriées, vous pouvez interagir avec MediaStore pour interroger la bibliothèque de l'appareil (la même approche fonctionne, que l'accès accordé soit partiel ou complet):

data class Media(
    val uri: Uri,
    val name: String,
    val size: Long,
    val mimeType: String,
)

// Run the querying logic in a coroutine outside of the main thread to keep the app responsive.
// Keep in mind that this code snippet is querying only images of the shared storage.
suspend fun getImages(contentResolver: ContentResolver): List<Media> = withContext(Dispatchers.IO) {
    val projection = arrayOf(
        Images.Media._ID,
        Images.Media.DISPLAY_NAME,
        Images.Media.SIZE,
        Images.Media.MIME_TYPE,
    )

    val collectionUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        // Query all the device storage volumes instead of the primary only
        Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
    } else {
        Images.Media.EXTERNAL_CONTENT_URI
    }

    val images = mutableListOf<Media>()

    contentResolver.query(
        collectionUri,
        projection,
        null,
        null,
        "${Images.Media.DATE_ADDED} DESC"
    )?.use { cursor ->
        val idColumn = cursor.getColumnIndexOrThrow(Images.Media._ID)
        val displayNameColumn = cursor.getColumnIndexOrThrow(Images.Media.DISPLAY_NAME)
        val sizeColumn = cursor.getColumnIndexOrThrow(Images.Media.SIZE)
        val mimeTypeColumn = cursor.getColumnIndexOrThrow(Images.Media.MIME_TYPE)

        while (cursor.moveToNext()) {
            val uri = ContentUris.withAppendedId(collectionUri, cursor.getLong(idColumn))
            val name = cursor.getString(displayNameColumn)
            val size = cursor.getLong(sizeColumn)
            val mimeType = cursor.getString(mimeTypeColumn)

            val image = Media(uri, name, size, mimeType)
            images.add(image)
        }
    }

    return@withContext images
}

Cet extrait de code est simplifié pour illustrer comment interagir avec MediaStore. Dans une application prête pour la production, utilisez la pagination avec, par exemple, la bibliothèque Paging pour garantir de bonnes performances.

L'accès aux photos et vidéos est préservé lorsque l'appareil est mis à niveau

Si votre application est installée sur un appareil qui met à niveau une version antérieure d'Android vers Android 14, le système conserve un accès complet aux photos et vidéos de l'utilisateur et accorde automatiquement certaines autorisations à votre application. Le comportement exact dépend de l'ensemble d'autorisations accordées à votre application avant la mise à niveau de l'appareil vers Android 14.

Autorisations d'Android 13

Prenons la situation suivante :

  1. Votre application est installée sur un appareil équipé d'Android 13.
  2. L'utilisateur a accordé les autorisations READ_MEDIA_IMAGES et READ_MEDIA_VIDEO à votre application.
  3. L'appareil passe ensuite à Android 14 et votre application n'est pas désinstallée.
  4. Votre application commence à cibler Android 14 (niveau d'API 34) ou version ultérieure.

Dans ce cas, votre application dispose d'un accès complet aux photos et vidéos de l'utilisateur. Le système conserve également les autorisations READ_MEDIA_IMAGES et READ_MEDIA_VIDEO accordées automatiquement à votre application.

Autorisations d'Android 12 et versions antérieures

Prenons la situation suivante :

  1. Votre application est installée sur un appareil équipé d'Android 13.
  2. L'utilisateur a accordé l'autorisation READ_EXTERNAL_STORAGE ou WRITE_EXTERNAL_STORAGE à votre application.
  3. L'appareil passe ensuite à Android 14 et votre application n'est pas désinstallée.
  4. Votre application commence à cibler Android 14 (niveau d'API 34) ou version ultérieure.

Dans ce cas, votre application dispose d'un accès complet aux photos et vidéos de l'utilisateur. Le système accorde également automatiquement l'autorisation READ_MEDIA_IMAGES et l'autorisation READ_MEDIA_VIDEO à votre application.

Bonnes pratiques

Cette section contient plusieurs bonnes pratiques concernant l'utilisation de l'autorisation READ_MEDIA_VISUAL_USER_SELECTED. Pour en savoir plus, consultez nos bonnes pratiques concernant les autorisations.

Ne pas stocker l'état d'autorisation de manière permanente

Ne stockez pas l'état d'autorisation de manière permanente, y compris SharedPreferences ou DataStore. L'état stocké peut ne pas être synchronisé avec l'état réel. L'état de l'autorisation peut changer après la réinitialisation de l'autorisation, l'hibernation de l'application, une modification des paramètres de votre application initiée par l'utilisateur ou lorsque celle-ci passe en arrière-plan. Vérifiez plutôt les autorisations de stockage à l'aide de ContextCompat.checkSelfPermission().

Ne pas supposer que vous avez un accès complet aux photos et vidéos

En raison des modifications introduites dans Android 14, il est possible que votre application ne dispose que d'un accès partiel à la bibliothèque de photos de l'appareil. Si l'application met en cache des données MediaStore lorsqu'elle est interrogée à l'aide de ContentResolver, une mise à jour du cache est peut-être nécessaire.

  • Interrogez toujours MediaStore à l'aide de ContentResolver, au lieu d'utiliser un cache stocké.
  • Gardez les résultats en mémoire lorsque votre application est au premier plan.
  • Actualisez les résultats lorsque votre application suit le cycle de vie de l'application onResume, car l'utilisateur peut passer d'un accès complet à un accès partiel via les paramètres d'autorisation.

Traiter l'accès à l'URI comme temporaire

Si l'utilisateur choisit Sélectionner des photos et des vidéos dans la boîte de dialogue des autorisations système, l'accès de votre application aux photos et vidéos sélectionnées expire au bout du compte. Votre application doit toujours gérer l'absence d'accès à des Uri, quelle que soit leur autorité.

Filtrer le type de média sélectionnable par autorisation

La boîte de dialogue de sélection est sensible au type d'autorisation demandé:

  • Si vous demandez uniquement READ_MEDIA_IMAGES, seules les images pouvant être sélectionnées s'affichent.
  • Si vous demandez uniquement READ_MEDIA_VIDEO, vous ne pourrez sélectionner que la vidéo.
  • Si vous demandez à la fois READ_MEDIA_IMAGES et READ_MEDIA_VIDEO, l'ensemble de la bibliothèque photo peut être sélectionné.

En fonction des cas d'utilisation de votre application, assurez-vous de demander les autorisations appropriées pour éviter une expérience utilisateur médiocre. Si une fonctionnalité ne s'attend à ce que des vidéos soient sélectionnées, veillez à ne demander que READ_MEDIA_VIDEO.

Demander des autorisations en une seule opération

Pour empêcher les utilisateurs de voir plusieurs boîtes de dialogue d'exécution du système, demandez les autorisations READ_MEDIA_VISUAL_USER_SELECTED, ACCESS_MEDIA_LOCATION et "lecture des médias" (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO ou les deux) lors d'une même opération.

Autoriser les utilisateurs à gérer leur sélection

Lorsque l'utilisateur choisit le mode d'accès partiel, votre application ne doit pas supposer que la bibliothèque de photos de l'appareil est vide, mais doit lui permettre d'accorder plus de fichiers.

L'utilisateur peut décider de passer d'un accès complet à un accès partiel via les paramètres d'autorisation, sans lui accorder l'accès à certains fichiers multimédias visuels.

Mode de compatibilité

Si vous gérez votre propre sélecteur de galerie à l'aide d'autorisations de stockage, mais que vous n'avez pas adapté votre application pour utiliser la nouvelle autorisation READ_MEDIA_VISUAL_USER_SELECTED, le système l'exécute en mode de compatibilité chaque fois que l'utilisateur doit sélectionner ou resélectionner le contenu multimédia.

Comportement lors de la sélection initiale du contenu multimédia

Lors de la sélection initiale, si un utilisateur choisit "Sélectionner des photos et des vidéos" (voir la figure 1), les autorisations READ_MEDIA_IMAGES et READ_MEDIA_VIDEO sont accordées pendant la session de l'application. Elles donnent une autorisation et un accès temporaires aux photos et vidéos sélectionnées par l'utilisateur. Lorsque votre application passe en arrière-plan ou que l'utilisateur la ferme activement, le système finit par refuser ces autorisations. Ce comportement est semblable à celui d'autres autorisations ponctuelles.

Comportement lors de la resélection des fichiers multimédias

Si votre application a besoin d'accéder à des photos et vidéos supplémentaires par la suite, vous devrez redemander manuellement l'autorisation READ_MEDIA_IMAGES ou READ_MEDIA_VIDEO. Le système suit le même flux que celui de la demande d'autorisation initiale, invitant les utilisateurs à sélectionner des photos et des vidéos (voir la figure 2).

Si votre application suit les bonnes pratiques en matière d'autorisations, cette modification ne devrait pas l'endommager. Cela est particulièrement vrai si votre application ne suppose pas que l'accès à l'URI est conservé, qu'elle stocke l'état des autorisations système ou actualise l'ensemble des images affichées une fois l'autorisation modifiée. Toutefois, ce comportement peut ne pas être idéal en fonction du cas d'utilisation de votre application. Pour offrir une expérience optimale à vos utilisateurs, nous vous recommandons d'implémenter le sélecteur de photos ou d'adapter le sélecteur de galerie de votre application afin de gérer ce comportement directement à l'aide de l'autorisation READ_MEDIA_VISUAL_USER_SELECTED.