Restrições ao iniciar atividades a partir do segundo plano

O Android 10 (nível 29 da API) e versões mais recentes impõem restrições quanto ao momento em que os apps podem iniciar atividades quando são executados em segundo plano. Essas restrições ajudam a minimizar as interrupções para o usuário e dão a ele mais controle sobre o que é exibido na tela.

Este guia apresenta as notificações como uma alternativa para iniciar atividades em segundo plano. Ela também lista os casos específicos em que a restrição não se aplica.

Exibir notificações

Em quase todos os casos, os apps em segundo plano precisam mostrar notificações urgentes para fornecer informações urgentes ao usuário em vez de iniciar uma atividade diretamente. Essas notificações incluem atender uma ligação ou um despertador ativo.

Esse sistema de alerta e lembrete baseado em notificações oferece diversas vantagens para os usuários:

  • Ao usar o dispositivo, o usuário recebe uma notificação de alerta que permite que ele responda. O usuário mantém o contexto atual e tem controle sobre o conteúdo exibido na tela.
  • As notificações urgentes respeitam as regras de Não perturbe do usuário. Por exemplo, quando a opção "Não perturbe" está ativada, os usuários podem permitir chamadas apenas de contatos específicos ou de chamadas repetidas.
  • Quando a tela do dispositivo está desligada, o intent de tela cheia é iniciado imediatamente.
  • Na tela Configurações do dispositivo, o usuário pode ver quais apps enviaram notificações recentemente, inclusive de canais de notificação específicos. Nessa tela, ele pode controlar as preferências de notificação.

Quando os apps podem iniciar atividades

Os apps que operam no Android 10 ou versões mais recentes podem iniciar atividades quando uma ou mais das condições a seguir forem atendidas:

  • O app tem uma janela visível, como uma atividade em primeiro plano.
  • O app tem uma atividade na pilha de retorno da tarefa em primeiro plano.
  • O app tem uma atividade na backstack de uma tarefa na tela Recentes.

  • O app tem uma atividade iniciada muito recentemente.

  • O app chamou finish() em uma atividade muito recentemente. Isso se aplica somente quando o app tem uma atividade em primeiro plano ou uma atividade na pilha de retorno da tarefa de primeiro plano no momento em que finish() foi chamado.

  • O app tem um dos seguintes serviços vinculados pelo sistema. Esses serviços podem precisar iniciar uma interface.

  • O app tem um serviço vinculado por um app visível diferente. O app vinculado ao serviço precisa permanecer visível para que o app em segundo plano inicie as atividades.

  • O app recebe uma notificação PendingIntent do sistema. No caso de intents pendentes para serviços e broadcast receivers, o app pode iniciar atividades por alguns segundos após o envio do intent pendente.

  • O app recebe um PendingIntent enviado de um app visível diferente.

  • O app recebe uma transmissão do sistema em que precisa iniciar uma interface. Os exemplos incluem ACTION_NEW_OUTGOING_CALL e SECRET_CODE_ACTION. O aplicativo pode iniciar atividades por alguns segundos após o envio da transmissão.

  • O app está associado a um dispositivo de hardware complementar por meio da API CompanionDeviceManager. Essa API permite que o app inicie atividades em resposta a ações que o usuário realiza em um dispositivo pareado.

  • O app é um controlador de política de dispositivo em execução no modo de proprietário do dispositivo. Exemplos de casos de uso incluem dispositivos corporativos totalmente gerenciados e dispositivos dedicados, como sinalização digital e quiosques.

  • O usuário concede a permissão SYSTEM_ALERT_WINDOW ao app.

Ativação necessária ao iniciar atividades de PendingIntents

Para evitar o início acidental de atividades com base nas condições listadas, a partir do Android 14, há APIs explícitas que permitem ativar ou desativar a concessão de permissões de um app para o início de atividades.

Os apps destinados ao Android 15 ou versões mais recentes não vão mais conceder implicitamente privilégios de início de atividade em segundo plano (BAL, na sigla em inglês) aos PendingIntents que eles criam. É necessário ativar explicitamente. Para isso, confira as opções dependendo se o app está enviando ou criando PendingIntents.

Tabela de intents pendentes
Figura 1: fluxo de decisão para inicializações de atividades em segundo plano.

Pelo remetente da PendingIntent

Os apps destinados ao Android 14 ou a versões mais recentes que querem iniciar um PendingIntent precisam

  • atender às condições listadas e
  • ativar para permitir o início de atividades em segundo plano com base nessas exceções.

Essa ativação deve acontecer se o desenvolvedor do app souber que ele vai iniciar uma atividade.

Para ativar o recurso, o app precisa transmitir um pacote ActivityOptions com setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) para o PendingIntent.send() ou métodos semelhantes.

Pelo criador da PendingIntent

Os apps destinados ao Android 15 ou versões mais recentes que criam um PendingIntent agora precisam ativar explicitamente o início de atividades em segundo plano se quiserem que esses PendingIntents possam ser iniciados nas condições listadas.

Na maioria dos casos, o app que inicia o PendingIntent precisa ativar a opção. No entanto, se o app criador precisar conceder esses privilégios:

  • O PendingIntent pode ser iniciado a qualquer momento em que o app de criação estiver visível.
  • O PendingIntent pode ser iniciado a qualquer momento se o app de criação tiver privilégios especiais.

Para ativar o recurso, o app precisa transmitir um pacote ActivityOptions com setPendingIntentCreatorBackgroundActivityStartMode (ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) para os métodos PendingIntent.getActivity() ou semelhantes.

Leia a documentação de referência relevante para mais detalhes:

Modo restrito

A partir do Android 16, o desenvolvedor de apps pode ativar o modo estrito para receber notificações quando o início de uma atividade é bloqueado (ou corre o risco de ser bloqueado quando o SDK de destino do app é aumentado).

Exemplo de código para ativar no início do método Application.onCreate() do aplicativo, da atividade ou de outro componente do aplicativo:

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     StrictMode.setVmPolicy(
         StrictMode.VmPolicy.Builder()
         .detectBlockedBackgroundActivityLaunch()
         .penaltyLog()
         .build());
     )
 }

Leia a documentação do modo estrito para mais detalhes.