Os serviços em primeiro plano realizam operações que são perceptíveis pelo usuário.
Os serviços em primeiro plano mostram uma notificação da barra de status para informar aos usuários que o app está realizando uma tarefa em primeiro plano e consumindo recursos do sistema.
Exemplos de apps que usam serviços em primeiro plano:
- Um app de player de música que toca músicas em um serviço em primeiro plano. A notificação pode mostrar a música que está tocando no momento.
- Um app fitness registra a corrida de um usuário em um serviço em primeiro plano, depois de receber permissão. A notificação pode mostrar a distância que o usuário percorreu durante a sessão de condicionamento físico atual.
Use um serviço em primeiro plano somente quando o app precisar executar uma tarefa perceptível pelo usuário, mesmo que ele não esteja interagindo diretamente com o app. Se a ação for tão importante que você queira usar uma notificação de prioridade mínima, crie uma tarefa em segundo plano.
Este documento descreve a permissão necessária para usar serviços em primeiro plano e como iniciar um serviço em primeiro plano e removê-lo do segundo plano. Ela também descreve como associar determinados casos de uso a tipos de serviço em primeiro plano e as restrições de acesso que entram em vigor quando você inicia um serviço desse tipo usando um app em execução em segundo plano.
O usuário pode dispensar a notificação por padrão
No Android 13 (nível 33 da API), os usuários podem dispensar a notificação associada a um serviço em primeiro plano por padrão. Para fazer isso, os usuários executam um gesto de deslizar na notificação. Tradicionalmente, a notificação não é dispensada, a menos que o serviço em primeiro plano seja interrompido ou removido do primeiro plano.
Se você quiser que a notificação não seja dispensável pelo usuário, transmita
true
para o método setOngoing()
ao criar a notificação usando Notification.Builder
.
Serviços que mostram uma notificação imediatamente
Se um serviço em primeiro plano tiver pelo menos uma das características a seguir, o sistema mostrará a notificação associada imediatamente após o início do serviço, mesmo em dispositivos com o Android 12 ou mais recente:
- O serviço está associado a uma notificação que inclui botões de ação.
- O serviço tem um
foregroundServiceType
demediaPlayback
,mediaProjection
ouphoneCall
. - O serviço tem um caso de uso relacionado a chamadas telefônicas, navegação ou reprodução de mídia, conforme definido no atributo de categoria da notificação.
- O serviço desativou a mudança de comportamento transmitindo
FOREGROUND_SERVICE_IMMEDIATE
para o métodosetForegroundServiceBehavior()
ao configurar a notificação.
No Android 13 (nível 33 da API) ou versões mais recentes, se o usuário negar a permissão de notificação, ele ainda vai receber avisos relacionados a serviços em primeiro plano no Gerenciador de tarefas, mas não na gaveta de notificações.
Declarar serviços em primeiro plano no manifesto
No manifesto do app, declare cada um dos serviços em primeiro plano
com um elemento
<service>
. Use um
atributo android:foregroundServiceType
para cada serviço para declarar o tipo de trabalho que ele faz.
Por exemplo, se o app criar um serviço em primeiro plano que reproduz música, declare o serviço desta forma:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
Se os vários tipos se aplicarem ao serviço, separe-os com o operador
|
. Por exemplo, um serviço que usa a câmera e o microfone
o declararia assim:
android:foregroundServiceType="camera|microphone"
Solicitar as permissões de serviço em primeiro plano
Os apps voltados ao Android 9 (nível 28 da API) ou versões mais recentes e que usam serviços em primeiro plano
precisam solicitar o
FOREGROUND_SERVICE
no manifesto do app, conforme mostrado no snippet de código abaixo. Essa é uma permissão
normal, portanto, o sistema
a concede automaticamente ao app solicitante.
Além disso, se o app for direcionado ao nível 34 da API ou mais recente, ele precisará solicitar o
tipo de permissão adequado para o tipo de trabalho que o serviço em primeiro plano
vai realizar. Cada tipo de serviço em primeiro plano
tem um tipo de permissão correspondente. Por exemplo, se um app iniciar um
serviço em primeiro plano que usa a câmera, será necessário solicitar as permissões
FOREGROUND_SERVICE
e FOREGROUND_SERVICE_CAMERA
. Essas são permissões normais, portanto, o sistema as concede
automaticamente se elas estiverem listadas no manifesto.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
<application ...>
...
</application>
</manifest>
Pré-requisitos de serviços em primeiro plano
A partir do Android 14 (nível 34 da API), quando você inicia um serviço em primeiro plano,
o sistema verifica pré-requisitos específicos com base no tipo de serviço. Por exemplo,
se você tentar iniciar um serviço em primeiro plano do tipo location
, o sistema vai verificar
se o app já tem a permissão ACCESS_COARSE_LOCATION
ou
ACCESS_FINE_LOCATION
. Caso contrário, o sistema vai gerar
SecurityException
.
Por esse motivo, confirme se os pré-requisitos necessários foram atendidos antes de iniciar um serviço em primeiro plano. A documentação do tipo de serviço em primeiro plano lista os pré-requisitos necessários para cada tipo de serviço em primeiro plano.
Iniciar um serviço em primeiro plano
Antes de solicitar que o sistema execute um serviço como um serviço em primeiro plano, inicie o serviço:
Kotlin
val intent = Intent(...) // Build the intent for the service context.startForegroundService(intent)
Java
Context context = getApplicationContext(); Intent intent = new Intent(...); // Build the intent for the service context.startForegroundService(intent);
Dentro do serviço, geralmente em onStartCommand()
, é possível solicitar
que ele seja executado em primeiro plano. Para fazer isso, chame
ServiceCompat.startForeground()
(disponível no androidx-core 1.12 e mais recentes). Esse método usa os seguintes
parâmetros:
- O serviço
- Um número inteiro positivo que identifica exclusivamente a notificação na barra de status
- O próprio objeto
Notification
- Os tipos de serviço em primeiro plano que identificam o trabalho realizado pelo serviço
Esses tipos podem ser um subconjunto dos tipos declarados no manifesto,
dependendo do caso de uso específico. Em seguida, se você precisar adicionar mais tipos de serviço,
chame startForeground()
novamente.
Por exemplo, suponha que um app fitness execute um serviço de rastreador de corrida que sempre
precisa de informações de location
, mas pode ou não tocar mídia. Você
precisa declarar location
e mediaPlayback
no manifesto. Se um
usuário iniciar uma corrida e quiser apenas que o local seja rastreado, o app precisará chamar
startForeground()
e transmitir apenas a permissão ACCESS_FINE_LOCATION
. Em seguida,
se o usuário quiser começar a tocar áudio, chame startForeground()
novamente e
transmita a combinação bit a bit de todos os tipos de serviço em primeiro plano (neste caso,
ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
).
Confira um exemplo que inicia um serviço de câmera em primeiro plano:
Kotlin
class MyCameraService: Service() { private fun startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user has // granted the CAMERA permission. val cameraPermission = PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA) if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) { // Without camera permissions the service cannot run in the foreground // Consider informing user or updating your app UI if visible. stopSelf() return } try { val notification = NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service is running .build() ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA } else { 0 }, ) } catch (e: Exception) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException) { // App not in a valid state to start foreground service // (e.g. started from bg) } // ... } } }
Java
public class MyCameraService extends Service { private void startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user // has granted the CAMERA permission. int cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (cameraPermission == PackageManager.PERMISSION_DENIED) { // Without camera permissions the service cannot run in the // foreground. Consider informing user or updating your app UI if // visible. stopSelf(); return; } try { Notification notification = new NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service // is running .build(); int type = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; } ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ type ); } catch (Exception e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException ) { // App not in a valid state to start foreground service // (e.g started from bg) } // ... } } //... }
Remover um serviço do primeiro plano
Para remover o serviço do primeiro plano, chame
stopForeground()
.
Esse método usa um booleano, que indica se a notificação da barra de status
também será removida. O serviço continua em execução.
Se você interromper o serviço enquanto ele estiver em execução em primeiro plano, a notificação será removida.
Processar a interrupção iniciada pelo usuário de apps que executam serviços em primeiro plano
No Android 13 (nível 33 da API) e versões mais recentes, os usuários podem concluir um fluxo de trabalho na gaveta de notificações para interromper um app que tem serviços em primeiro plano em andamento, independentemente da versão do SDK de destino. Essa funcionalidade, chamada de Gerenciador de tarefas, mostra uma lista de apps que estão executando um serviço em primeiro plano.
A lista tem o rótulo Apps ativos. Ao lado de cada app há um botão Parar. A Figura 1 ilustra o fluxo de trabalho do Gerenciador de tarefas em um dispositivo com o Android 13.
Quando o usuário pressiona o botão Stop ao lado do app no Gerenciador de tarefas, as seguintes ações ocorrem:
- O sistema remove o app da memória. Portanto, todo o app é interrompido, não apenas o serviço em primeiro plano em execução.
- O sistema remove a backstack de atividades do app.
- A reprodução de mídia é interrompida.
- A notificação associada ao serviço em primeiro plano é removida.
- Seu app continua no histórico.
- Os jobs programados são executados no horário programado.
- Os alarmes são acionados no horário ou na janela de tempo programados.
Para testar se o app se comporta conforme o esperado ao ser interrompido pelo usuário, execute o comando ADB abaixo em uma janela de terminal:
adb shell cmd activity stop-app PACKAGE_NAME
Isenções
O sistema oferece vários níveis de isenção para determinados tipos de apps, apresentados nas seções abaixo.
As isenções são aplicadas por app, e não por processo. Se o sistema isentar um processo em um app, todos os outros processos nesse app também vão ser isentos.
Isenções de exibição no gerenciador de tarefas
Os apps abaixo podem executar um serviço em primeiro plano sem que apareçam no gerenciador de tarefas:
- Apps do sistema
- Apps de segurança: ou seja, apps que têm o papel
ROLE_EMERGENCY
- Apps em dispositivos no modo de demonstração
Isenções para que o app não possa ser interrompido pelo usuário
Quando os tipos de apps apresentados abaixo executam um serviço em primeiro plano, eles aparecem no Gerenciador de tarefas, mas o botão Parar não é mostrado ao lado do nome do app para o usuário tocar:
- Apps do proprietário do dispositivo
- Apps do proprietário do perfil
- Apps persistentes
- Apps que têm o papel
ROLE_DIALER
Usar APIs específicas em vez de serviços em primeiro plano
Para muitos casos de uso, existem APIs da plataforma ou do Jetpack que podem ser usadas para fazer o trabalho que você usaria um serviço em primeiro plano. Se houver uma API criada especificamente para isso, use-a quase sempre em vez de um serviço em primeiro plano. As APIs criadas para um propósito geralmente oferecem recursos específicos de caso de uso que você precisa criar por conta própria. Por exemplo, a API Bubbles processa a lógica complexa da interface para apps de mensagens que precisam implementar recursos de balão de chat.
A documentação dos tipos de serviço em primeiro plano lista boas alternativas para usar em vez dos serviços em primeiro plano.
Restrições para iniciar um serviço em primeiro plano em segundo plano
Apps destinados ao Android 12 ou mais recente não podem iniciar serviços
em primeiro plano enquanto são executados em segundo plano, exceto em alguns casos
específicos. Se um app tentar iniciar um
serviço em primeiro plano enquanto estiver em segundo plano e esse serviço
não atender a um dos casos excepcionais, o sistema vai gerar uma
ForegroundServiceStartNotAllowedException
.
Além disso, se um app quiser iniciar um serviço em primeiro plano que precise de permissões durante o uso (por exemplo, permissões de sensor corporal, câmera, microfone ou localização), ele não poderá criar o serviço enquanto estiver em segundo plano, mesmo que o app se enquadre em uma das exceções das restrições de inicialização em segundo plano. A razão para isso é explicada na seção Restrições de inicialização de serviços em primeiro plano que precisam de permissões durante o uso.
Isenção de restrições de início em segundo plano
O app pode iniciar serviços em primeiro plano mesmo quando é executado em segundo plano:
- O app estava em um estado visível para o usuário, como uma atividade.
- O app pode iniciar uma atividade do segundo plano, exceto quando o app tem uma atividade na backstack para uma tarefa existente.
O app recebe uma mensagem de alta prioridade usando o Firebase Cloud Messaging.
O usuário realiza uma ação em um elemento da IU relacionado ao app. Por exemplo, o usuário pode interagir com um balão, uma notificação, um widget ou uma atividade.
O app invoca um alarme exato para concluir uma ação solicitada pelo usuário.
O app é o método de entrada atual do dispositivo.
O app recebe um evento relacionado à fronteira geográfica virtual ou à transição de reconhecimento de atividade.
Após o dispositivo ser reiniciado e receber a ação da intent
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
ouACTION_MY_PACKAGE_REPLACED
em um broadcast receiver.O app recebe a ação da intent
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
ouACTION_LOCALE_CHANGED
em um broadcast receiver.Seu app recebe o evento
ACTION_TRANSACTION_DETECTED
deNfcService
.Apps com determinados papéis ou permissões do sistema, como proprietários de dispositivo e proprietários de perfil.
O app usa o gerenciador de dispositivo complementar e declara a permissão
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
ouREQUEST_COMPANION_RUN_IN_BACKGROUND
. Sempre que possível, useREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
.O usuário desativa as otimizações de bateria do app.
O app tem a permissão
SYSTEM_ALERT_WINDOW
. Observação: se o app for destinado ao Android 15 ou mais recente, ele precisará ter a permissãoSYSTEM_ALERT_WINDOW
e o app precisa ter uma janela de sobreposição visível.
Restrições para iniciar serviços em primeiro plano que precisam de permissões durante o uso
No Android 14 (nível 34 da API) ou versões mais recentes, há situações especiais que precisam ser consideradas se você estiver iniciando um serviço em primeiro plano que precisa de permissões durante o uso.
Se o app for destinado ao Android 14 ou a versões mais recentes, o sistema operacional
vai verificar quando você criar um serviço em primeiro plano para garantir que o app tenha todas as
permissões adequadas para esse tipo de serviço. Por exemplo, quando você cria um
serviço em primeiro plano do tipo
microfone, o sistema operacional
verifica se o app tem a permissão
RECORD_AUDIO
. Se você não tiver essa permissão, o sistema vai gerar uma
SecurityException
.
Para permissões em uso, isso causa um possível problema. Se o app tiver uma
permissão durante o uso, ele só terá essa permissão enquanto estiver em
primeiro plano. Isso significa que, se o app estiver em segundo plano e tentar criar
um serviço em primeiro plano do tipo câmera, localização ou microfone, o sistema vai detectar
que o app não tem as permissões necessárias e gerar uma
SecurityException
.
Da mesma forma, se o app estiver em segundo plano e criar um
serviço de integridade que precise da permissão BODY_SENSORS
, o app
não terá essa permissão no momento, e o sistema gerará uma exceção.
Isso não se aplica se for um serviço de saúde que precisa de permissões diferentes,
como ACTIVITY_RECOGNITION
. Chamar
PermissionChecker.checkSelfPermission()
não evita esse problema. Se o app tiver uma permissão durante o uso e
chamar checkSelfPermission()
para verificar se ele tem essa permissão, o método
vai retornar PERMISSION_GRANTED
, mesmo que o app esteja em segundo plano. Quando o
método retorna PERMISSION_GRANTED
, isso significa que "seu app tem essa permissão
enquanto o app está em uso".
Por esse motivo, se o serviço em primeiro plano precisar de uma permissão durante o uso, chame Context.startForegroundService()
ou Context.bindService()
enquanto
o app tiver uma atividade visível, a menos que o serviço se enquadre em uma das
isenções definidas.
Isenções de restrições de permissões durante o uso
Em algumas situações, mesmo que um serviço em primeiro plano seja iniciado enquanto o app é executado em segundo plano, ele ainda pode acessar informações de localização, câmera e microfone enquanto o app é executado em primeiro plano ("durante o uso").
Nessas mesmas situações, se o serviço declarar um
tipo de serviço em primeiro plano de location
e for iniciado por um app que
tenha a permissão
ACCESS_BACKGROUND_LOCATION
, esse serviço poderá acessar informações de localização o tempo todo, mesmo quando
o app for executado em segundo plano.
A lista a seguir contém essas situações:
- Um componente do sistema inicia o serviço.
- O serviço começa interagindo com widgets de apps.
- O serviço é iniciado por uma interação com uma notificação.
- O serviço é iniciado como uma
PendingIntent
enviada por outro app visível. - O serviço é iniciado por um app que é um controlador de política de dispositivo que é executado no modo de proprietário do dispositivo.
- O serviço é iniciado por um app que fornece o
VoiceInteractionService
. - O serviço é iniciado por um app que tem a
permissão privilegiada
START_ACTIVITIES_FROM_BACKGROUND
.
Determinar quais serviços são afetados no seu app
Ao testar seu app, inicie os serviços em primeiro plano. Se um serviço iniciado tiver acesso restrito à localização, ao microfone e à câmera, a seguinte mensagem será exibida no Logcat:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME