{"id":3803,"date":"2025-11-27T18:25:57","date_gmt":"2025-11-27T10:25:57","guid":{"rendered":"https:\/\/imastudio.com\/?p=3803"},"modified":"2025-11-27T18:25:58","modified_gmt":"2025-11-27T10:25:58","slug":"android-storage-permission-adaptation-guide","status":"publish","type":"post","link":"https:\/\/imastudio.com\/fr\/blog\/android-storage-permission-adaptation-guide","title":{"rendered":"Guide d&#039;adaptation des autorisations de stockage Android pour Android 11 et versions ult\u00e9rieures"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Lorsque j&#039;ai essay\u00e9 de mettre en \u0153uvre une exigence tr\u00e8s simple \u2014 <strong>t\u00e9l\u00e9charger une image et l&#039;enregistrer dans le stockage local<\/strong> \u2014 Tout semblait bien au d\u00e9but.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Honor (Android 10) \u2013 fonctionne<\/li>\n\n\n\n<li>Redmi (Android 11) \u2013 fonctionne<\/li>\n\n\n\n<li>Xiaomi (Android 13) \u2013 fonctionne<\/li>\n\n\n\n<li><strong>Samsung (Android 13)<\/strong> \u2013 \u00c9chec complet\u00a0: la bo\u00eete de dialogue d\u2019autorisation de stockage ne s\u2019affichait jamais.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">M\u00eame code, m\u00eame fonctionnalit\u00e9, mais un appareil sous Android 13 a tout simplement refus\u00e9 d&#039;afficher la demande d&#039;autorisation. C&#039;est ainsi que cette petite t\u00e2che de \u201c\u00a0t\u00e9l\u00e9chargement d&#039;image\u00a0\u201d s&#039;est transform\u00e9e en une analyse approfondie. <strong>Stockage \u00e0 port\u00e9e limit\u00e9e<\/strong> et <strong>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cet article r\u00e9sume comment j&#039;ai adapt\u00e9 les autorisations de stockage pour <strong>Android 11 et versions ult\u00e9rieures<\/strong>, et comment je g\u00e8re les diff\u00e9rents comportements selon les versions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Le bug\u00a0: la bo\u00eete de dialogue d\u2019autorisation de stockage ne s\u2019affiche jamais (Samsung Android 13)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">L&#039;exigence est simple :<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">T\u00e9l\u00e9chargez une image et enregistrez-la sur l&#039;appareil pour qu&#039;elle apparaisse dans la galerie.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Sur mes trois appareils de test\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Honor \u2013 Android 10 \u2192 OK<\/li>\n\n\n\n<li>Redmi \u2013 Android 11 \u2192 OK<\/li>\n\n\n\n<li>Xiaomi \u2013 Android 13 \u2192 OK<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Mais sur un <strong>Appareil Samsung fonctionnant sous Android 13<\/strong>, le syst\u00e8me <strong>La bo\u00eete de dialogue d&#039;autorisation de stockage ne s&#039;est jamais affich\u00e9e.<\/strong>, peu importe comment je l&#039;ai demand\u00e9.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"184\" src=\"https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182134-1024x184.jpeg\" alt=\"\" class=\"wp-image-3810\" srcset=\"https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182134-1024x184.jpeg 1024w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182134-300x54.jpeg 300w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182134-768x138.jpeg 768w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182134-18x3.jpeg 18w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182134.jpeg 1277w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"168\" src=\"https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182139-1024x168.jpeg\" alt=\"\" class=\"wp-image-3811\" srcset=\"https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182139-1024x168.jpeg 1024w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182139-300x49.jpeg 300w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182139-768x126.jpeg 768w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182139-1536x253.jpeg 1536w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182139-18x3.jpeg 18w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182139.jpeg 1806w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"174\" src=\"https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182150-1024x174.jpeg\" alt=\"\" class=\"wp-image-3808\" srcset=\"https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182150-1024x174.jpeg 1024w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182150-300x51.jpeg 300w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182150-768x131.jpeg 768w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182150-1536x262.jpeg 1536w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182150-18x3.jpeg 18w, https:\/\/imastudio.com\/wp-content\/uploads\/2025\/11\/20251127-182150.jpeg 1879w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Au d\u00e9part, je pensais qu&#039;il s&#039;agissait simplement d&#039;une autre bizarrerie du fabricant, mais apr\u00e8s avoir v\u00e9rifi\u00e9 les changements d&#039;autorisation de stockage sur les diff\u00e9rentes versions d&#039;Android, j&#039;ai r\u00e9alis\u00e9 que je me basais sur un comportement qui avait \u00e9t\u00e9 effectivement d\u00e9pr\u00e9ci\u00e9 sur Android 13 lors du ciblage du SDK 33.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Cause principale\u00a0: Les fonctions WRITE\/READ_EXTERNAL_STORAGE sont obsol\u00e8tes sur Android 13 (SDK 33).<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dans les anciennes versions d&#039;Android, il suffisait de d\u00e9clarer ces deux autorisations dans le manifeste\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>LECTURE_STOCKAGE_EXTERNE<\/code><\/li>\n\n\n\n<li><code>\u00c9CRIRE_STOCKAGE_EXTERNE<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">et les demander ensuite au moment de l&#039;ex\u00e9cution, lorsque cela s&#039;av\u00e8re n\u00e9cessaire.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sur Android 13 (SDK 33) avec <strong>targetSdkVersion = 33<\/strong>, cette approche commence \u00e0 montrer ses limites :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>\u00c9CRIRE_STOCKAGE_EXTERNE<\/code> est <strong>obsol\u00e8te et pratiquement inutile<\/strong> sur les versions r\u00e9centes d&#039;Android<\/li>\n\n\n\n<li>Si vous ajoutez <code>maxSdkVersion=32<\/code> Ces autorisations fonctionnent toujours sur Android 11\/12.<br>mais ils le sont <strong>ignor\u00e9<\/strong> sur Android 13 lors du ciblage de la version 33<\/li>\n\n\n\n<li>Parall\u00e8lement, le Play Store exige que les nouvelles applications ciblent au moins le SDK 33.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Pour Android 11 et versions ult\u00e9rieures, nous devons donc nous adapter \u00e0\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Stockage \u00e0 port\u00e9e limit\u00e9e<\/strong><\/li>\n\n\n\n<li>Et dans certains cas, l&#039;autorisation sp\u00e9ciale\u00a0: <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code><\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/strong> accorde \u00e0 une application un acc\u00e8s \u00e9tendu \u00e0 tout le contenu du stockage partag\u00e9 (y compris les fichiers non multim\u00e9dias). <strong>pas<\/strong> Elle autorise l&#039;acc\u00e8s aux r\u00e9pertoires priv\u00e9s d&#039;autres applications, mais Google Play la consid\u00e8re toujours comme une autorisation tr\u00e8s sensible.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Pour assurer la compatibilit\u00e9 avec les diff\u00e9rentes versions d&#039;Android, j&#039;ai finalement divis\u00e9 la gestion des autorisations en\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Avant Android 11 (API &lt; 30)<\/strong> \u2013 autorisations de stockage externe de style ancien<\/li>\n\n\n\n<li><strong>Android 11 et versions ult\u00e9rieures<\/strong> \u2013 Stockage sous p\u00e9rim\u00e8tre + manutention sp\u00e9ciale avec <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> l\u00e0 o\u00f9 cela est strictement n\u00e9cessaire<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Adaptation \u00e9tape par \u00e9tape<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 D\u00e9clarez MANAGE_EXTERNAL_STORAGE dans le manifeste<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Dans le <code>AndroidManifest.xml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;uses-permission\n    android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"\n    tools:ignore=\"ScopedStorage\" \/><\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f Remarque : Parce que <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> Il s&#039;agit d&#039;une autorisation sensible, restreinte sur Google Play. Je parlerai d&#039;alternatives plus tard si vous souhaitez simplement enregistrer des images.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3.2 V\u00e9rifier si l&#039;autorisation est accord\u00e9e<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">J&#039;ai utilis\u00e9 <strong>EasyPermissions<\/strong> pour simplifier les contr\u00f4les d&#039;autorisation.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private fun checkPer(activity: PreViewActivity): Boolean { return if (Build.VERSION.SDK_INT &gt;= 30) { EasyPermissions.hasPermissions( activity, android.Manifest.permission.MANAGE_EXTERNAL_STORAGE ) } else { EasyPermissions.hasPermissions( activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE ) } }\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sur <strong>Android 11+ (API &gt;= 30)<\/strong>Je v\u00e9rifie <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code><\/li>\n\n\n\n<li>Sur <strong>Android 10 et versions ant\u00e9rieures<\/strong>Je v\u00e9rifie encore. <code>\u00c9CRIRE_STOCKAGE_EXTERNE<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Cette scission est cruciale, car <code>\u00c9CRIRE_STOCKAGE_EXTERNE<\/code> Ne se comporte plus comme sur les versions plus r\u00e9centes.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3.3 Demander l&#039;autorisation lorsqu&#039;elle est manquante<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Si l&#039;autorisation n&#039;est pas accord\u00e9e, je la demande diff\u00e9remment en fonction de la version du syst\u00e8me.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private fun requestStoragePermission(activity: PreViewActivity, curImg: Int) { if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.R) { \/\/ Android 11+ \u2013 redirection vers la page des param\u00e8tres syst\u00e8me \"\u00a0Acc\u00e8s \u00e0 tous les fichiers\u00a0\" val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) intent.data = Uri.parse(&quot;package:&quot; + activity.packageName) activity.startActivityForResult(intent, 200) } else { \/\/ Android 10 et versions ant\u00e9rieures \u2013 autorisation d&#039;ex\u00e9cution normale val perm = android.Manifest.permission.WRITE_EXTERNAL_STORAGE PaperThreeVariable.isToRequestPer = true EasyPermissions.requestPermissions( PermissionRequest.Builder( activity, 200, perm ).build() ) } }\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sur <strong>Android 11+<\/strong>: vous ne pouvez pas simplement \u201c faire appara\u00eetre \u201d une bo\u00eete de dialogue d&#039;ex\u00e9cution normale pour <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code><br>Vous devez rediriger l&#039;utilisateur vers la page des param\u00e8tres syst\u00e8me o\u00f9 il devra autoriser manuellement l&#039;acc\u00e8s \u00e0 \u201c Tous les fichiers \u201d.<\/li>\n\n\n\n<li>Sur <strong>Android 10 et versions ant\u00e9rieures<\/strong>: la bo\u00eete de dialogue d&#039;autorisation d&#039;ex\u00e9cution classique fonctionne toujours.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3.4 G\u00e9rer les rappels d&#039;autorisation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">EasyPermissions permet de faire le lien entre le rappel de l&#039;activit\u00e9 et notre propre logique\u00a0:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>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(&quot;Cette fonction n\u00e9cessite l&#039;activation de l&#039;autorisation de stockage&quot;) .setNegativeButton(&quot;Non&quot;) .setPositiveButton(&quot;Oui&quot;) .build() .show() } }\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pourquoi j&#039;utilise EasyPermissions ici\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Les utilisateurs peuvent <strong>nier d\u00e9finitivement<\/strong> autorisations, ce qui fait que les requ\u00eates r\u00e9p\u00e9t\u00e9es \u00e9chouent silencieusement<\/li>\n\n\n\n<li>EasyPermissions facilite\u00a0:\n<ul class=\"wp-block-list\">\n<li>D\u00e9tecter l&#039;\u00e9tat de \u201c refus permanent \u201d<\/li>\n\n\n\n<li>Afficher une bo\u00eete de dialogue qui guide les utilisateurs vers <strong>Param\u00e8tres syst\u00e8me \u2192 Autorisations des applications<\/strong> activer l&#039;acc\u00e8s au stockage manuellement<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Une fois l&#039;autorisation accord\u00e9e, j&#039;appelle :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>AppInitUtils().saveFreshAppImageToGallery(this, curImg)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">pour enregistrer l&#039;image et actualiser la galerie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Apr\u00e8s cette adaptation, l&#039;appareil Samsung sous Android 13 s&#039;est finalement comport\u00e9 comme les autres.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Remarque : Mon appareil Xiaomi \u00e9tait identifi\u00e9 comme fonctionnant sous Android 13, mais la fonction \u201c\u00a0Historique des appareils connect\u00e9s\u00a0\u201d d\u2019Android Studio le reconnaissait comme fonctionnant sous Android 12. Cela pourrait expliquer pourquoi il fonctionnait encore dans certains cas, mais c\u2019est pr\u00e9cis\u00e9ment pour cette raison que la gestion des autorisations en fonction de la version est importante.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. \u00c0 propos de MANAGE_EXTERNAL_STORAGE et des restrictions de Google Play<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> est puissant :<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Il accorde un acc\u00e8s en lecture\/\u00e9criture \u00e0 <strong>tout stockage partag\u00e9<\/strong> sur l&#039;appareil.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">De ce fait, Google Play le traite comme un <strong>autorisation hautement sensible<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Il est principalement destin\u00e9 \u00e0 <strong>Gestionnaire de fichiers \/ Sauvegarde \/ Antivirus<\/strong> applications de type<\/li>\n\n\n\n<li>Vous devez fournir une justification pour l&#039;utiliser.<\/li>\n\n\n\n<li>Si votre application est une simple application grand public (par exemple, enregistrement d&#039;images, t\u00e9l\u00e9chargements simples), votre requ\u00eate sera tr\u00e8s probablement\u00a0: <strong>rejet\u00e9<\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Donc si votre seule exigence est\u00a0:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u201c Enregistrez une image dans la galerie et rendez-la visible \u00e0 l&#039;utilisateur. \u201d<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">alors vous devriez <strong>Il est fortement conseill\u00e9 d&#039;\u00e9viter<\/strong> <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> et \u00e0 la place\u00a0:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Utiliser <strong>MediaStore<\/strong> ins\u00e9rer des images dans la biblioth\u00e8que multim\u00e9dia du syst\u00e8me<\/li>\n\n\n\n<li>Vous pouvez \u00e9galement utiliser des API capables d&#039;enregistrer des images sans n\u00e9cessiter un acc\u00e8s complet au fichier.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Il existe plusieurs mod\u00e8les \u00e0 :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enregistrez une image dans le r\u00e9pertoire Images\/DCIM<\/li>\n\n\n\n<li>Signalez-le au scanner multim\u00e9dia ou utilisez MediaStore pour que la galerie puisse le r\u00e9cup\u00e9rer.<\/li>\n\n\n\n<li>Faites tout cela <strong>sans demander MANAGE_EXTERNAL_STORAGE<\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Pour la distribution interne ou hors Play Store (par exemple, les boutiques d&#039;applications internes d&#039;entreprise), vous pouvez techniquement toujours utiliser <code>Environnement.getExternalStorageDirectory()<\/code>, mais je ne recommande pas de concevoir une nouvelle application autour de cela en 2025.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. R\u00e9sum\u00e9 version par version (Android 9 \u2192 13)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Pour tout rassembler au m\u00eame endroit, voici un r\u00e9sum\u00e9 g\u00e9n\u00e9ral du comportement du stockage externe et des autorisations selon les versions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Android 9 et versions ant\u00e9rieures (API 28 et ant\u00e9rieures)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Autorisations<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>LECTURE_STOCKAGE_EXTERNE<\/code><\/li>\n\n\n\n<li><code>\u00c9CRIRE_STOCKAGE_EXTERNE<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Comportement<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Les applications peuvent acc\u00e9der librement <code>\/carte SD<\/code> et ses sous-r\u00e9pertoires<\/li>\n\n\n\n<li>Les fichiers cr\u00e9\u00e9s par l&#039;application restent sur l&#039;appareil m\u00eame apr\u00e8s la d\u00e9sinstallation de l&#039;application.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Approche typique<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Lecture\/\u00e9criture directe sous les chemins de stockage externes<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Android 10 (API 29) \u2013 Introduction du stockage limit\u00e9<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Autorisations<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>LECTURE_STOCKAGE_EXTERNE<\/code> fonctionne toujours<\/li>\n\n\n\n<li><code>\u00c9CRIRE_STOCKAGE_EXTERNE<\/code> Elle existe toujours, mais sa port\u00e9e effective est r\u00e9duite.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Comportement<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>Stockage \u00e0 port\u00e9e limit\u00e9e<\/strong> est introduit :\n<ul class=\"wp-block-list\">\n<li>Les applications sont limit\u00e9es \u00e0 leur propre r\u00e9pertoire sp\u00e9cifique sous<br><code>Android\/data\/votre.nom.de.package\/<\/code><\/li>\n\n\n\n<li>L&#039;acc\u00e8s direct aux fichiers des autres applications est restreint.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Les fichiers multim\u00e9dias (images, vid\u00e9os, audio) doivent \u00eatre accessibles via <strong>MediaStore<\/strong><\/li>\n\n\n\n<li><code>requestLegacyExternalStorage=true<\/code> pourrait temporairement conserver les anciens comportements<br>(mais cet indicateur est ignor\u00e9 \u00e0 partir d&#039;Android 11)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Approche recommand\u00e9e<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Pour les images\/vid\u00e9os\/audio\u00a0: utilisez <strong>MediaStore<\/strong><\/li>\n\n\n\n<li>Pour les fichiers priv\u00e9s\u00a0: utilisez <code>obtenirExternalFilesDir()<\/code> ou <code>obtenirDataDir()<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Android 11 (API 30) \u2013 Stockage limit\u00e9 impos\u00e9<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Autorisations<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>LECTURE_STOCKAGE_EXTERNE<\/code> Cela fonctionne, mais uniquement pour les m\u00e9dias g\u00e9r\u00e9s par MediaStore.<\/li>\n\n\n\n<li><code>\u00c9CRIRE_STOCKAGE_EXTERNE<\/code> est effectivement <strong>obsol\u00e8te<\/strong> pour le stockage externe g\u00e9n\u00e9ral<\/li>\n\n\n\n<li><code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> introduit pour des cas d&#039;utilisation sp\u00e9cifiques d&#039;\u201c acc\u00e8s \u00e0 tous les fichiers \u201d.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Comportement<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>requestLegacyExternalStorage=true<\/code> ne fonctionne plus\u00a0; le stockage limit\u00e9 est <strong>toujours allum\u00e9<\/strong><\/li>\n\n\n\n<li>Acc\u00e8s \u00e0 <code>\/carte SD\/<\/code> L&#039;acc\u00e8s root est bloqu\u00e9.<\/li>\n\n\n\n<li>Les applications peuvent uniquement\u00a0:\n<ul class=\"wp-block-list\">\n<li>Acc\u00e9der \u00e0 leurs propres r\u00e9pertoires priv\u00e9s<\/li>\n\n\n\n<li>Acc\u00e9der aux m\u00e9dias partag\u00e9s via <strong>MediaStore<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Approche recommand\u00e9e<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Pour les applications classiques\u00a0:\n<ul class=\"wp-block-list\">\n<li>Utilisez MediaStore ou <strong>SAF<\/strong> (<code>ACTION_OUVRIR_DOCUMENT<\/code>, <code>ACTION_CR\u00c9ER_DOCUMENT<\/code>) pour les fichiers s\u00e9lectionn\u00e9s par l&#039;utilisateur<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Consid\u00e9rer uniquement <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> si votre application est v\u00e9ritablement un gestionnaire de fichiers, un outil de sauvegarde, une application de s\u00e9curit\u00e9, etc.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Android 13 (API 33) \u2013 Division des autorisations multim\u00e9dias<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Autorisations<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>LIRE_IMAGES_M\u00c9DIAS<\/code> \u2013 acc\u00e9der aux images<\/li>\n\n\n\n<li><code>LIRE_M\u00c9DIA_VID\u00c9O<\/code> \u2013 acc\u00e9der aux vid\u00e9os<\/li>\n\n\n\n<li><code>LIRE_M\u00c9DIA_AUDIO<\/code> \u2013 acc\u00e9der \u00e0 l&#039;audio<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Comportement<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Les autorisations m\u00e9dias sont <strong>\u00e0 grains fins<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Les utilisateurs peuvent autoriser uniquement l&#039;acc\u00e8s aux images, uniquement l&#039;acc\u00e8s aux vid\u00e9os, etc.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Les r\u00e8gles de stockage limit\u00e9 d&#039;Android 11 restent en place.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Approche recommand\u00e9e<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Demandez les autorisations m\u00e9dias sp\u00e9cifiques dont vous avez besoin\u00a0:\n<ul class=\"wp-block-list\">\n<li>Par exemple, si vous travaillez uniquement avec des images, demandez uniquement <code>LIRE_IMAGES_M\u00c9DIAS<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Faire <strong>pas<\/strong> demande <code>LECTURE_STOCKAGE_EXTERNE<\/code> sur Android 13+, car elle est remplac\u00e9e par les nouvelles autorisations multim\u00e9dias<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Matrice rapide (conceptuelle)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Android 9 et versions ant\u00e9rieures<\/strong>\n<ul class=\"wp-block-list\">\n<li>L&#039;acc\u00e8s au stockage externe est \u00e9tendu et contr\u00f4l\u00e9 par READ\/WRITE_EXTERNAL_STORAGE.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Android 10<\/strong>\n<ul class=\"wp-block-list\">\n<li>Le stockage \u00e0 port\u00e9e limit\u00e9e a \u00e9t\u00e9 introduit, mais il existe des issues de secours (<code>requestLegacyExternalStorage<\/code>)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Android 11<\/strong>\n<ul class=\"wp-block-list\">\n<li>Le stockage limit\u00e9 est impos\u00e9, les commutateurs h\u00e9rit\u00e9s sont supprim\u00e9s.<\/li>\n\n\n\n<li><code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> appara\u00eet, mais est tr\u00e8s restreint.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Android 13<\/strong>\n<ul class=\"wp-block-list\">\n<li>L&#039;acc\u00e8s aux m\u00e9dias divis\u00e9 en <code>LIRE_M\u00c9DIA_*<\/code> autorisations<\/li>\n\n\n\n<li>M\u00eames r\u00e8gles de stockage limit\u00e9, mais contr\u00f4le utilisateur plus pr\u00e9cis<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Points cl\u00e9s<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ne pr\u00e9sumez pas que \u201c cela fonctionne sur un appareil Android 13 \u201d signifie que cela fonctionne partout ; les rapports des fabricants et des syst\u00e8mes peuvent \u00eatre incoh\u00e9rents.<\/li>\n\n\n\n<li>Pour <strong>Android 11+<\/strong>, pensez en termes de :\n<ul class=\"wp-block-list\">\n<li><strong>R\u00e9pertoires priv\u00e9s d&#039;applications + MediaStore + SAF<\/strong>, pas \u201c cru \u00bb <code>\/carte SD<\/code> acc\u00e9der&quot;\u201d<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Traiter <code>G\u00c9RER_LE_STOCKAGE_EXTERNE<\/code> comme un <strong>dernier recours<\/strong> pour des types d&#039;applications tr\u00e8s sp\u00e9cifiques, notamment si vous pr\u00e9voyez de publier sur Google Play.<\/li>\n\n\n\n<li>Toujours tester sur <strong>plusieurs appareils et versions Android<\/strong>, notamment en ce qui concerne les autorisations et le stockage.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Cet article est issu de mes propres d\u00e9bogages et adaptations sur des projets Android r\u00e9els (dont un appareil Samsung sous Android 13). GPT a uniquement contribu\u00e9 \u00e0 la traduction et \u00e0 la reformulation\u00a0; l\u2019ensemble du contenu technique et des d\u00e9cisions sont de ma responsabilit\u00e9.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n<\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Lorsque j&#039;ai tent\u00e9 de mettre en \u0153uvre une fonctionnalit\u00e9 tr\u00e8s simple (t\u00e9l\u00e9charger une image et l&#039;enregistrer dans le stockage local), tout semblait fonctionner correctement au d\u00e9part. M\u00eame code, m\u00eame fonctionnalit\u00e9, mais un appareil sous Android 13 refusait tout simplement d&#039;afficher la demande d&#039;autorisation. C&#039;est ainsi que cette petite t\u00e2che de \u201c\u00a0t\u00e9l\u00e9chargement d&#039;image\u00a0\u201d s&#039;est transform\u00e9e en une exploration approfondie de [\u2026]<\/p>","protected":false},"author":10,"featured_media":3804,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"","rank_math_description":"","footnotes":""},"categories":[35],"tags":[],"class_list":["post-3803","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-knowledge-hub"],"_links":{"self":[{"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/posts\/3803","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/comments?post=3803"}],"version-history":[{"count":4,"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/posts\/3803\/revisions"}],"predecessor-version":[{"id":3812,"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/posts\/3803\/revisions\/3812"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/media\/3804"}],"wp:attachment":[{"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/media?parent=3803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/categories?post=3803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/imastudio.com\/fr\/wp-json\/wp\/v2\/tags?post=3803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}