Esta página discute alguns motivos comuns para a falha dos serviços em primeiro plano e ajuda a identificar a causa do problema.
Neste documento, discutimos os seguintes problemas:
Antes de resolver problemas
Verificar mudanças recentes nos serviços em primeiro plano
Se forem usados de maneira inadequada, eles podem afetar negativamente o desempenho do dispositivo e a duração da bateria. Por isso, as versões da plataforma Android costumam fazer mudanças no comportamento dos serviços em primeiro plano para limitar esses efeitos negativos.
Se você estiver com problemas com serviços em primeiro plano, confira a documentação sobre mudanças nos serviços em primeiro plano e verifique se há mudanças recentes que possam explicar seus problemas. É especialmente 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 em uma nova versão da plataforma ou mudou o nível da API segmentado pelo 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 determinadas circunstâncias, espera-se 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 vai acionar um erro O app não está respondendo (ANR).
Um serviço curto é executado por muito tempo, causando um ANR
Os serviços em primeiro plano que usam o tipo serviço curto
precisam ser concluídos rapidamente, em cerca de três minutos. Quando o tempo acabar, 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
parar sozinho, o sistema vai acionar um erro de "O app não está respondendo".
Diagnóstico:
Se o ANR foi causado por um serviço em primeiro plano que não conseguiu se interromper, o sistema vai gerar uma exceção interna. Para verificar se esse foi o problema, confira 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 terminam o trabalho e chamam
stopForeground(int)
dentro do limite de tempo do sistema.
Faça com que seus 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
Nesta seção, descrevemos 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 ver uma caixa de diálogo informando que o app parou.
Em alguns casos, o sistema gera uma exceção interna. Nesses casos, é possível consultar o rastreamento de pilha para saber qual foi a exceção e verificar o Logcat para informações mais detalhadas sobre o erro.
Exceção interna: tempo limite excedido
O sistema impõe um limite de quanto tempo os serviços em primeiro plano de sincronização de dados e processamento de mídia podem ser executados 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 um
RemoteServiceException
interno, causando a falha do app.
Diagnóstico:
Para saber qual foi a exceção, consulte o stack trace e verifique o Logcat para informações mais 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 terminam o trabalho e chamam
stopForeground(int)
dentro do limite de tempo do sistema.
Faça com que seus 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, ele vai gerar um
ForegroundServiceDidNotStartInTimeException
interno.
Diagnóstico:
Para saber qual foi a exceção, consulte o stack trace e verifique o Logcat para informações mais 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.
ForegroundServiceStartNotAllowedException
Erro:
O sistema gera ForegroundServiceStartNotAllowedException
.
Causa:
Isso geralmente é causado pelo app ao iniciar um serviço em primeiro plano em segundo plano quando não há uma exceção válida.
A partir do Android 12 (nível 31 da API), os apps não podem iniciar
serviços em primeiro plano enquanto são executados 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 faz isso se você não atender aos requisitos da isenção.
Por exemplo, um app pode ter um botão em que o usuário pode clicar, o que faz com que o
app faça algum processamento e inicie um serviço em primeiro plano. Nesse caso, há o risco de o usuário clicar no botão e colocar o app em segundo plano imediatamente. Em seguida, 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 iniciar um serviço em primeiro plano
em resposta a uma mensagem do FCM de alta prioridade. Se você não iniciar o serviço
rápido o suficiente, vai receber um ForegroundServiceStartNotAllowedException
.
Algumas isenções específicas às vezes se tornam mais restritivas com novas versões do Android. Se você mudou a versão do Android para a qual seu app está direcionado, confira a documentação sobre mudanças nos serviços em primeiro plano e confirme se o app ainda atende a uma das exenções permitidas.
Correção:
Mude o fluxo de trabalho do app para que ele não precise iniciar serviços em primeiro plano enquanto o app está em segundo plano ou confirme se o app atende a uma das exceções.
Você pode usar componentes com reconhecimento de ciclo de vida para gerenciar o ciclo de vida do app e evitar tentar iniciar um serviço em primeiro plano por engano em segundo plano.
SecurityException
Erro:
O sistema gera SecurityException
.
Causa:
O app tentou iniciar um serviço em primeiro plano sem 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á da permissão
FOREGROUND_SERVICE
para iniciar um serviço em primeiro plano. - Se um app for destinado 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 são detalhados na documentação sobre tipos de serviço em primeiro plano. Em
particular, esteja ciente dos seguintes requisitos:
- Vários tipos de serviço em primeiro plano exigem permissões específicas de execução. Por exemplo, um serviço em primeiro plano de mensagens remotas precisa ter a permissão
FOREGROUND_SERVICE_REMOTE_MESSAGING
.
- Vários tipos de serviço em primeiro plano exigem permissões específicas de execução. Por exemplo, um serviço em primeiro plano de mensagens remotas precisa ter a permissão
- Em vários casos, há outras restrições de uso em
permissões necessárias para alguns tipos de serviços em primeiro plano. Essas permissões são concedidas ao app apenas quando 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 exceçã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 de uso.- Você pode 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 foram concedidas.
- Você pode receber um
Correção:
Antes de iniciar o serviço em primeiro plano, solicite todas as permissões adequadas e confirme se você atende a todos os outros pré-requisitos de tempo de execução.