Resolver problemas de serviços em primeiro plano

Nesta página, discutimos alguns motivos comuns para falhas em serviços em primeiro plano e ajudamos você a identificar o que está causando o problema.

Neste documento, discutimos os seguintes problemas:

Antes de resolver problemas

Verificar mudanças recentes nos serviços em primeiro plano

Se os serviços em primeiro plano forem usados de forma inadequada, eles podem ter efeitos negativos no desempenho do dispositivo e na duração da bateria. Por esse motivo, as versões da plataforma Android costumam fazer mudanças no comportamento do serviço em primeiro plano para limitar esses efeitos negativos.

Se você estiver com problemas com os serviços em primeiro plano, consulte a documentação sobre as mudanças nos serviços em primeiro plano e verifique se há mudanças recentes que possam explicar seus problemas. É particularmente importante verificar se há mudanças nestas circunstâncias:

  • O código do serviço em primeiro plano que funcionava antes agora está falhando
  • Você acabou de começar a testar uma nova versão da plataforma ou mudou o nível da API de destino do app.

Além disso, se você estiver testando o dispositivo em uma prévia para desenvolvedores da plataforma, confira a versão mais recente da documentação da prévia para desenvolvedores.

Erros do tipo "O app não está respondendo" (ANR)

Em algumas circunstâncias, é esperado que um app encerre o serviço em primeiro plano. Se o app não interromper o serviço, o sistema vai fazer isso e acionar um erro O app não está respondendo (ANR).

O serviço curto é executado por muito tempo, causando um ANR

Os serviços em primeiro plano que usam o tipo short service precisam ser concluídos rapidamente, em cerca de três minutos. Quando o tempo acaba, o sistema chama o método Service.onTimeout(int,int) do serviço. O serviço tem alguns segundos para chamar stopSelf(). Se o serviço não for interrompido, o sistema vai acionar um erro "O app não está respondendo".

Diagnóstico:

Se o ANR foi causado por um serviço em primeiro plano que não foi interrompido, o sistema vai gerar uma exceção interna. Para verificar se esse foi o problema, consulte os relatórios de ANR. Se esse for o problema, o relatório vai incluir a seguinte mensagem:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type FOREGROUND_SERVICE_TYPE_SHORT_SERVICE did not stop within its timeout:
[component name]"

Correção:

Verifique se todos os serviços em primeiro plano com limite de tempo concluem o trabalho e chamam stopForeground(int) dentro do limite de tempo do sistema.

Faça com que os serviços em primeiro plano implementem Service.onTimeout(int,int). Verifique se a implementação desse método chama stopSelf() imediatamente.

Exceções de serviço em primeiro plano

Esta seção descreve vários problemas de serviço em primeiro plano que podem fazer com que o sistema gere uma exceção. Se o app não capturar a exceção, o usuário vai receber uma caixa de diálogo informando que o app parou.

Em alguns casos, o sistema gera uma exceção interna. Nesses casos, é possível descobrir qual foi a exceção analisando o stack trace e verificar o Logcat para mais informações detalhadas sobre o erro.

Exceção interna: tempo limite excedido

O sistema impõe um limite ao tempo de execução dos serviços em primeiro plano de sincronização de dados e processamento de mídia enquanto o app está em segundo plano. Se o serviço exceder esse limite, o sistema vai chamar o método Service.onTimeout(int,int) do serviço. O serviço tem alguns segundos para chamar stopSelf(). Se o serviço não for interrompido, o sistema vai gerar uma RemoteServiceException interna, fazendo com que o app falhe.

Diagnóstico:

Para descobrir qual foi a exceção, procure no stack trace. Confira o Logcat para mais informações detalhadas sobre o erro. Nesse caso, o Logcat tem a seguinte mensagem de erro:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"

Correção:

Verifique se todos os serviços em primeiro plano com limite de tempo concluem o trabalho e chamam stopForeground(int) dentro do limite de tempo do sistema.

Faça com que os serviços em primeiro plano implementem Service.onTimeout(int,int). Verifique se a implementação desse método chama stopSelf() imediatamente.

Exceção interna: ForegroundServiceDidNotStartInTimeException

Quando você inicia um serviço chamando context.startForegroundService(), ele tem alguns segundos para se promover a um serviço em primeiro plano chamando ServiceCompat.startForeground(). Se o serviço não fizer isso, o gera um ForegroundServiceDidNotStartInTimeException interno.

Diagnóstico:

Para descobrir qual foi a exceção, procure no stack trace. Confira o Logcat para mais informações detalhadas sobre o erro. Nesse caso, o Logcat tem a seguinte mensagem de erro:

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()

Correção:

Verifique se todos os serviços em primeiro plano recém-criados chamam ServiceCompat.startForeground() em alguns segundos.

WorkManager:

Você também pode ver essa exceção com workers do WorkManager que executam um serviço em primeiro plano (chamam setForegound ou setForegroundAsync). Quando o ciclo de vida de dois workers em primeiro plano se sobrepõe, enquanto um worker tenta iniciar um serviço em primeiro plano enquanto um serviço em primeiro plano em execução anteriormente tenta ser encerrado, essa falha é acompanhada pelo seguinte registro:

Re-initializing SystemForegroundService after a request to shut-down

Uma correção para essa falha foi introduzida na versão 2.10.5 do WorkManager.

Se o app estiver encontrando essa exceção, atualize para a versão mais recente do WorkManager e informe qualquer problema persistente no Issue Tracker do WorkManager.

ForegroundServiceStartNotAllowedException

Erro:

O sistema gera ForegroundServiceStartNotAllowedException.

Causa:

Isso geralmente é causado pelo app que inicia um serviço em primeiro plano em segundo plano quando não há uma isenção válida.

No Android 12 (nível 31 da API) e versões mais recentes, os apps não podem iniciar serviços em primeiro plano enquanto estão em execução em segundo plano, com algumas exceções específicas. Se você tentar iniciar um serviço em primeiro plano em segundo plano e não atender aos requisitos de uma das isenções, o sistema vai gerar ForegroundServiceStartNotAllowedException. O sistema também fará isso se você não atender aos requisitos da isenção.

Por exemplo, um app pode ter um botão que o usuário pode clicar, o que faz com que o app faça algum processamento e, em seguida, inicie um serviço em primeiro plano. Nesse caso, há o perigo de o usuário clicar no botão e colocar o app em segundo plano imediatamente. O app tentaria iniciar o serviço em segundo plano. Se o app não atender a uma das isenções especificadas, o sistema vai gerar uma ForegroundServiceStartNotAllowedException.

Além disso, algumas isenções têm um limite de tempo curto. Por exemplo, há uma breve isenção se o app inicia um serviço em primeiro plano em resposta a uma mensagem FCM de alta prioridade. Se você não iniciar o serviço com rapidez suficiente, vai receber um ForegroundServiceStartNotAllowedException.

Algumas isenções específicas podem se tornar mais restritivas com as novas versões do Android. Se você mudou a versão do Android que seu app segmenta, confira a documentação sobre mudanças nos serviços em primeiro plano e confirme se o app ainda atende a uma das isenções permitidas.

Correção:

Mude o fluxo de trabalho do app para que ele não precise iniciar serviços em primeiro plano enquanto estiver em segundo plano ou confirme se o app atende a uma das isenções.

É possível usar componentes que reconhecem o ciclo de vida para gerenciar o ciclo de vida do app e evitar que você tente iniciar um serviço em primeiro plano em segundo plano.

SecurityException

Erro:

O sistema gera SecurityException.

Causa:

O app tentou iniciar um serviço em primeiro plano sem ter as permissões necessárias.

  • Se um app for destinado ao Android 9 (nível 28 da API) ou versões mais recentes, ele precisará ter a permissão FOREGROUND_SERVICE para iniciar um serviço em primeiro plano.
  • Se um app for direcionado ao Android 14 (nível 34 da API) ou versões mais recentes, ele precisará atender a todos os pré-requisitos do tipo de serviço em primeiro plano. Esses pré-requisitos estão detalhados na documentação sobre tipos de serviço em primeiro plano. Em especial, esteja ciente dos seguintes requisitos:
    • Vários tipos de serviço em primeiro plano exigem permissões de execução específicas. Por exemplo, um serviço em primeiro plano de mensagens remotas precisa ter a permissão FOREGROUND_SERVICE_REMOTE_MESSAGING.
  • Em vários casos, há outras restrições durante o uso nas permissões necessárias para alguns tipos de serviço em primeiro plano. Essas permissões são concedidas ao app apenas enquanto ele está em primeiro plano (com algumas exceções específicas). Isso significa que, mesmo que o app tenha solicitado e recebido uma dessas permissões, se ele tentar iniciar o serviço em primeiro plano enquanto estiver em segundo plano, o sistema vai gerar uma SecurityException, mesmo que o app tenha uma isenção para iniciar um serviço em primeiro plano em segundo plano. Para mais informações, consulte Restrições para iniciar serviços em primeiro plano que precisam de permissões durante o uso.
    • Você poderá receber um SecurityException se tiver solicitado as permissões necessárias, mas iniciar o serviço em primeiro plano antes de confirmar que as permissões necessárias foram concedidas.

Correção:

Antes de iniciar o serviço em primeiro plano, solicite todas as permissões adequadas e confirme se você atendeu a todos os outros pré-requisitos de execução.