android.os.FileUriExposedException: file:///... exposed beyond app through Intent.getData() significa que o aplicativo enviou um URI file:// para fora do próprio processo por meio de um Intent ou de outro fluxo entre aplicativos. O Android lança essa exceção de diagnóstico para aplicativos direcionados ao Android N/API 24 ou superior. A primeira ação mais segura é inspecionar os dados do Intent, EXTRA_STREAM, ClipData e qualquer URI de saída da câmera em busca do valor file:// restante antes de alterar as configurações do provedor.
O que significa android.os.FileUriExposedException
A exceção se aplica à exposição de arquivos entre aplicativos, não a todas as falhas de acesso a arquivos no Android. Ela costuma aparecer em fluxos de ACTION_VIEW, ACTION_SEND, ACTION_SEND_MULTIPLE, captura pela câmera, anexos, impressão e compartilhamento.
A exceção foi adicionada no nível 24 da API e é lançada para aplicativos direcionados ao Android N ou superior. A versão do Android no dispositivo e o targetSdkVersion do aplicativo são condições relacionadas, mas não são equivalentes. A referência de FileUriExposedException do Android identifica como substituição compatível um URI content:// com acesso temporário para o aplicativo receptor.
A ausência da exceção em outra configuração de SDK não torna seguro o compartilhamento por file://. O Android descreve a exceção como um recurso de diagnóstico, e não como um mecanismo de segurança por si só.
Localize o URI file:// que está saindo do aplicativo
Quando isto se aplica: faça esta inspeção antes de configurar o FileProvider, inclusive quando a mensagem terminar com Intent.getData() ou ClipData.Item.getUri().
Pré-requisitos: o texto da exceção e o código-fonte do fluxo de saída do Intent.
- Inspecione o URI exibido na exceção e confirme se o esquema é
file. - Analise os quadros do aplicativo imediatamente anteriores à exceção para localizar onde o URI de saída é criado ou anexado.
- Procure por
Uri.fromFile()e pela análise de valores iniciados porfile://. - Inspecione separadamente os dados do Intent,
EXTRA_STREAM, cada item deClipDatae qualquer URI de saída da câmera. - Registre a origem e o local real do arquivo. Esses detalhes determinam se é apropriado usar um URI autorizado existente ou o FileProvider.
Resultado esperado: você identifica todos os URIs file:// no fluxo com falha e o ponto em que cada URI entra no Intent.
Risco e aviso: esta é uma etapa de diagnóstico somente leitura. Não presuma que alterar apenas os dados do Intent será suficiente se outro campo que aceite URI continuar inalterado. A presença de ClipData deve ser confirmada pela inspeção do Intent real.
Escolha a origem correta do URI de conteúdo
Quando esta correção se aplica: use este caminho quando a origem já fornecer um URI content:// autorizado, como um documento selecionado pelo usuário ou um item de mídia compartilhada.
Pré-requisitos: confirme se o URI existente continua autorizado para a operação pretendida.
- Preserve o URI
content://existente em vez de convertê-lo em um caminho do sistema de arquivos. - Use o Framework de acesso ao armazenamento para documentos selecionados pelo usuário.
- Use um URI apropriado do MediaStore para mídia compartilhada.
- Coloque o URI autorizado no campo obrigatório do Intent e prossiga para as verificações de permissões temporárias abaixo.
Resultado esperado: o fluxo entre aplicativos mantém um URI content:// autorizado sem introduzir um novo FileProvider.
Risco e reversão: o risco é baixo. Se a origem não puder fornecer um URI autorizado adequado à operação, use o FileProvider somente quando o aplicativo for o proprietário do arquivo. Não converta todos os caminhos pelo FileProvider por padrão.
Configure o AndroidX FileProvider no manifesto
Quando esta correção se aplica: use o AndroidX FileProvider quando o aplicativo for o proprietário de um arquivo e precisar disponibilizá-lo a outro aplicativo.
Pré-requisitos: o AndroidX FileProvider deve estar disponível, você deve ter controle sobre o manifesto e deve conseguir criar um recurso XML de caminhos do provedor. A autoridade exata é específica de cada aplicativo.
- Declare um provedor cujo
android:nameseja FileProvider ou a subclasse de FileProvider do aplicativo. - Defina
android:authoritiescomo uma autoridade específica do aplicativo. - Defina
android:exported="false". - Defina
android:grantUriPermissions="true". - Adicione a entrada de metadados do FileProvider que faça referência ao recurso XML de caminhos do provedor.
- Confirme se a autoridade usada posteriormente para gerar o URI corresponde exatamente à autoridade declarada no manifesto.
A documentação do AndroidX FileProvider oferece suporte a esse modelo de provedor e às permissões temporárias de URI.
Resultado esperado: o aplicativo tem um provedor não exportado capaz de gerar URIs content:// autorizados para os arquivos configurados.
Risco e reversão: o risco é baixo. Remova o provedor e seus metadados se o recurso de compartilhamento for removido. Não publique nem copie um valor de autoridade universal, pois ele deve corresponder à configuração do aplicativo.
Restrinja o XML file_paths aos arquivos que precisam ser compartilhados
Quando esta correção se aplica: conclua esta etapa sempre que o FileProvider for usado.
Pré-requisitos: conheça o diretório exato que contém o arquivo que precisa ser compartilhado.
- Defina somente o diretório ou os diretórios exigidos pelo recurso de compartilhamento.
- Prefira o diretório mais restrito que ainda contenha o arquivo pretendido.
- Evite raízes amplas que incluam arquivos não relacionados do aplicativo ou do armazenamento compartilhado.
- Antes de gerar o URI de conteúdo, verifique se o arquivo é resolvido dentro de uma das raízes configuradas.
A entrada XML exata não pode ser universal porque depende do local em que o aplicativo armazena o arquivo. As alterações de exposição de URI de arquivo do Android 7.0 recomendam a migração para o FileProvider em vez da continuidade da exposição de URIs de arquivo.
Resultado esperado: o FileProvider consegue resolver o arquivo pretendido, enquanto os locais não relacionados permanecem fora do escopo configurado do provedor.
Risco e reversão: o risco é médio porque uma raiz excessivamente ampla pode expor mais arquivos do que o pretendido. Restrinja o XML de caminhos se a análise ou os testes mostrarem uma cobertura excessiva; não amplie os caminhos apenas para contornar uma falha de raiz configurada.
Substitua file:// e conceda somente o acesso temporário necessário
Crie e anexe o URI de conteúdo do FileProvider
Quando esta correção se aplica: use-a depois de configurar a autoridade no manifesto e os caminhos restritos do provedor para um arquivo pertencente ao aplicativo.
Pré-requisitos: o arquivo deve estar dentro de uma raiz permitida do provedor, e a autoridade usada para gerar o URI deve corresponder à do manifesto.
- Crie o URI com o FileProvider em vez de usar
Uri.fromFile()ou um valorfile://construído manualmente. - Coloque o URI
content://resultante nos dados do Intent, emEXTRA_STREAMou no campo de saída da câmera exigido pelo fluxo existente. - Para vários arquivos, substitua todos os URIs expostos, e não apenas o primeiro item.
- Inspecione
ClipDatae qualquer outro campo que aceite URI para garantir que o URI de arquivo antigo não permaneça em outro local.
Resultado esperado: o Intent de saída transporta URIs content:// do FileProvider em vez de URIs file://.
Risco e reversão: o risco é baixo, e esta operação não exclui o arquivo. Não restaure o compartilhamento entre aplicativos por file:// em produção; a origem anterior do URI é adequada apenas para depuração local isolada que não exponha o URI.
Conceda permissões temporárias de URI
Quando esta correção se aplica: use concessões temporárias quando o aplicativo receptor precisar ler ou modificar o conteúdo referenciado pelo Intent.
Pré-requisitos: o Intent deve transportar um URI content:// válido, e o nível de acesso exigido pelo receptor deve ser conhecido.
- Adicione
FLAG_GRANT_READ_URI_PERMISSIONquando o receptor precisar ler o arquivo. - Adicione
FLAG_GRANT_WRITE_URI_PERMISSIONsomente quando o receptor precisar modificar o arquivo. - Anexe o URI por meio de
ClipDataquando isso for necessário para propagar a permissão no fluxo compatível. - Não adicione permissões mais amplas do sistema de arquivos nem acesso de gravação não relacionado à operação.
Resultado esperado: o receptor obtém o acesso temporário mínimo necessário enquanto o provedor permanece não exportado.
Risco e reversão: o risco é baixo quando o acesso é limitado. Remova os sinalizadores de concessão de leitura ou gravação quando o receptor não precisar mais dessa capacidade. A propagação por ClipData depende do fluxo e deve ser testada nas versões compatíveis do Android.
Verifique se o aplicativo receptor consegue acessar o URI de conteúdo
Quando isto se aplica: verifique o fluxo completo depois de substituir o URI e aplicar as concessões temporárias.
Pré-requisitos: o componente receptor pretendido deve estar disponível para testes.
- Confirme se todos os URIs de saída usam o esquema
content. - Confirme se a autoridade do URI gerado corresponde exatamente à autoridade do provedor declarada no manifesto.
- Confirme se o arquivo está dentro de uma raiz configurada do provedor.
- Verifique novamente os dados do Intent,
EXTRA_STREAM,ClipDatae os URIs de saída em busca de qualquer valorfile://restante. - Teste o aplicativo receptor real com permissão de leitura e adicione permissão de gravação somente se for necessário modificar o arquivo.
- Confirme se o receptor consegue realizar a operação pretendida sem ampliar a raiz do provedor ou as permissões.
Resultado esperado: o fluxo de saída deixa de expor um URI de arquivo, e o componente receptor consegue acessar o URI de conteúdo autorizado com a concessão mínima necessária. Isso deve ser confirmado por testes; apenas alterar o esquema não garante o acesso do receptor.
Risco e aviso: a verificação apresenta baixo risco. Se a exceção original desaparecer, mas o acesso continuar falhando, verifique manualmente a autoridade, os metadados do provedor, os caminhos configurados, as concessões de URI e o local real do arquivo. Não desative a detecção com StrictMode.VmPolicy, não reduza o targetSdkVersion, não exponha raízes amplas e não conceda acesso de gravação por padrão. Essas ações ocultam ou enfraquecem o problema em vez de corrigir o projeto de compartilhamento entre aplicativos.

