O que significa “android:exported needs to be explicitly specified”

“Manifest merger failed: Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined.” significa que o manifesto final contém uma atividade, um serviço ou um receptor de transmissão com um filtro de intent, mas sem uma configuração de acesso explícita. Isso se aplica quando o app é destinado ao Android 12/API 31 ou posterior.

As mensagens equivalentes para <activity>, <service> ou <receiver> indicam o mesmo problema. android:exported controla se outros apps podem iniciar esse componente. Não defina o valor como true apenas para a compilação passar. Primeiro, identifique o componente exato e o manifesto de origem na saída mesclada. Consulte o requisito do Android 12 para componentes exportados.

Este guia se limita a atividades, serviços e receptores com filtros de intent. Provedores de conteúdo não são uma variante equivalente comum desse erro do Android 12.

Encontre o componente com falha e o manifesto responsável

Use a saída do mesclador de manifestos antes de alterar o manifesto do app. A entrada afetada pode vir do módulo do app, de uma variante de compilação, de um módulo de teste, de um manifesto gerado ou de uma dependência de terceiros.

  1. Abra o AndroidManifest.xml do módulo afetado no Android Studio.
  2. Selecione Merged Manifest.
  3. Selecione a atividade, o serviço ou o receptor afetado.
  4. Use Merging Log e Manifest Sources para identificar o manifesto que o fornece.
  5. Se necessário, consulte o relatório de compilação do mesclador de manifestos.
  6. Corrija o manifesto responsável ou use uma regra de mesclagem específica de prioridade mais alta somente quando os pré-requisitos forem atendidos.

Resultado esperado: você sabe o tipo do componente, o nome dele e a origem do manifesto responsável pelo atributo ausente ou conflitante. Isso apresenta baixo risco e não exige reversão em tempo de execução; reverta apenas uma alteração no manifesto se a validação posterior falhar. O Android documenta a visualização mesclada, os registros, as origens, os relatórios e os marcadores de mesclagem na documentação sobre gerenciamento de arquivos de manifesto.

Escolha o valor correto de android:exported

Para um componente que você controla ou pode editar, adicione um valor explícito ao manifesto responsável, recompile a variante afetada e inspecione o manifesto mesclado final.

Finalidade do componente Valor adequado Motivo
Atividade inicial do app android:exported="true" O iniciador é um ponto de entrada externo para o app.
Atividade, serviço ou receptor intencionalmente externo android:exported="true" Use somente quando outro app precisar invocá-lo.
Serviço somente interno android:exported="false" Impede acesso externo desnecessário.
Receptor somente interno android:exported="false" Impede acesso externo desnecessário.
  1. Abra o manifesto responsável pelo componente afetado.
  2. Adicione android:exported="true" somente quando apps externos precisarem alcançá-lo.
  3. Adicione android:exported="false" quando ele for apenas interno.
  4. Recompile a variante afetada.
  5. Confirme que o Merged Manifest final mantém o valor revisado.

Risco: baixo para a edição do manifesto, mas definir true expõe o componente ao acesso externo. Filtros de intent, por si só, não fornecem controle de acesso suficiente para um componente exposto. Revise as implicações de segurança usando a orientação sobre segurança de componentes Android exportados. Para reverter, remova ou altere apenas o atributo adicionado e recompile.

Corrija o caso da atividade MAIN e LAUNCHER

Se a atividade afetada tiver um filtro de intent contendo MAIN e LAUNCHER, ela será o ponto de entrada do app e normalmente deverá declarar android:exported="true".

  1. Encontre a atividade com o filtro de intent MAIN e LAUNCHER.
  2. Defina android:exported="true" nessa atividade.
  3. Compile o app.
  4. Instale ou execute o app e verifique se o ícone no iniciador abre a atividade pretendida.

Resultado esperado: a atividade inicial tem um estado de exportação explícito e continua podendo ser iniciada. Isso não resolve uma falha distinta identificada para um serviço ou receptor. O risco é baixo; restaure a declaração anterior somente se a atividade deixar de ser um ponto de entrada pelo iniciador.

Se o componente vier de uma dependência, módulo de teste ou manifesto gerado

Se o Merged Manifest mostrar que outra entrada é responsável pelo componente, não presuma que o manifesto principal do app é o local correto para editar. Diagnose a dependência real que contribui com ele, a biblioteca transitiva, o módulo de teste, a variante de compilação ou o manifesto gerado.

Opção cautelosa: se a origem parecer obsoleta, verifique se há uma atualização de dependência compatível antes de manter uma substituição local. Uma atualização pode remover ou corrigir a declaração, mas isso não é garantido e deve ser testado na variante afetada. Confirme que os recursos necessários da dependência continuam funcionando e que o manifesto mesclado final contém o valor pretendido.

Não remova um componente fornecido apenas para eliminar o erro. Ele pode ser necessário para um recurso da biblioteca.

Use uma substituição específica do mesclador de manifestos somente quando necessário

Use uma substituição somente depois que o Merged Manifest comprovar que um manifesto de prioridade inferior define o mesmo componente e existe um conflito real no atributo exported. A declaração de prioridade mais alta deve identificar o mesmo componente por android:name.

Substitua um valor de exported revisado

  1. Declare o namespace tools no manifesto de prioridade mais alta.
  2. Declare o componente correspondente com o valor de android:exported pretendido.
  3. Use tools:replace="android:exported" somente em caso de conflito real de atributo.
  4. Inspecione o Merged Manifest para confirmar o resultado.
  5. Recompile e teste o caminho de entrada pretendido do componente.

Risco: médio. Uma substituição pode alterar o acesso externo ao componente. Para reverter, remova a declaração de substituição do componente e tools:replace, depois recompile.

Remova um componente de biblioteca comprovadamente desnecessário

  1. Verifique se o componente não é necessário para a dependência ou para um recurso do app.
  2. Adicione uma declaração de componente correspondente no manifesto de prioridade mais alta.
  3. Aplique tools:node="remove" a esse componente.
  4. Inspecione o Merged Manifest para confirmar a remoção.
  5. Compile o app e teste os recursos da dependência que possam usar o componente removido.

Risco: médio. Remover um componente pode interromper o comportamento da biblioteca. Para reverter, remova a declaração tools:node="remove" e recompile.

Verifique a correção no manifesto final e no comportamento do app

  • Confirme que o Merged Manifest mostra um valor explícito e revisado de android:exported no componente afetado.
  • Compile a variante afetada com sucesso.
  • Teste o caminho de entrada pretendido: iniciador, deep link, serviço ou comportamento do receptor, conforme aplicável.
  • Se uma entrada de dependência foi alterada, teste os recursos da dependência que podem invocar ou depender desse componente.
  • Para um componente acessível externamente, revise manualmente se os chamadores precisam de proteção por permissão ou validação do chamador além do estado exported.

Uma compilação bem-sucedida confirma que o requisito de mesclagem foi atendido; ela não comprova, por si só, que o componente é seguro ou se comporta conforme o esperado. O compartilhamento de URIs de arquivo é uma questão distinta de controle de acesso: siga a orientação para compartilhar arquivos com FileProvider em vez de expor URIs de arquivo, em vez de exportar componentes de forma ampla. Da mesma forma, erros da política de segurança de rede do Android são diferentes desta falha do mesclador de manifestos.

Perguntas frequentes

Devo definir android:exported=”true” para corrigir este erro?

Não. Use true somente quando outros apps precisarem invocar o componente. Use false para atividades, serviços e receptores somente internos e, em seguida, verifique a saída mesclada.

Por que o erro continua depois que alterei minha atividade inicial?

O componente com falha pode ser outra atividade, um serviço ou um receptor, ou pode vir de uma dependência, módulo de teste, variante ou manifesto gerado. Consulte o Merged Manifest e suas origens.

Posso usar tools:replace=”android:exported”?

Somente quando um manifesto de prioridade mais alta definir o mesmo componente e houver um conflito real no atributo exported. Inspecione o resultado mesclado final e teste o caminho de entrada pretendido do componente.