Cas d'utilisation de l'espace de stockage Android et bonnes pratiques

Pour mieux contrôler les fichiers et limiter l'encombrement, Android 10 inclut un nouveau modèle de stockage pour les applications, appelé espace de stockage cloisonné. L'espace de stockage cloisonné modifie la façon dont les applications stockent les fichiers et y accèdent sur la mémoire de stockage externe d'un appareil. Pour que votre application soit compatible avec cette fonctionnalité, suivez les bonnes pratiques décrites dans ce guide pour les cas d'utilisation les plus courants. Ces derniers sont classés dans deux catégories : gestion des fichiers multimédias et gestion des fichiers non multimédias.

Dans de nombreux cas, votre application crée des fichiers auxquels d'autres applications n'ont pas besoin d'accéder ou ne doivent pas accéder. Le système fournit des emplacements de stockage spécifiques à l'application pour gérer ces fichiers.

Pour découvrir comment stocker des fichiers et y accéder sur Android, consultez les guides de formation relatifs au stockage.

Gérer les fichiers multimédias

Cette section décrit certains des cas d'utilisation courants liées à la gestion des fichiers multimédias (fichiers vidéo, image et audio), et explique l'approche globale que votre application peut utiliser. Le tableau suivant récapitule chacun de ces cas d'utilisation et renvoie vers chacune des sections contenant des informations supplémentaires.

Cas d'utilisation Résumé
Afficher tous les fichiers image ou vidéo Utilisez la même approche pour toutes les versions d'Android.
Afficher les images ou les vidéos d'un dossier donné Utilisez la même approche pour toutes les versions d'Android.
Accéder aux informations de géolocalisation des photos Optez pour une seule approche si votre application utilise un espace de stockage cloisonné. Optez pour une approche distincte si l'espace de stockage cloisonné a été désactivé pour votre application.
Définir l'emplacement de stockage pour les nouveaux téléchargements Optez pour une seule approche si votre application utilise un espace de stockage cloisonné. Optez pour une approche distincte si l'espace de stockage cloisonné a été désactivé pour votre application.
Exporter les fichiers multimédias des utilisateurs vers un appareil Utilisez la même approche pour toutes les versions d'Android.
Modifier ou supprimer plusieurs fichiers multimédias en une seule opération Choisissez une seule approche pour Android 11. Pour Android 10, désactivez l'espace de stockage cloisonné et choisissez l'approche pour Android 9 ou version antérieure.
Importer une seule image qui existe déjà Utilisez la même approche pour toutes les versions d'Android.
Capturer une seule image Utilisez la même approche pour toutes les versions d'Android.
Partager des fichiers multimédias avec d'autres applications Utilisez la même approche pour toutes les versions d'Android.
Partager des fichiers multimédias avec une application spécifique Utilisez la même approche pour toutes les versions d'Android.
Accéder à des fichiers à partir du code ou de bibliothèques utilisant des chemins d'accès directs Choisissez une seule approche pour Android 11. Pour Android 10, désactivez l'espace de stockage cloisonné et choisissez l'approche pour Android 9 ou version antérieure.

Afficher des fichiers image ou vidéo issus de plusieurs dossiers

Interroger une collection multimédia à l'aide de l'API query() Pour filtrer ou trier les fichiers multimédias, ajustez les paramètres projection, selection, selectionArgs et sortOrder.

Afficher les images ou les vidéos d'un dossier donné

Adoptez cette approche :

  1. Conformément aux bonnes pratiques décrites dans cette section, demandez l'autorisation READ_EXTERNAL_STORAGE.
  2. Récupérez les fichiers multimédias en fonction de la valeur de MediaColumns.DATA, qui contient le chemin absolu du système de fichiers vers l'élément multimédia sur le disque.

Remarque : Lorsque vous accédez à un fichier multimédia existant, vous pouvez utiliser la valeur de la colonne DATA dans votre logique. Cela est dû au fait que cette valeur contient un chemin d'accès valide. Toutefois, ne partez pas du principe que le fichier est toujours disponible. Préparez-vous à gérer les éventuelles erreurs d'E/S basées sur les fichiers.

Pour créer ou mettre à jour un fichier multimédia, n'utilisez pas la colonne DATA. Préférez les colonnes DISPLAY_NAME et RELATIVE_PATH.

Accéder aux informations de géolocalisation des photos

Si votre application utilise un espace de stockage cloisonné, suivez la procédure décrite dans cette section du guide sur le stockage de fichiers multimédias.

Définir l'emplacement de stockage pour les nouveaux téléchargements

Si votre application utilise un espace de stockage cloisonné, tenez compte de l'emplacement où vous choisissez de stocker les fichiers multimédias que vous téléchargez.

Si d'autres applications ont besoin d'accéder à ces fichiers, pensez à utiliser des collections multimédias bien définies pour les téléchargements ou les collections de documents.

Sur Android 11 et versions ultérieures, les autres applications ne peuvent pas accéder aux fichiers situés dans votre répertoire externe spécifique à l'application, même si vous utilisez DownloadManager pour récupérer ces fichiers.

Exporter les fichiers multimédias des utilisateurs vers un appareil

Définissez un emplacement par défaut approprié pour stocker les fichiers multimédias des utilisateurs :

Modifier ou supprimer plusieurs fichiers multimédias en une seule opération

Incorporez une logique basée sur les versions d'Android sur lesquelles votre application s'exécute.

Exécution sur Android 11

Adoptez cette approche :

  1. Créez un intent en attente pour la requête d'écriture ou de suppression de votre application à l'aide de MediaStore.createWriteRequest() ou de MediaStore.createTrashRequest(), puis demandez à l'utilisateur d'autoriser la modification d'un ensemble de fichiers en appelant cet intent.
  2. Évaluez la réponse de l'utilisateur :

    • Si l'autorisation est accordée, procédez à la modification ou à la suppression.
    • Si l'autorisation n'a pas été accordée, expliquez à l'utilisateur pourquoi la fonctionnalité de votre application nécessite cette autorisation.

Découvrez comment gérer des groupes de fichiers multimédias à l'aide de ces méthodes, disponibles sur Android 11 ou version ultérieure.

Exécution sur Android 10

Si votre application cible Android 10 (niveau d'API 29), désactivez l'espace de stockage cloisonné et continuez à utiliser l'approche spécifique à Android 9 ou version antérieure pour effectuer cette opération.

Exécution sur Android 9 ou version antérieure

Adoptez cette approche :

  1. Conformément aux bonnes pratiques décrites dans cette section, demandez l'autorisation WRITE_EXTERNAL_STORAGE.
  2. Utilisez l'API MediaStore pour modifier ou supprimer les fichiers multimédias.

Importer une seule image qui existe déjà

Lorsque vous souhaitez importer une seule image qui existe déjà (par exemple, pour la photo d'un profil utilisateur), votre application peut utiliser sa propre UI pour l'opération ou peut utiliser le sélecteur système.

Utiliser votre propre interface utilisateur

Adoptez cette approche :

  1. Conformément aux bonnes pratiques décrites dans cette section, demandez l'autorisation READ_EXTERNAL_STORAGE.
  2. Utilisez l'API query() pour interroger une collection multimédia.
  3. Affichez les résultats dans l'interface utilisateur personnalisée de votre application.

Utiliser le sélecteur système

Utilisez l'intent ACTION_GET_CONTENT, qui demande à l'utilisateur de choisir une image à importer.

Si vous souhaitez filtrer les types d'images que le sélecteur de système présente à l'utilisateur, vous avez le choix entre setType() ou EXTRA_MIME_TYPES.

Capturer une seule image

Lorsque vous souhaitez capturer une seule image à utiliser dans votre application (par exemple, pour l'afficher comme photo de profil d'un utilisateur), utilisez l'intent ACTION_IMAGE_CAPTURE pour demander à l'utilisateur l'autorisation de prendre une photo avec l'appareil photo de son appareil. Le système stockera la photo capturée dans la table MediaStore.Images.

Partager des fichiers multimédias avec d'autres applications

Utilisez la méthode insert() pour ajouter des enregistrements directement dans MediaStore. Pour en savoir plus, consultez la section Ajouter un élément du guide sur le stockage multimédia.

Partager des fichiers multimédias avec une application spécifique

Utilisez le composant FileProvider d'Android, comme décrit dans le guide Configurer le partage de fichiers.

Accéder à des fichiers à partir du code ou de bibliothèques utilisant des chemins d'accès directs

Incorporez une logique basée sur les versions d'Android sur lesquelles votre application s'exécute.

Exécution sur Android 11

Adoptez cette approche :

  1. Conformément aux bonnes pratiques décrites dans cette section, demandez l'autorisation READ_EXTERNAL_STORAGE.
  2. Accédez aux fichiers à l'aide de leur chemin direct.

Pour en savoir plus, consultez la section expliquant comment ouvrir des fichiers multimédias à l'aide des chemins d'accès directs aux fichiers.

Exécution sur Android 10

Si votre application cible Android 10 (niveau d'API 29), désactivez l'espace de stockage cloisonné et continuez à utiliser l'approche spécifique à Android 9 ou version antérieure pour effectuer cette opération.

Exécution sur Android 9 ou version antérieure

Adoptez cette approche :

  1. Conformément aux bonnes pratiques décrites dans cette section, demandez l'autorisation WRITE_EXTERNAL_STORAGE.
  2. Accédez aux fichiers à l'aide de leur chemin direct.

Gérer les fichiers non multimédias

Cette section décrit certains des cas d'utilisation courants liés à la gestion des fichiers non multimédias, et explique l'approche globale que votre application peut utiliser. Le tableau suivant récapitule chacun de ces cas d'utilisation et renvoie vers chacune des sections contenant des informations supplémentaires.

Cas d'utilisation Résumé
Ouvrir un fichier de document Utilisez la même approche pour toutes les versions d'Android.
Écrire dans des fichiers stockés sur des volumes de stockage secondaires Choisissez une seule approche pour Android 11. Utilisez une approche distincte pour les versions antérieures d'Android.
Migrer des fichiers existants depuis un ancien emplacement de stockage Si possible, migrez vos fichiers vers un espace de stockage cloisonné. Désactivez le stockage cloisonné pour Android 10 si nécessaire.
Partager du contenu avec d'autres applications Utilisez la même approche pour toutes les versions d'Android.
Mettre en cache les fichiers non multimédias Utilisez la même approche pour toutes les versions d'Android.
Exporter des fichiers non multimédias vers un appareil Optez pour une seule approche si votre application utilise un espace de stockage cloisonné. Optez pour une approche distincte si l'espace de stockage cloisonné a été désactivé pour votre application.

Ouvrir un fichier de document

Utilisez l'intent ACTION_OPEN_DOCUMENT pour demander à l'utilisateur de sélectionner un fichier à ouvrir à l'aide du sélecteur système. Si vous souhaitez filtrer les types de fichiers que le sélecteur système présente à l'utilisateur, vous avez le choix entre setType() ou .EXTRA_MIME_TYPES

Par exemple, vous pouvez rechercher tous les fichiers PDF, ODT et TXT à l'aide du code suivant :

Kotlin

startActivityForResult(
        Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
            putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
                    "application/pdf", // .pdf
                    "application/vnd.oasis.opendocument.text", // .odt
                    "text/plain" // .txt
            ))
        },
        REQUEST_CODE
      )

Java

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
                "application/pdf", // .pdf
                "application/vnd.oasis.opendocument.text", // .odt
                "text/plain" // .txt
        });
        startActivityForResult(intent, REQUEST_CODE);

Écrire dans des fichiers stockés sur des volumes de stockage secondaires

Les volumes de stockage secondaires incluent les cartes SD. Pour accéder aux informations concernant un volume de stockage donné, utilisez la classe StorageVolume.

Incorporez une logique basée sur la version d'Android sur laquelle votre application s'exécute.

Exécution sur Android 11

Adoptez cette approche :

  1. Utilisez le modèle d'espace de stockage cloisonné.
  2. Ciblez Android 10 (niveau d'API 29) ou version antérieure.
  3. Déclarez l'autorisation WRITE_EXTERNAL_STORAGE.
  4. Définissez l'un des types d'accès suivants :
    • Accès aux fichiers via l'API MediaStore
    • Accès via le chemin d'accès direct aux fichiers à l'aide d'API telles que File ou fopen()

Exécution sur des versions plus anciennes

Utilisez le framework d'accès au stockage, qui permet aux utilisateurs de sélectionner l'emplacement d'un volume de stockage secondaire dans lequel votre application peut enregistrer le fichier.

Migrer des fichiers existants depuis un ancien emplacement de stockage

Un répertoire est considéré comme un ancien emplacement de stockage s'il ne s'agit pas d'un répertoire spécifique à l'application ni d'un répertoire partagé public. Si votre application crée ou consomme des fichiers dans un ancien emplacement de stockage, nous vous recommandons de migrer ses fichiers vers des emplacements accessibles avec un espace de stockage cloisonné et d'apporter les modifications nécessaires à l'application pour qu'elle fonctionne avec les fichiers inclus dans cet espace de stockage.

Conserver l'accès à l'ancien emplacement de stockage pour la migration des données

Pour pouvoir migrer les fichiers de l'application vers les emplacements accessibles via un espace de stockage cloisonné, votre application doit conserver l'accès à l'ancien emplacement de stockage. L'approche à utiliser dépend du niveau d'API cible de votre application.

Si votre application cible Android 11
  1. Définissez l'indicateur preserveLegacyExternalStorage sur true pour conserver l'ancien modèle de stockage afin que votre application puisse migrer les données d'un utilisateur lorsqu'il passe à la nouvelle version de votre application qui cible Android 11.

  2. Continuez à désactiver l'espace de stockage cloisonné pour que votre application puisse continuer à accéder à vos fichiers dans l'ancien emplacement de stockage sur les appareils Android 10.

Si votre application cible Android 10

Désactivez l'espace de stockage cloisonné pour que le comportement de votre application sur toutes les versions d'Android soit harmonieux.

Migrer les données de l'application

Lorsque votre application est prête pour la migration, adoptez l'approche suivante :

  1. Ciblez Android 10 ou version antérieure.
  2. Désactivez l'espace de stockage cloisonné afin que votre application ait accès aux fichiers que vous devez migrer.
  3. Déployez le code qui utilise l'API File pour déplacer les fichiers de leur emplacement actuel sous /sdcard/ vers un emplacement accessible via un espace de stockage cloisonné :

    1. Déplacez tous les fichiers d'application privés vers le répertoire renvoyé par la méthode getExternalFilesDir().
    2. Déplacez tous les fichiers non multimédias partagés vers un sous-répertoire dédié du répertoire Downloads/.
  4. Supprimez les anciens répertoires de stockage de votre application du répertoire /sdcard/.

Une fois que les utilisateurs auront installé la nouvelle version de votre application, ils effectueront le processus de migration des données sur leurs appareils. Vous pouvez créer un événement d'analyse afin de surveiller ce processus pour votre base d'utilisateurs.

Une fois que les utilisateurs ont migré leurs données, publiez une autre mise à jour dans votre application, qui cible Android 11.

Partager du contenu avec d'autres applications

Pour partager les fichiers de votre application avec une seule autre application, utilisez un fichier FileProvider. Pour les applications qui doivent partager des fichiers entre elles, nous vous recommandons de recourir à un fournisseur de contenu pour chaque application, puis de synchroniser les données à mesure que les applications sont ajoutées à la collection.

Mettre en cache les fichiers non multimédias

L'approche à adopter dépend du type de fichier à mettre en cache.

Exporter des fichiers non multimédias vers un appareil

Définissez un emplacement par défaut approprié pour stocker les fichiers non multimédias. Donnez aux utilisateurs la possibilité d'exporter des fichiers depuis des répertoires spécifiques à l'application vers un emplacement plus accessible. Utilisez les téléchargements ou collections de documents de MediaStore pour exporter les fichiers non multimédias vers l'appareil.

Gérer les fichiers spécifiques à l'application

Si votre application crée des fichiers auxquels d'autres applications n'ont pas besoin d'accéder ou ne doivent pas accéder, vous pouvez les stocker dans des emplacements de stockage spécifiques à l'application.

Répertoires de stockage interne

Le système empêche d'autres applications d'accéder à ces emplacements. Ils sont chiffrés sur Android 10 (niveau d'API 29) ou version ultérieure. Ces emplacements sont un bon endroit pour stocker des données sensibles auxquelles seule votre application peut accéder.

Répertoires de stockage externe

Si la mémoire de stockage interne est insuffisante pour stocker les fichiers spécifiques à l'application, envisagez d'utiliser un espace de stockage externe. Bien qu'une autre application puisse accéder à ces répertoires si elle dispose des autorisations appropriées, les fichiers stockés dans ces répertoires ne sont destinés qu'à votre application.

Sous Android 4.4 (niveau d'API 19) ou version ultérieure, votre application n'a pas besoin de demander des autorisations liées au stockage pour accéder aux répertoires spécifiques à l'application dans un espace de stockage externe.

Lorsque l'utilisateur désinstalle votre application, les fichiers enregistrés dans l'espace de stockage spécifique à l'application sont supprimés. Par conséquent, vous ne devez pas utiliser cet espace de stockage pour enregistrer tout élément que l'utilisateur s'attend à conserver indépendamment de votre application.

Désactiver temporairement l'espace de stockage cloisonné

Avant que votre application soit entièrement compatible avec l'espace de stockage cloisonné, vous pouvez le désactiver temporairement, à la fois dans vos tests et dans votre application de production.

Désactiver l'espace de stockage cloisonné dans vos tests

Sur Android 10 (niveau d'API 29) ou version ultérieure, les tests de votre application s'exécutent par défaut dans un bac à sable de stockage. Ce bac à sable empêche votre application d'accéder aux fichiers situés en dehors du répertoire spécifique à l'application et des répertoires partagés publiquement.

Si un test génère des fichiers pour l'hôte, tels que des captures d'écran, des données de débogage, des données de couverture ou des métriques de performances, vous pouvez écrire ces fichiers dans des répertoires globaux. Pour ce faire, ajoutez l'indicateur suivant à l'élément approprié qui appelle am instrument :

-e no-isolated-storage 1

Cet indicateur s'applique au comportement entier du scénario de test instrumenté et à tout le code de test appelé. Par conséquent, lorsque vous l'utilisez, vous ne pouvez pas confirmer la compatibilité de votre application avec l'espace de stockage cloisonné. Pour les résultats de test, il est préférable d'écrire dans un espace de stockage spécifique à l'application que l'interface système peut comprendre. Vous pouvez ensuite extraire ce répertoire spécifique à l'application. Pour déterminer le répertoire à partir duquel effectuer l'extraction, appelez getExternalMediaDirs().

Désactiver l'espace de stockage cloisonné dans l'application de production

Si votre application cible Android 10 (niveau d'API 29) ou version antérieure, vous pouvez désactiver temporairement l'espace de stockage cloisonné dans votre application de production. Toutefois, si vous ciblez Android 10, vous devez définir la valeur de requestLegacyExternalStorage sur true dans le fichier manifeste de votre application :

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

Pour tester le comportement d'une application ciblant Android 10 ou version antérieure lors de l'utilisation de l'espace de stockage cloisonné, définissez la valeur de requestLegacyExternalStorage sur false afin d'activer ce comportement. Si vous effectuez le test sur un appareil exécutant Android 11, vous pouvez également utiliser des indicateurs de compatibilité pour tester le comportement de votre application avec ou sans espace de stockage cloisonné.

Ressources supplémentaires

Pour en savoir plus sur l'espace de stockage Android, consultez les ressources suivantes :

Articles de blog