Guia de adaptação de permissões de armazenamento do Android para Android 11+

Resumir com IA

Quando tentei implementar um requisito muito simples — Baixe uma imagem e salve-a no armazenamento local. — No início, tudo parecia bem.

  • Honor (Android 10) – funciona
  • Redmi (Android 11) – funciona
  • Xiaomi (Android 13) – funciona
  • Samsung (Android 13) – Falhou completamente: a caixa de diálogo de permissão de armazenamento nunca aparecia.

Mesmo código, mesma funcionalidade, mas um dispositivo com Android 13 simplesmente se recusou a exibir a solicitação de permissão. Foi assim que essa pequena tarefa de "baixar imagem" se transformou em uma investigação profunda sobre... Armazenamento com escopo e GERENCIAR ARMAZENAMENTO EXTERNO.

Esta postagem resume como adaptei as permissões de armazenamento para Android 11 e superior, E como lido com os diferentes comportamentos entre as versões.


1. O bug: a caixa de diálogo de permissão de armazenamento nunca é exibida (Samsung Android 13)

O requisito é simples:

Baixe uma imagem e salve-a no dispositivo para que ela apareça na galeria.

Nos meus três dispositivos de teste:

  • Honor – Android 10 → OK
  • Redmi – Android 11 → OK
  • Xiaomi – Android 13 → OK

Mas em um Dispositivo Samsung com Android 13, o sistema A caixa de diálogo de permissão de armazenamento nunca foi exibida., não importa como eu tenha pedido.

A princípio, pensei que fosse apenas mais uma peculiaridade do fabricante, mas depois de verificar as alterações nas permissões de armazenamento entre as versões do Android, percebi que estava dependendo de um comportamento que havia sido efetivamente descontinuado no Android 13 ao usar o SDK 33 como alvo.


2. Causa raiz: as permissões WRITE/READ_EXTERNAL_STORAGE foram descontinuadas no Android 13 (SDK 33).

Em versões mais antigas do Android, podíamos simplesmente declarar essas duas permissões no manifesto:

  • LER_ARMAZENAMENTO_EXTERNO
  • GRAVAR_ARMAZENAMENTO_EXTERNO

e depois solicitá-los em tempo de execução quando necessário.

No Android 13 (SDK 33) com targetSdkVersion = 33, essa abordagem começa a falhar:

  • GRAVAR_ARMAZENAMENTO_EXTERNO é obsoleto e efetivamente inútil em versões recentes do Android
  • Se você adicionar maxSdkVersion=32 Com essas permissões, elas ainda funcionam no Android 11/12.
    mas eles são ignorado no Android 13 ao direcionar para 33
  • Ao mesmo tempo, a Play Store exige que os novos aplicativos sejam compatíveis com pelo menos o SDK 33.

Portanto, para o Android 11 e versões posteriores, precisamos nos adaptar a:

  • Armazenamento com escopo
  • E, em alguns casos, a permissão especial: GERENCIAR ARMAZENAMENTO EXTERNO

GERENCIAR ARMAZENAMENTO EXTERNO Concede a um aplicativo amplo acesso a todo o conteúdo do armazenamento compartilhado (incluindo arquivos que não sejam de mídia). não Permitir o acesso aos diretórios privados de outros aplicativos ainda é considerado uma permissão altamente sensível pelo Google Play.

Para dar suporte a diferentes versões do Android, acabei dividindo o gerenciamento de permissões em:

  • Antes do Android 11 (API < 30) – permissões de armazenamento externo no estilo antigo
  • Android 11 e superior – Armazenamento com escopo definido + manuseio especial com GERENCIAR ARMAZENAMENTO EXTERNO onde for estritamente necessário

3. Adaptação passo a passo

3.1 Declare MANAGE_EXTERNAL_STORAGE no manifesto.

No AndroidManifest.xml:

<uses-permission
    android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

⚠️ Observação: Porque GERENCIAR ARMAZENAMENTO EXTERNO É uma permissão sensível, restrita no Google Play. Falarei sobre alternativas mais tarde, caso você queira apenas salvar imagens.


3.2 Verificar se a permissão foi concedida

Eu usei Permissões fáceis Para simplificar as verificações de permissão.

função privada 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 ) } }
  • Sobre Android 11+ (API >= 30): Eu verifico GERENCIAR ARMAZENAMENTO EXTERNO
  • Sobre Android 10 e versões anterioresEu ainda verifico GRAVAR_ARMAZENAMENTO_EXTERNO

Essa divisão é crucial, porque GRAVAR_ARMAZENAMENTO_EXTERNO Não se comporta mais da mesma forma que nas versões mais recentes.


3.3 Solicitar permissão quando ela estiver ausente

Caso a permissão não seja concedida, eu a solicito de forma diferente, dependendo da versão do sistema.

private fun requestStoragePermission(activity: PreViewActivity, curImg: Int) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // Android 11+ – redirecionar para a página de configurações do sistema "Acesso a todos os arquivos" 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 e versões anteriores – permissão de tempo de execução normal val perm = android.Manifest.permission.WRITE_EXTERNAL_STORAGE PaperThreeVariable.isToRequestPer = true EasyPermissions.requestPermissions( PermissionRequest.Builder( activity, 200, perm ).build() ) } }
  • Sobre Android 11+Você não pode simplesmente "abrir" uma caixa de diálogo normal em tempo de execução para GERENCIAR ARMAZENAMENTO EXTERNO
    Você deve enviar o usuário para a página de configurações do sistema, onde ele concederá manualmente o acesso a "Todos os arquivos".
  • Sobre Android 10 e versões anterioresA caixa de diálogo clássica de permissão em tempo de execução ainda funciona.

3.4 Gerenciar retornos de chamada de permissão

O EasyPermissions ajuda a fazer a ponte entre o retorno de chamada da Activity e a nossa própria lógica:

sobrescreva a função 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("Esta função requer que a permissão de armazenamento esteja habilitada") .setNegativeButton("Não") .setPositiveButton("Sim") .build() .show() } }

Por que eu uso o EasyPermissions aqui:

  • Os usuários podem negar permanentemente permissões, o que faz com que solicitações repetidas falhem silenciosamente
  • O EasyPermissions facilita:
    • Detectar estado de “negação permanente”
    • Exibir uma caixa de diálogo que oriente os usuários a Configurações do sistema → permissões do aplicativo para habilitar o acesso ao armazenamento manualmente

Assim que a permissão for concedida, eu ligo:

AppInitUtils().saveFreshAppImageToGallery(this, curImg)

Para salvar a imagem e atualizar a galeria.

Após essa adaptação, o dispositivo Samsung com Android 13 finalmente passou a se comportar da mesma forma que os demais.

Observação: Meu dispositivo Xiaomi foi reportado como Android 13, mas o recurso "dispositivos conectados históricos" do Android Studio o reconheceu como Android 12. Isso pode explicar por que ainda funcionou em alguns casos — mas é exatamente por isso que o gerenciamento de permissões com reconhecimento de versão é importante.


4. Sobre MANAGE_EXTERNAL_STORAGE e restrições do Google Play

GERENCIAR ARMAZENAMENTO EXTERNO é poderoso:

Concede acesso de leitura/gravação a todo o armazenamento compartilhado no dispositivo.

Por isso, o Google Play o trata como um permissão altamente confidencial:

  • É destinado principalmente a gerenciador de arquivos / backup / antivírus aplicativos de tipo
  • Você precisa apresentar uma justificativa para usá-lo.
  • Se o seu aplicativo for apenas um aplicativo típico para o consumidor (por exemplo, salvar imagens, downloads simples), sua solicitação provavelmente será rejeitado

Portanto, se sua única exigência for:

“Salvar uma imagem na galeria e torná-la visível para o usuário.”

então você deveria Considere seriamente evitar GERENCIAR ARMAZENAMENTO EXTERNO e em vez disso:

  • Usar MediaStore Para inserir imagens na biblioteca de mídia do sistema.
  • Ou utilize APIs que podem salvar imagens sem exigir acesso total ao arquivo.

Existem vários padrões para:

  • Salvar imagem no diretório Pictures/DCIM
  • Avise o scanner de mídia ou utilize o MediaStore para que a galeria possa detectar o arquivo.
  • Faça tudo isso sem solicitar MANAGE_EXTERNAL_STORAGE

Para distribuição interna ou fora da Play Store (por exemplo, lojas de aplicativos internas de empresas), tecnicamente você ainda pode usar Ambiente.obterDiretórioDeArmazenamentoExterno(), Mas não recomendo desenvolver um novo aplicativo com base nisso em 2025.


5. Resumo versão por versão (Android 9 → 13)

Para reunir tudo em um só lugar, aqui está um resumo geral de como o armazenamento externo e as permissões se comportam em diferentes versões.

Android 9 e versões anteriores (API 28 e anteriores)

  • Permissões:
    • LER_ARMAZENAMENTO_EXTERNO
    • GRAVAR_ARMAZENAMENTO_EXTERNO
  • Comportamento:
    • Os aplicativos podem acessar livremente /sdcard e seus subdiretórios
    • Os arquivos criados pelo aplicativo permanecem no dispositivo mesmo após a desinstalação do aplicativo.
  • Abordagem típica:
    • Leitura/gravação direta em caminhos de armazenamento externo

Android 10 (API 29) – Introdução do armazenamento com escopo

  • Permissões:
    • LER_ARMAZENAMENTO_EXTERNO ainda funciona
    • GRAVAR_ARMAZENAMENTO_EXTERNO Ainda existe, mas seu alcance efetivo foi reduzido.
  • Comportamento:
    • Armazenamento com escopo é apresentado:
      • Os aplicativos ficam restritos ao seu próprio diretório específico, em
        Android/data/nome.do.pacote/
      • O acesso direto aos arquivos de outros aplicativos é restrito.
    • Os arquivos de mídia (imagens, vídeos, áudio) devem ser acessados através de MediaStore
    • solicitarArmazenamentoExternoLegado=true poderia manter temporariamente o comportamento antigo
      (mas essa flag é ignorada a partir do Android 11)
  • Abordagem recomendada:
    • Para imagens/vídeos/áudio: use MediaStore
    • Para arquivos privados: use obterDiretórioDeArquivosExternos() ou obterDiretórioDeDados()

Android 11 (API 30) – Armazenamento com escopo imposto

  • Permissões:
    • LER_ARMAZENAMENTO_EXTERNO Funciona, mas apenas para mídias gerenciadas pelo MediaStore.
    • GRAVAR_ARMAZENAMENTO_EXTERNO é efetivamente obsoleto para armazenamento externo geral
    • GERENCIAR ARMAZENAMENTO EXTERNO Introduzido para casos de uso especiais de "acesso a todos os arquivos".
  • Comportamento:
    • solicitarArmazenamentoExternoLegado=true Não funciona mais; o armazenamento com escopo é sempre ligado
    • Acesso a /sdcard/ O root está bloqueado
    • Os aplicativos só podem:
      • Acesse seus próprios diretórios privados
      • Acesse mídias compartilhadas através de MediaStore
  • Abordagem recomendada:
    • Para aplicações típicas:
      • Use o MediaStore ou SAF (AÇÃO_ABRIR_DOCUMENTO, AÇÃO_CRIAR_DOCUMENTO) para arquivos selecionados pelo usuário
    • Considere apenas GERENCIAR ARMAZENAMENTO EXTERNO Se o seu aplicativo for realmente um gerenciador de arquivos, ferramenta de backup, aplicativo de segurança, etc.

Android 13 (API 33) – Divisão de Permissões de Mídia

  • Permissões:
    • LEIA_IMAGENS_DE_MÍDIA – acessar imagens
    • LEIA_MÍDIA_VÍDEO – acessar vídeos
    • LER_MÍDIA_ÁUDIO – acessar áudio
  • Comportamento:
    • As permissões de mídia são de grão fino:
      • Os usuários podem conceder acesso somente a imagens, somente a vídeos, etc.
    • As regras de armazenamento com escopo do Android 11 permanecem em vigor.
  • Abordagem recomendada:
    • Solicite as permissões de mídia específicas de que você precisa:
      • Por exemplo, se você trabalha apenas com imagens, solicite apenas LEIA_IMAGENS_DE_MÍDIA
    • Fazer não solicitar LER_ARMAZENAMENTO_EXTERNO No Android 13+, ele foi substituído pelas novas permissões de mídia.

Matriz Rápida (Conceitual)

  • Android 9 e versões anteriores
    • O acesso ao armazenamento externo é amplo e controlado por READ/WRITE_EXTERNAL_STORAGE.
  • Android 10
    • O armazenamento com escopo foi introduzido, mas existem saídas de emergência (solicitarArmazenamentoExternoLegado)
  • Android 11
    • O armazenamento com escopo foi implementado e os switches legados foram removidos.
    • GERENCIAR ARMAZENAMENTO EXTERNO Aparece, mas é altamente restrito.
  • Android 13
    • O acesso à mídia foi dividido em LEIA_MÍDIA_* permissões
    • As mesmas regras de armazenamento com escopo, mas com controle de usuário mais detalhado.

6. Principais conclusões

  • Não assuma que "funciona em um dispositivo Android 13" significa que funcionará em todos os lugares; os fabricantes de equipamentos originais (OEMs) e os relatórios do sistema podem ser inconsistentes.
  • Para Android 11+, Pense em termos de:
    • Diretórios privados de aplicativos + MediaStore + SAF, não “cru” /sdcard acesso"”
  • Tratar GERENCIAR ARMAZENAMENTO EXTERNO como um último recurso Para tipos de aplicativos muito específicos, especialmente se você planeja publicar no Google Play.
  • Sempre teste em múltiplos dispositivos e versões do Android, especialmente no que diz respeito a permissões e armazenamento.

Este artigo é fruto da minha própria experiência de depuração e adaptação em projetos reais de Android (incluindo um dispositivo Samsung com Android 13). O GPT apenas auxiliou na tradução e no aprimoramento do texto; todo o conteúdo técnico e as decisões são de minha autoria.

Sobre o autor

Compartilhar publicação:

Mantenha-se conectado

Mais atualizações

Como criar anúncios com IA para lançamentos de produtos com imagens do produto, variações de anúncios e fluxo de trabalho de campanhas de e-commerce.

Como criar anúncios com IA para lançamentos de produtos

O lançamento de produtos acontece rapidamente. Assim que o produto estiver pronto, a equipe precisa de explicações sobre o produto, anúncios pagos em redes sociais, peças criativas para a semana de lançamento, recursos visuais para a página de destino, variantes de remarketing e muito mais.