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 executados em segundo plano. Essas restrições ajudam a minimizar as interrupções para o usuário e a manter o controle do que é mostrado na tela.

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

Mostrar notificações

Em quase todos os casos, os apps em segundo plano precisam mostrar notificações urgentes para fornecer informações importantes ao usuário em vez de iniciar uma atividade diretamente. Essas notificações incluem o tratamento de uma chamada telefônica recebida ou um despertador ativo.

Esse sistema de alertas e lembretes com base em notificações oferece várias vantagens para os usuários:

  • Ao usar o dispositivo, o usuário recebe uma notificação de alerta que permite responder. O usuário mantém o contexto atual e tem controle sobre o conteúdo que aparece 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 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, o usuário pode controlar as preferências de notificação.

Quando os apps podem iniciar atividades

Os apps executados no Android 10 ou versões mais recentes podem iniciar atividades quando uma ou mais das seguintes condições forem atendidas:

  • O app tem uma janela visível, como uma atividade em primeiro plano.

  • O app tem uma atividade na backstack da tarefa de primeiro plano.

  • O app tem uma atividade na backstack de uma tarefa na tela Recentes.

  • O app tem uma atividade que foi 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 no backstack da tarefa de primeiro plano no momento em que finish() é 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 uma PendingIntent enviada de um app visível diferente.

  • O app recebe uma transmissão do sistema em que o app precisa iniciar uma interface. Exemplos incluem ACTION_NEW_OUTGOING_CALL e SECRET_CODE_ACTION. O app 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 CompanionDeviceManager API. 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 bem como 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 Activity 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 do app para o início de Activity.

Os apps direcionados ao Android 15 ou versões mais recentes não concederão mais privilégios de inicialização de atividades em segundo plano (BAL, na sigla em inglês) implicitamente às PendingIntents que criam. A ativação explícita é necessária. Para isso, estas são 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 direcionados ao Android 14 ou versões mais recentes que querem iniciar uma PendingIntent precisam

  • atender às condições listadas e
  • ativar a inicialização de atividades em segundo plano com base nessas exceções

Essa ativação acontece se o desenvolvedor de apps souber que o app vai iniciar uma atividade.

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

Pelo criador da PendingIntent

Os apps direcionados ao Android 15 ou versões mais recentes que criam uma PendingIntent agora precisam ativar explicitamente a inicialização de atividades em segundo plano se quiserem que essas PendingIntents possam ser iniciadas nas condições listadas.

Na maioria dos casos, o app que inicia a PendingIntent precisa ser ativado. No entanto, se o app de criação precisar conceder essas permissões:

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

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

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

Modo estrito

A partir do Android 16, o desenvolvedor de apps pode ativar o modo estrito para receber uma notificação quando uma inicialização de atividade for bloqueada (ou estiver em risco de ser bloqueada quando o SDK de destino do app for 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.