Hibernação do app

Se o app for direcionado ao Android 11 (nível 30 da API) ou versões mais recentes e o usuário não interagir com o app por alguns meses, o aplicativo vai ser colocado em um estado de hibernação pelo sistema. O sistema otimiza o espaço de armazenamento em vez da performance e protege os dados do usuário. Esse comportamento do sistema é semelhante ao que ocorre quando o usuário força o fechamento manual do app nas configurações do sistema.

Efeitos da hibernação

Conforme mostrado na tabela 1, os efeitos da hibernação dependem da versão do SDK de destino do app e do dispositivo em que ele está sendo executado:

Tabela 1. Efeitos da hibernação no app
Versão do SDK de destino Características do dispositivo Efeitos de hibernação
Android 12 ou versão mais recente Executa o Android 12 ou mais recente

As permissões de execução do app são redefinidas. Essa ação tem o mesmo efeito que se o usuário tivesse aberto uma permissão nas configurações do sistema e mudado o nível de acesso do app para Negar.

O app não pode executar tarefas ou alertas em segundo plano.

O app não recebe notificações push, incluindo mensagens de alta prioridade que são enviadas pelo Firebase Cloud Messaging.

Todos os arquivos no cache do app são removidos.

Android 11 Executa o Android 11 As permissões de execução do app são redefinidas.
Android 11 Executa o Android 10 (nível 29 da API) ou uma versão anterior, até a mínima, que é o Android 6.0 (nível 23 da API), e usa tecnologias do Google Play Services.

As permissões de execução do app são redefinidas.

Esse comportamento vai entrar em vigor em dezembro de 2021. Saiba mais nesta postagem do blog sobre como disponibilizar a redefinição automática de permissões para bilhões de dispositivos (link em inglês).

Comportamento do sistema quando um app sai da hibernação

Quando o usuário interage com o app, ele sai da hibernação e pode criar jobs, alertas e notificações novamente.

No entanto, o sistema não faz o seguinte no app:

  1. Reatribui permissões de execução do app.

    O usuário precisa conceder essas permissões novamente ao aplicativo.

  2. Reprograma todos os jobs, alertas e notificações que foram agendados antes da hibernação do app.

    Para facilitar esse fluxo de trabalho, use o WorkManager. Também é possível adicionar a lógica de reprogramação no broadcast receiver ACTION_BOOT_COMPLETED, que é invocada quando o app sai da hibernação e após a inicialização do dispositivo.

Uso de apps

As próximas seções apresentam exemplos de uso do app e de ações que o sistema não considera como sendo de uso dele.

Exemplos de uso de apps

Quando uma atividade no app é retomada, o sistema considera esse evento como uma interação do usuário. O sistema estende o período antes que o app entre em hibernação.

No Android 11 e versões mais recentes, os comportamentos abaixo também são considerados como interações do usuário:

  • O usuário interage com um widget.
  • O usuário interage com uma notificação. Dispensar a notificação não é considerado uma interação.

Para hibernação, o uso de apps não exige explicitamente a interação do usuário. Desde que um componente do pacote seja invocado, o sistema registra o uso do app. Alguns exemplos são:

  • Apps que têm um serviço ou provedor de conteúdo vinculado por outro app no dispositivo ou no SO. Por exemplo, Editores de método de entrada (IME, na sigla em inglês) ou gerenciadores de senhas.
  • Broadcast receivers no pacote que recebem uma transmissão explícita de um pacote externo.

Outros exemplos

Se o app só realiza os comportamentos descritos na lista abaixo, ele vai entrar em hibernação após alguns meses:

Isenções de hibernação concedidas pelo sistema

O Android concede isenções de hibernação do app no nível do sistema em determinados casos de uso. Se o app se enquadrar em uma das categorias abaixo, ele fica isento dos padrões de uso do app e não vai entrar em hibernação.

Apps não mostrados na tela de início
Qualquer app que não tenha um bloco de atalho ativo na tela de início.
Apps do perfil de trabalho
Qualquer app instalado por um usuário em um perfil de trabalho. Se o mesmo app também estiver em um perfil pessoal, apenas o app do perfil de trabalho vai ficar isento.
Controladores de política do dispositivo
Apps que controlam políticas de dispositivos locais e aplicativos do sistema em dispositivos.
Apps privilegiados da operadora
Qualquer app pré-carregado por operadoras de celular em dispositivos e considerados necessários para obrigações contratuais de serviço, como apps de correio de voz ou atendimento ao cliente.
Apps instaladores de terceiros
Lojas de apps de terceiros armazenam atualizações automáticas dos apps instalados quando necessário.

Isenções de hibernação concedidas pelo usuário

Se você prevê que um caso de uso do app vai ser afetado pela hibernação, envie ao usuário um pedido de exceção. Essa isenção é útil em situações em que o usuário espera que o app funcione, principalmente em segundo plano, mesmo que não interaja com ele, por exemplo, quando o app realiza uma destas ações:

  • Fornecer segurança familiar, informando periodicamente a localização dos membros da família.
  • Sincronizar dados entre um dispositivo e o servidor do app.
  • Comunicar-se com dispositivos inteligentes, como uma TV.
  • Parear com dispositivos complementares, como um smartwatch.

Para solicitar uma isenção, siga as etapas nas próximas seções.

Verificar se o usuário já desativou a hibernação do app

Para verificar se o usuário já desativou a hibernação do seu app, use a API getUnusedAppRestrictionsStatus().

Para mais detalhes sobre como usar essa API no seu app, consulte o exemplo de código da API nesta página.

Pedir ao usuário para desativar a hibernação do app

Se o usuário ainda não tiver desativado a hibernação do app, envie uma solicitação a ele. Para fazer isso, siga estas etapas:

  1. Mostre uma IU que explique ao usuário por que é necessário desativar a hibernação do app.
  2. Invoque a API createManageUnusedAppRestrictionsIntent(), conforme mostrado no exemplo de código. Essa API cria uma intent que carrega a tela de Informações do app nas configurações. Aqui, o usuário pode desativar a hibernação do app.

    É importante chamar startActivityForResult(), não startActivity(), ao enviar essa intent.

    Conforme mostrado na tabela 2, o local e o nome da opção dependem das características do dispositivo em que o app está instalado:

    Tabela 2. Opção que desativa a hibernação do app
    Características do dispositivo Página em que a opção é mostrada Nome da opção de desativar
    Executa o Android 13 ou mais recente Informações do app Pausar atividade no app quando não usado
    Executa o Android 12 Informações do app Remover permissões e liberar espaço
    Executa o Android 11 Informações do app > Permissões Remover permissões se o app não for usado
    Executa o Android 6.0 ou mais recente, até a versão máxima do Android 10, inclusive, e usa tecnologias do Google Play Services App Play > Menu > Play Protect > Permissões de apps não usados Remover permissões se o app não for usado

Exemplo de código da API

O exemplo de código abaixo mostra como verificar se a hibernação está ativada no app e a maneira correta de pedir que os usuários a desativem.

Kotlin

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener({ onResult(future.get()) }, ContextCompat.getMainExecutor(context))

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Couldn't fetch status. Check logs for details.
    ERROR -> { }

    // Restrictions don't apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }

    // The user has disabled restrictions for your app.
    DISABLED -> { }

    // If the user doesn't start your app for a few months, the system will
    // place restrictions on it. See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to
  // the user explaining why permission auto-reset or app hibernation should be
  // disabled. Then, redirect the user to the page in system settings where they
  // can disable the feature.
  val intent = IntentCompat.createManageUnusedAppRestrictionsIntent(context, packageName)

  // You must use startActivityForResult(), not startActivity(), even if
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

API da plataforma legada

O sistema operacional também inclui uma API para interagir com o recurso de hibernação. No entanto, a API só funciona em dispositivos com o Android 11 ou mais recente. A API não processa os recursos de hibernação compatíveis com versões anteriores do Android. Portanto, não recomendamos usar essa API.

Se você precisa continuar usando a API temporariamente para fins de compatibilidade, a lista abaixo mostra como fazer isso:

Invocar manualmente o comportamento de hibernação

Para testar como o app se comporta depois que o sistema o coloca em um estado de hibernação, siga estas etapas:

  1. (Somente Android 12 e versões mais recentes) Ative o comportamento de hibernação no dispositivo:

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. Defina o período padrão que o sistema espera para entrar em hibernação. Dessa forma, você pode restaurá-lo após o teste:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  3. Reduza o tempo de espera do sistema. No exemplo abaixo, o sistema é modificado para que o app entre em hibernação apenas um segundo depois que você parar de interagir com ele:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. Aguarde até que as transmissões durante a inicialização sejam concluídas no dispositivo de teste executando este comando:

    adb shell am wait-for-broadcast-idle
    

    Quando as transmissões forem concluídas, este comando vai retornar a mensagem: All broadcast queues are idle!

  5. Invoque o processo de hibernação do app manualmente:

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  6. (Somente Android 12 e versões mais recentes) Confirme se o app entra em hibernação usando um dos métodos abaixo:

    • O dispositivo de teste agora mostra uma notificação, indicando que apps não usados são colocados em hibernação.
    • Execute este comando:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. Restaure o tempo padrão que o sistema aguarda antes de colocar o app em hibernação:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold