Lorsque j'ai essayé de mettre en œuvre une exigence très simple — télécharger une image et l'enregistrer dans le stockage local — Tout semblait bien au début.
- Honor (Android 10) – fonctionne
- Redmi (Android 11) – fonctionne
- Xiaomi (Android 13) – fonctionne
- Samsung (Android 13) – Échec complet : la boîte de dialogue d’autorisation de stockage ne s’affichait jamais.
Même code, même fonctionnalité, mais un appareil sous Android 13 a tout simplement refusé d'afficher la demande d'autorisation. C'est ainsi que cette petite tâche de “ téléchargement d'image ” s'est transformée en une analyse approfondie. Stockage à portée limitée et GÉRER_LE_STOCKAGE_EXTERNE.
Cet article résume comment j'ai adapté les autorisations de stockage pour Android 11 et versions ultérieures, et comment je gère les différents comportements selon les versions.
1. Le bug : la boîte de dialogue d’autorisation de stockage ne s’affiche jamais (Samsung Android 13)
L'exigence est simple :
Téléchargez une image et enregistrez-la sur l'appareil pour qu'elle apparaisse dans la galerie.
Sur mes trois appareils de test :
- Honor – Android 10 → OK
- Redmi – Android 11 → OK
- Xiaomi – Android 13 → OK
Mais sur un Appareil Samsung fonctionnant sous Android 13, le système La boîte de dialogue d'autorisation de stockage ne s'est jamais affichée., peu importe comment je l'ai demandé.



Au départ, je pensais qu'il s'agissait simplement d'une autre bizarrerie du fabricant, mais après avoir vérifié les changements d'autorisation de stockage sur les différentes versions d'Android, j'ai réalisé que je me basais sur un comportement qui avait été effectivement déprécié sur Android 13 lors du ciblage du SDK 33.
2. Cause principale : Les fonctions WRITE/READ_EXTERNAL_STORAGE sont obsolètes sur Android 13 (SDK 33).
Dans les anciennes versions d'Android, il suffisait de déclarer ces deux autorisations dans le manifeste :
LECTURE_STOCKAGE_EXTERNEÉCRIRE_STOCKAGE_EXTERNE
et les demander ensuite au moment de l'exécution, lorsque cela s'avère nécessaire.
Sur Android 13 (SDK 33) avec targetSdkVersion = 33, cette approche commence à montrer ses limites :
ÉCRIRE_STOCKAGE_EXTERNEest obsolète et pratiquement inutile sur les versions récentes d'Android- Si vous ajoutez
maxSdkVersion=32Ces autorisations fonctionnent toujours sur Android 11/12.
mais ils le sont ignoré sur Android 13 lors du ciblage de la version 33 - Parallèlement, le Play Store exige que les nouvelles applications ciblent au moins le SDK 33.
Pour Android 11 et versions ultérieures, nous devons donc nous adapter à :
- Stockage à portée limitée
- Et dans certains cas, l'autorisation spéciale :
GÉRER_LE_STOCKAGE_EXTERNE
GÉRER_LE_STOCKAGE_EXTERNE accorde à une application un accès étendu à tout le contenu du stockage partagé (y compris les fichiers non multimédias). pas Elle autorise l'accès aux répertoires privés d'autres applications, mais Google Play la considère toujours comme une autorisation très sensible.
Pour assurer la compatibilité avec les différentes versions d'Android, j'ai finalement divisé la gestion des autorisations en :
- Avant Android 11 (API < 30) – autorisations de stockage externe de style ancien
- Android 11 et versions ultérieures – Stockage sous périmètre + manutention spéciale avec
GÉRER_LE_STOCKAGE_EXTERNElà où cela est strictement nécessaire
3. Adaptation étape par étape
3.1 Déclarez MANAGE_EXTERNAL_STORAGE dans le manifeste
Dans le AndroidManifest.xml:
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />⚠️ Remarque : Parce que
GÉRER_LE_STOCKAGE_EXTERNEIl s'agit d'une autorisation sensible, restreinte sur Google Play. Je parlerai d'alternatives plus tard si vous souhaitez simplement enregistrer des images.
3.2 Vérifier si l'autorisation est accordée
J'ai utilisé EasyPermissions pour simplifier les contrôles d'autorisation.
private fun checkPer(activity: PreViewActivity): Boolean { return if (Build.VERSION.SDK_INT >= 30) { EasyPermissions.hasPermissions( activity, android.Manifest.permission.MANAGE_EXTERNAL_STORAGE ) } else { EasyPermissions.hasPermissions( activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE ) } }
- Sur Android 11+ (API >= 30)Je vérifie
GÉRER_LE_STOCKAGE_EXTERNE - Sur Android 10 et versions antérieuresJe vérifie encore.
ÉCRIRE_STOCKAGE_EXTERNE
Cette scission est cruciale, car ÉCRIRE_STOCKAGE_EXTERNE Ne se comporte plus comme sur les versions plus récentes.
3.3 Demander l'autorisation lorsqu'elle est manquante
Si l'autorisation n'est pas accordée, je la demande différemment en fonction de la version du système.
private fun requestStoragePermission(activity: PreViewActivity, curImg: Int) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // Android 11+ – redirection vers la page des paramètres système " Accès à tous les fichiers " val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) intent.data = Uri.parse("package:" + activity.packageName) activity.startActivityForResult(intent, 200) } else { // Android 10 et versions antérieures – autorisation d'exécution normale val perm = android.Manifest.permission.WRITE_EXTERNAL_STORAGE PaperThreeVariable.isToRequestPer = true EasyPermissions.requestPermissions( PermissionRequest.Builder( activity, 200, perm ).build() ) } }
- Sur Android 11+: vous ne pouvez pas simplement “ faire apparaître ” une boîte de dialogue d'exécution normale pour
GÉRER_LE_STOCKAGE_EXTERNE
Vous devez rediriger l'utilisateur vers la page des paramètres système où il devra autoriser manuellement l'accès à “ Tous les fichiers ”. - Sur Android 10 et versions antérieures: la boîte de dialogue d'autorisation d'exécution classique fonctionne toujours.
3.4 Gérer les rappels d'autorisation
EasyPermissions permet de faire le lien entre le rappel de l'activité et notre propre logique :
remplacer la fonction onRequestPermissionsResult( requestCode: Int, permissions: Array , grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) } override fun onPermissionsGranted(requestCode: Int, perms: MutableList ) { AppInitUtils().saveFreshAppImageToGallery(this, curImg) PaperThreeVariable.isToRequestPer = false } override fun onPermissionsDenied(requestCode: Int, perms: MutableList ) { PaperThreeVariable.isToRequestPer = false if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { AppSettingsDialog.Builder(this) .setRationale("Cette fonction nécessite l'activation de l'autorisation de stockage") .setNegativeButton("Non") .setPositiveButton("Oui") .build() .show() } }
Pourquoi j'utilise EasyPermissions ici :
- Les utilisateurs peuvent nier définitivement autorisations, ce qui fait que les requêtes répétées échouent silencieusement
- EasyPermissions facilite :
- Détecter l'état de “ refus permanent ”
- Afficher une boîte de dialogue qui guide les utilisateurs vers Paramètres système → Autorisations des applications activer l'accès au stockage manuellement
Une fois l'autorisation accordée, j'appelle :
AppInitUtils().saveFreshAppImageToGallery(this, curImg)
pour enregistrer l'image et actualiser la galerie.
Après cette adaptation, l'appareil Samsung sous Android 13 s'est finalement comporté comme les autres.
Remarque : Mon appareil Xiaomi était identifié comme fonctionnant sous Android 13, mais la fonction “ Historique des appareils connectés ” d’Android Studio le reconnaissait comme fonctionnant sous Android 12. Cela pourrait expliquer pourquoi il fonctionnait encore dans certains cas, mais c’est précisément pour cette raison que la gestion des autorisations en fonction de la version est importante.
4. À propos de MANAGE_EXTERNAL_STORAGE et des restrictions de Google Play
GÉRER_LE_STOCKAGE_EXTERNE est puissant :
Il accorde un accès en lecture/écriture à tout stockage partagé sur l'appareil.
De ce fait, Google Play le traite comme un autorisation hautement sensible:
- Il est principalement destiné à Gestionnaire de fichiers / Sauvegarde / Antivirus applications de type
- Vous devez fournir une justification pour l'utiliser.
- Si votre application est une simple application grand public (par exemple, enregistrement d'images, téléchargements simples), votre requête sera très probablement : rejeté
Donc si votre seule exigence est :
“ Enregistrez une image dans la galerie et rendez-la visible à l'utilisateur. ”
alors vous devriez Il est fortement conseillé d'éviter GÉRER_LE_STOCKAGE_EXTERNE et à la place :
- Utiliser MediaStore insérer des images dans la bibliothèque multimédia du système
- Vous pouvez également utiliser des API capables d'enregistrer des images sans nécessiter un accès complet au fichier.
Il existe plusieurs modèles à :
- Enregistrez une image dans le répertoire Images/DCIM
- Signalez-le au scanner multimédia ou utilisez MediaStore pour que la galerie puisse le récupérer.
- Faites tout cela sans demander MANAGE_EXTERNAL_STORAGE
Pour la distribution interne ou hors Play Store (par exemple, les boutiques d'applications internes d'entreprise), vous pouvez techniquement toujours utiliser Environnement.getExternalStorageDirectory(), mais je ne recommande pas de concevoir une nouvelle application autour de cela en 2025.
5. Résumé version par version (Android 9 → 13)
Pour tout rassembler au même endroit, voici un résumé général du comportement du stockage externe et des autorisations selon les versions.
Android 9 et versions antérieures (API 28 et antérieures)
- Autorisations:
LECTURE_STOCKAGE_EXTERNEÉCRIRE_STOCKAGE_EXTERNE
- Comportement:
- Les applications peuvent accéder librement
/carte SDet ses sous-répertoires - Les fichiers créés par l'application restent sur l'appareil même après la désinstallation de l'application.
- Les applications peuvent accéder librement
- Approche typique:
- Lecture/écriture directe sous les chemins de stockage externes
Android 10 (API 29) – Introduction du stockage limité
- Autorisations:
LECTURE_STOCKAGE_EXTERNEfonctionne toujoursÉCRIRE_STOCKAGE_EXTERNEElle existe toujours, mais sa portée effective est réduite.
- Comportement:
- Stockage à portée limitée est introduit :
- Les applications sont limitées à leur propre répertoire spécifique sous
Android/data/votre.nom.de.package/ - L'accès direct aux fichiers des autres applications est restreint.
- Les applications sont limitées à leur propre répertoire spécifique sous
- Les fichiers multimédias (images, vidéos, audio) doivent être accessibles via MediaStore
requestLegacyExternalStorage=truepourrait temporairement conserver les anciens comportements
(mais cet indicateur est ignoré à partir d'Android 11)
- Stockage à portée limitée est introduit :
- Approche recommandée:
- Pour les images/vidéos/audio : utilisez MediaStore
- Pour les fichiers privés : utilisez
obtenirExternalFilesDir()ouobtenirDataDir()
Android 11 (API 30) – Stockage limité imposé
- Autorisations:
LECTURE_STOCKAGE_EXTERNECela fonctionne, mais uniquement pour les médias gérés par MediaStore.ÉCRIRE_STOCKAGE_EXTERNEest effectivement obsolète pour le stockage externe généralGÉRER_LE_STOCKAGE_EXTERNEintroduit pour des cas d'utilisation spécifiques d'“ accès à tous les fichiers ”.
- Comportement:
requestLegacyExternalStorage=truene fonctionne plus ; le stockage limité est toujours allumé- Accès à
/carte SD/L'accès root est bloqué. - Les applications peuvent uniquement :
- Accéder à leurs propres répertoires privés
- Accéder aux médias partagés via MediaStore
- Approche recommandée:
- Pour les applications classiques :
- Utilisez MediaStore ou SAF (
ACTION_OUVRIR_DOCUMENT,ACTION_CRÉER_DOCUMENT) pour les fichiers sélectionnés par l'utilisateur
- Utilisez MediaStore ou SAF (
- Considérer uniquement
GÉRER_LE_STOCKAGE_EXTERNEsi votre application est véritablement un gestionnaire de fichiers, un outil de sauvegarde, une application de sécurité, etc.
- Pour les applications classiques :
Android 13 (API 33) – Division des autorisations multimédias
- Autorisations:
LIRE_IMAGES_MÉDIAS– accéder aux imagesLIRE_MÉDIA_VIDÉO– accéder aux vidéosLIRE_MÉDIA_AUDIO– accéder à l'audio
- Comportement:
- Les autorisations médias sont à grains fins:
- Les utilisateurs peuvent autoriser uniquement l'accès aux images, uniquement l'accès aux vidéos, etc.
- Les règles de stockage limité d'Android 11 restent en place.
- Les autorisations médias sont à grains fins:
- Approche recommandée:
- Demandez les autorisations médias spécifiques dont vous avez besoin :
- Par exemple, si vous travaillez uniquement avec des images, demandez uniquement
LIRE_IMAGES_MÉDIAS
- Par exemple, si vous travaillez uniquement avec des images, demandez uniquement
- Faire pas demande
LECTURE_STOCKAGE_EXTERNEsur Android 13+, car elle est remplacée par les nouvelles autorisations multimédias
- Demandez les autorisations médias spécifiques dont vous avez besoin :
Matrice rapide (conceptuelle)
- Android 9 et versions antérieures
- L'accès au stockage externe est étendu et contrôlé par READ/WRITE_EXTERNAL_STORAGE.
- Android 10
- Le stockage à portée limitée a été introduit, mais il existe des issues de secours (
requestLegacyExternalStorage)
- Le stockage à portée limitée a été introduit, mais il existe des issues de secours (
- Android 11
- Le stockage limité est imposé, les commutateurs hérités sont supprimés.
GÉRER_LE_STOCKAGE_EXTERNEapparaît, mais est très restreint.
- Android 13
- L'accès aux médias divisé en
LIRE_MÉDIA_*autorisations - Mêmes règles de stockage limité, mais contrôle utilisateur plus précis
- L'accès aux médias divisé en
6. Points clés
- Ne présumez pas que “ cela fonctionne sur un appareil Android 13 ” signifie que cela fonctionne partout ; les rapports des fabricants et des systèmes peuvent être incohérents.
- Pour Android 11+, pensez en termes de :
- Répertoires privés d'applications + MediaStore + SAF, pas “ cru »
/carte SDaccéder"”
- Répertoires privés d'applications + MediaStore + SAF, pas “ cru »
- Traiter
GÉRER_LE_STOCKAGE_EXTERNEcomme un dernier recours pour des types d'applications très spécifiques, notamment si vous prévoyez de publier sur Google Play. - Toujours tester sur plusieurs appareils et versions Android, notamment en ce qui concerne les autorisations et le stockage.
Cet article est issu de mes propres débogages et adaptations sur des projets Android réels (dont un appareil Samsung sous Android 13). GPT a uniquement contribué à la traduction et à la reformulation ; l’ensemble du contenu technique et des décisions sont de ma responsabilité.


