Scoped Storage — ce que c'est, gestion des fichiers et accès au stockage

Auteur : IT Sectr Publié le : 2026-07-10 Temps de lecture : 10 min

Scoped Storage est un modèle d'accès au système de fichiers introduit dans Android 10 (API 29) qui restreint l'accès arbitraire des applications au stockage partagé de l'appareil. Selon la Documentation Développeur Android de Google (2024), Scoped Storage remplace l'ancien modèle d'autorisations READ_EXTERNAL_STORAGE et WRITE_EXTERNAL_STORAGE, accordant aux applications uniquement l'accès à leurs propres fichiers dans un sandbox isolé et aux collections partagées via MediaStore. Ce modèle renforce la confidentialité des données utilisateur et empêche la collecte non autorisée d'informations par les applications.

Points clés

  • Scoped Storage est un modèle d'accès aux fichiers dans Android 10+ qui restreint la lecture arbitraire du stockage partagé.
  • L'application dispose de son propre sandbox avec un accès complet sans autorisations supplémentaires.
  • Pour accéder aux fichiers partagés (photos, vidéos, audio), on utilise l'API MediaStore.
  • Pour accéder aux répertoires et fichiers arbitraires, on utilise le Storage Access Framework (SAF).
  • Les autorisations READ_EXTERNAL_STORAGE et WRITE_EXTERNAL_STORAGE ont perdu leur effet pour la plupart des scénarios.

Qu'est-ce que Scoped Storage dans Android ?

Scoped Storage est un changement architectural dans Android 10 (API 29) qui transforme fondamentalement la façon dont les applications accèdent au système de fichiers de l'appareil. Au lieu d'un accès complet au stockage partagé, l'application obtient uniquement l'accès à son propre sandbox et à des collections multimédias spécifiques via MediaStore.

Avant Scoped Storage, toute application disposant de l'autorisation READ_EXTERNAL_STORAGE pouvait lire tous les fichiers du stockage partagé — photos, documents, téléchargements, données d'autres applications. Cela créait des risques de confidentialité : des applications non fiables pouvaient collecter des informations sur l'utilisateur à son insu.

Selon Google I/O 2019, plus de 65 % des utilisateurs d'Android considèrent la confidentialité des données comme un facteur critique lors du choix d'une application. Scoped Storage est une réponse directe à cette demande : chaque application fonctionne dans un environnement isolé et n'accède aux données d'autres applications qu'avec le consentement explicite de l'utilisateur.

Important : Scoped Storage dans Android 10 était optionnel (l'application pouvait le désactiver via requestLegacyExternalStorage). À partir d'Android 11 (API 30), Scoped Storage est devenu obligatoire pour toutes les applications, quel que soit le target SDK.

Pourquoi Scoped Storage a été nécessaire

Google a introduit Scoped Storage pour résoudre trois problèmes fondamentaux de l'ancien modèle d'accès aux fichiers : la confidentialité, la gestion des autorisations et le nettoyage des fichiers résiduels.

Problème de confidentialité

Dans l'ancien modèle, une application avec READ_EXTERNAL_STORAGE pouvait scanner tout le stockage partagé et collecter les métadonnées des fichiers de l'utilisateur — coordonnées géographiques des photos, noms de documents, structure des répertoires. Scoped Storage élimine cette possibilité : même avec l'autorisation, l'application ne voit que les fichiers qu'elle a créés elle-même et les fichiers sélectionnés explicitement par l'utilisateur via SAF.

Problème de nettoyage lors de la désinstallation

Avant Scoped Storage, les applications pouvaient laisser des fichiers dans le stockage partagé après la désinstallation. Avec le temps, des répertoires indésirables s'accumulaient. Scoped Storage résout ce problème : tous les fichiers dans le sandbox de l'application sont supprimés avec l'application, et les fichiers via MediaStore ont un propriétaire et peuvent être nettoyés par le système.

AspectAncien modèle (Legacy)Scoped Storage
Accès au stockage partagéComplet (avec autorisation)Seulement son sandbox
Fichiers multimédiaChemin de fichier directVia URI MediaStore
Fichiers des autres applicationsToujours accessiblesUniquement via SAF
Nettoyage à la désinstallationLes fichiers restentLe sandbox est supprimé
Contrôle de l'utilisateurMinimalConsentement explicite par fichier

Scoped Storage fait partie de la stratégie globale de confidentialité de Google dans Android, qui inclut également les autorisations « uniquement pendant l'utilisation », les indicateurs d'accès à la caméra et au microphone, et le Tableau de bord de la confidentialité.

Répertoire privé de l'application

Chaque application Android reçoit son propre répertoire privé, accessible via Context.getFilesDir() et context.getCacheDir(). Pour accéder au répertoire privé externe (partagé), on utilise Context.getExternalFilesDir().

Dans Scoped Storage, une application a un accès complet à son répertoire privé externe sans aucune autorisation. C'est l'emplacement principal pour stocker les fichiers qui ne doivent pas être accessibles aux autres applications ou que l'application crée pour son propre usage.

kotlin
import android.os.Environment
import java.io.File
import java.io.IOException

class FileManager {

    fun saveToAppStorage(context: Context, fileName: String, data: ByteArray) {
        val appDir = context.getExternalFilesDir(null)
            ?: return
        val file = File(appDir, fileName)
        file.writeBytes(data)
    }

    fun readFromAppStorage(context: Context, fileName: String): ByteArray? {
        val appDir = context.getExternalFilesDir(null)
            ?: return null
        val file = File(appDir, fileName)
        return file.takeIf { it.exists() }?.readBytes()
    }
}

Chemin vers le répertoire privé externe : /storage/emulated/0/Android/data/{packageName}/files/. À partir d'Android 11, le chemin de fichier direct n'est pas disponible — seulement via l'API. C'est une autre amélioration de sécurité de Scoped Storage.

MediaStore — accès aux fichiers multimédia

MediaStore est l'API principale pour accéder aux fichiers multimédias partagés (images, vidéos, audio) dans Scoped Storage. L'application ne travaille pas avec des chemins de fichier, mais avec des content URIs fournis par le fournisseur MediaStore.

MediaStore est divisé en trois collections principales : Images, Video et Audio. Chaque collection prend en charge les opérations CRUD via ContentResolver. Pour insérer un nouveau fichier dans la collection Images, on utilise MediaStore.Images.Media ; pour interroger les fichiers existants — query avec l'URI correspondante.

kotlin
import android.content.ContentValues
import android.provider.MediaStore
import android.os.Environment
import java.io.OutputStream

fun saveImageToGallery(context: Context, bitmap: Bitmap, title: String) {
    val values = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, "$title.jpg")
        put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        put(
            MediaStore.Images.Media.RELATIVE_PATH,
            "${Environment.DIRECTORY_PICTURES}/MyApp"
        )
    }

    val uri = context.contentResolver
        .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
        ?: return

    context.contentResolver.openOutputStream(uri)?.use { output: OutputStream ->
        bitmap.compress(
            Bitmap.CompressFormat.JPEG,
            95,
            output
        )
    }
}

Important : MediaStore ne prend pas en charge les chemins de fichier arbitraires — seulement les content URIs. Essayer d'obtenir un chemin de fichier à partir d'une URI via MediaStore.Files.getContentUri() ne donnera pas un chemin direct vers le fichier sur Android 11+. utilisez plutôt ContentResolver.openInputStream() et openOutputStream() pour travailler avec le contenu.

Storage Access Framework (SAF)

Storage Access Framework (SAF) est une API pour accéder aux fichiers et répertoires arbitraires en dehors du sandbox de l'application. SAF fournit à l'utilisateur une interface de sélection de fichier ou de répertoire, après quoi l'application reçoit une content URI avec un accès temporaire.

SAF est utilisé pour les scénarios non couverts par MediaStore : travailler avec des documents arbitraires (PDF, ZIP, APK), accéder aux répertoires sur la carte SD, importer et exporter des fichiers depuis d'autres applications. L'utilisateur sélectionne explicitement un fichier via le sélecteur de fichiers système — cela garantit son consentement à l'accès.

kotlin
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.provider.DocumentsContract

const val REQUEST_CODE_PICK_DIR = 1001

fun pickDirectory(activity: Activity) {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
    activity.startActivityForResult(intent, REQUEST_CODE_PICK_DIR)
}

fun handlePickResult(requestCode: Int, data: Intent?) {
    if (requestCode == REQUEST_CODE_PICK_DIR && data != null) {
        val treeUri: Uri = data.data ?: return

        // Take persistent URI permission
        val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
                       Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        contentResolver.takePersistableUriPermission(treeUri, flags)
    }
}

SAF accorde à l'application l'accès au répertoire sélectionné par l'utilisateur jusqu'au redémarrage de l'appareil (en utilisant takePersistableUriPermission). C'est le seul moyen d'obtenir un accès à des fichiers arbitraires dans le stockage partagé sur Android 11+.

Migration de votre application vers Scoped Storage

La migration d'une application Android existante vers Scoped Storage nécessite des changements dans plusieurs domaines clés. Google recommande une approche progressive avec des tests sur Android 11+.

Remplacer les chemins de fichier par des content URIs

Remplacez toutes les opérations directes avec File dans le stockage partagé par ContentResolver.openInputStream / openOutputStream. Pour les fichiers dans le sandbox de l'application (getExternalFilesDir), les chemins de fichier continuent de fonctionner.

Mettre à jour AndroidManifest

Supprimez READ_EXTERNAL_STORAGE et WRITE_EXTERNAL_STORAGE s'ils ne sont pas nécessaires pour des scénarios spécifiques (par exemple, la gestion de fichiers — pour cela il existe l'autorisation spéciale MANAGE_EXTERNAL_STORAGE).

ScénarioAncienne approcheApproche Scoped Storage
Enregistrer une photoFile(path).writeBytes()MediaStore + ContentResolver
Lire un PDFFile(path).inputStream()SAF ACTION_OPEN_DOCUMENT
Fichiers personnelsEnvironment.getExternalStorageDirectory()context.getExternalFilesDir()
CacheFile(cacheDir).writeBytes()context.cacheDir (inchangé)

Après la migration, testez l'application sur Android 11+ (API 30), en définissant targetSdk = 30 ou supérieur dans build.gradle. Assurez-vous que toutes les opérations sur les fichiers dans le stockage partagé fonctionnent via MediaStore ou SAF, et non via des chemins de fichier directs.

kotlin
import android.os.Build

fun isScopedStorage(): Boolean {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
}

fun compatReadFile(context: Context, uri: Uri): ByteArray? {
    return if (isScopedStorage()) {
        context.contentResolver
            .openInputStream(uri)?.readBytes()
    } else {
        File(uri.path ?: return null)
            .takeIf { it.exists() }
            ?.readBytes()
    }
}

Selon la Google Play Console (2024), plus de 78 % des appareils Android actifs fonctionnent sous Android 10+ avec Scoped Storage. La migration est une étape obligatoire pour publier des mises à jour sur Google Play : les nouvelles applications doivent cibler API 31+, les mises à jour — API 30+.

Questions fréquentes

Peut-on désactiver Scoped Storage dans Android 11 ?

Non, à partir d'Android 11 (API 30), Scoped Storage est obligatoire pour toutes les applications. Le flag requestLegacyExternalStorage, disponible dans Android 10, ne fonctionne pas sur API 30+. La seule façon d'obtenir un accès large au système de fichiers est l'autorisation MANAGE_EXTERNAL_STORAGE, mais elle est destinée uniquement aux gestionnaires de fichiers et aux antivirus.

Qu'est-ce que MANAGE_EXTERNAL_STORAGE et comment l'obtenir ?

MANAGE_EXTERNAL_STORAGE est une autorisation spéciale pour les applications qui ont besoin d'un accès complet au système de fichiers (gestionnaires de fichiers, outils de sauvegarde). La demande d'autorisation ouvre un écran système avec un avertissement pour l'utilisateur. Lors de la publication sur Google Play, il est nécessaire de remplir un formulaire de Déclaration sur la nécessité de cette autorisation.

Comment obtenir un chemin de fichier à partir d'une content URI dans Scoped Storage ?

Dans Scoped Storage sur Android 11+, on ne peut pas obtenir un chemin de fichier direct à partir d'une content URI. Utilisez plutôt ContentResolver.openInputStream() pour la lecture et openOutputStream() pour l'écriture. Si vous avez besoin d'un chemin de fichier pour la compatibilité avec une bibliothèque tierce, créez une copie du fichier dans getCacheDir() et travaillez avec la copie.

Comment Scoped Storage affecte-t-il FileProvider ?

FileProvider continue de fonctionner sans changement — il est utilisé pour fournir un accès aux fichiers du sandbox de l'application à d'autres applications via des content URIs. Scoped Storage n'affecte pas FileProvider, car FileProvider fonctionne au niveau des content URIs, et non des chemins de fichier directs.

Comment vérifier si un appareil prend en charge Scoped Storage ?

Vérifiez Build.VERSION.SDK_INT : s'il est >= Build.VERSION_CODES.Q (29), alors l'appareil prend en charge Scoped Storage. Cependant, sur Android 10, Scoped Storage peut être désactivé via requestLegacyExternalStorage. Sur Android 11+, vérifiez si le flag de manifeste requestLegacyExternalStorage est défini — sinon, Scoped Storage est actif.

Résumé

  • Scoped Storage est un modèle d'accès aux fichiers dans Android 10+ qui restreint la lecture arbitraire du stockage partagé.
  • L'application a un accès complet à son sandbox privé sans autorisations supplémentaires.
  • Pour accéder aux fichiers multimédias partagés, on utilise l'API MediaStore avec des content URIs.
  • Pour accéder aux fichiers et répertoires arbitraires, on utilise Storage Access Framework (SAF).
  • À partir d'Android 11, Scoped Storage est obligatoire pour toutes les applications.
  • Les autorisations READ_EXTERNAL_STORAGE et WRITE_EXTERNAL_STORAGE ne fonctionnent pas dans la plupart des scénarios sur Android 11+.
  • Lors de la migration, remplacez les chemins de fichier directs par ContentResolver.openInputStream / openOutputStream.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi