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'accorder à des applications l'accès à des images et vidéos spécifiques de sa bibliothèque, au lieu d'accorder d'accéder à tous les supports d'un type donné.

Cette modification n'est activée que si votre appli cible Android 14 (niveau d'API 34) ou plus élevée. Si vous n'utilisez pas encore le sélecteur de photos, nous vous recommandons de l'implémenter dans votre application afin de proposer une expérience cohérente pour la sélection d'images et de vidéos qui améliore également la confidentialité des utilisateurs sans avoir à demander d'espace de stockage autorisations.

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

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ôle par l'application
SDK 34 Non Oui Contrôlées par le système (comportement de compatibilité)
Oui Oui Contrôle par l'application

La création de votre propre sélecteur de galerie nécessite un développement et une maintenance intensifs. et votre application doit demander des autorisations d'accès à l'espace 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 avec Android 14 et votre application ciblent Android 14 (niveau d'API 34) ou version ultérieure, limite l'accès aux fichiers multimédias sélectionnés. L'image suivante montre un exemple de requête les autorisations et en sélectionnant les médias à l'aide des nouvelles options.

<ph type="x-smartling-placeholder">
</ph> L&#39;extension .
Figure 1. La nouvelle boîte de dialogue permet à l'utilisateur de sélectionner les photos et vidéos qu'ils souhaitent mettre à la disposition de votre application, en plus aux options habituelles pour accorder un accès complet ou refuser tout accès.

Cette section présente l'approche recommandée pour créer votre propre galerie sélecteur à l'aide de MediaStore. Si vous gérez déjà un sélecteur de galerie pour votre application et que vous avez besoin d'en garder le contrôle, vous pouvez utiliser ces exemples pour adapter la mise en œuvre. Si vous ne mettez pas à jour votre implémentation pour gérer les sélections Accès à Photos : le système exécute votre application en mode de compatibilité.

Demander des autorisations

Tout d'abord, demandez 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" />

Ensuite, demandez les autorisations d'exécution appropriées, également en fonction de la version de l'OS:

// 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 applis n'ont plus besoin d'autorisations de stockage pour pouvoir être ajoutées vers un espace de stockage partagé. Cela signifie que les applications peuvent ajouter des images à la galerie, enregistrez des vidéos et enregistrez-les sur un espace de stockage partagé, ou téléchargez des factures PDF sans sans avoir à demander des autorisations de stockage. Si votre application n'ajoute des fichiers qu'aux fichiers partagés et n'interroge pas les images ni les vidéos, vous devez cesser de demander de l'espace de stockage les autorisations et définissez une maxSdkVersion d'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é d'accès aux photos sélectionnées sous Android 14, votre application devrait adopter le nouvelle autorisation READ_MEDIA_VISUAL_USER_SELECTED pour contrôler les contenus multimédias et mettre à jour l'interface de votre appli pour permettre aux utilisateurs de lui accorder l'accès à un autre ensemble d'images et de vidéos. L'image suivante montre un exemple demandant les autorisations et resélectionnant le média:

<ph type="x-smartling-placeholder">
</ph> 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'ils souhaitent mettre à la disposition de votre application.

Lorsque vous ouvrez la boîte de dialogue de sélection, des photos, des vidéos ou les deux s'affichent en fonction de sur les autorisations demandées. Par exemple, si vous demandez Autorisation READ_MEDIA_VIDEO sans l'autorisation READ_MEDIA_IMAGES, uniquement vidéos apparaissaient 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é à l'accès bibliothèque photo et mettez à jour votre interface en conséquence. Demander ces autorisations lorsque l'application a besoin d'accéder à l'espace de stockage, et non au démarrage. Gardez à l'esprit que l'autorisation d'accès peut être modifiée entre les applications onStart et onResume de cycle de vie, 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 d'appareils

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 si l'accès accordé est 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 un texte tel que Paging bibliothèque pour garantir de bonnes performances.

Interroger la dernière sélection

Les applications sous Android 15 et versions ultérieures et sur Android 14 compatibles avec les mises à jour du système Google Play peuvent : interroger la dernière sélection d'images et de vidéos réalisées par l'utilisateur avec un accès partiel ; en activant QUERY_ARG_LATEST_SELECTION_ONLY:

if (getExtensionVersion(Build.VERSION_CODES.U) >= 12) {
    val queryArgs = bundleOf(
        QUERY_ARG_SQL_SORT_ORDER to "${Images.Media.DATE_ADDED} DESC"
        QUERY_ARG_LATEST_SELECTION_ONLY to true
    )

    contentResolver.query(collectionUri, projection, queryArgs, null)
}

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. hibernation de l'application, modification des paramètres de votre application par l'utilisateur ou votre application passe en arrière-plan. Vérifiez plutôt les autorisations de stockage 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 comporte qu'une partie à 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.
  • Actualiser les résultats lorsque votre application passe par le cycle de vie de l'application onResume car l'utilisateur peut passer d'un accès complet à un accès partiel via 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 les autorisations système l'accès de votre application aux photos et vidéos sélectionnées expire. Votre application doit toujours gérer l'absence d'accès à n'importe quel Uri, non leur autorité.

Filtrer le type de contenu sélectionnable en fonction de l'autorisation

La boîte de dialogue de sélection tient compte du type d'autorisation demandé:

  • Si vous ne demandez que READ_MEDIA_IMAGES, seules les images pouvant être sélectionnées s'affichent.
  • Si vous ne demandez que READ_MEDIA_VIDEO, seule la vidéo peut être sélectionnée.
  • Le fait de demander READ_MEDIA_IMAGES et READ_MEDIA_VIDEO permet d'afficher l'intégralité la bibliothèque photo.

Selon les cas d'utilisation de votre application, assurez-vous de demander les autorisations pour éviter une mauvaise expérience utilisateur. Si une fonctionnalité n'est attendue vidéos à sélectionner, 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 et doit permettre à l'utilisateur d'accorder plus .

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

Mode de compatibilité

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

Comportement lors de la sélection initiale du support

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

Comportement lors de la resélection du média

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

Si votre application respecte les bonnes pratiques concernant les autorisations, vous ne devriez pas constater de modification casser votre application. Cela est particulièrement vrai si votre application ne suppose pas que cet URI l'accès est conservé, stocke l'état des autorisations du système ou actualise l'ensemble des affichées après la modification de l'autorisation. Toutefois, il est possible que ce comportement sont idéales en fonction du cas d'utilisation de votre application. Afin d'offrir la meilleure expérience possible pour vos utilisateurs, nous vous recommandons d'implémenter le sélecteur de photos ou d'adapter votre le sélecteur de galerie de l'application pour gérer ce comportement directement à l'aide de la Autorisation READ_MEDIA_VISUAL_USER_SELECTED.