Este guia fornece uma visão geral de como oferecer suporte aos principais casos de uso para comunicação com dispositivos periféricos quando o app está em execução em segundo plano:
Há várias opções para cada um desses casos de uso. Cada uma tem benefícios e desvantagens que podem torná-la mais ou menos adequada para suas necessidades específicas.
O diagrama a seguir mostra uma visão simplificada das orientações desta página:

Encontrar um dispositivo
Primeiro, o app precisa encontrar um dispositivo para se conectar. Para encontrar um dispositivo BLE, use uma das seguintes APIs:
BluetoothLeScanner, conforme descrito em Encontrar dispositivos BLE. (Trecho)CompanionDeviceManagerconforme descrito em Pareamento de dispositivos complementares. (Trecho)
Em segundo plano
Não há limitação para o uso de nenhuma dessas APIs enquanto o app não está visível, mas ambas precisam que o processo do app esteja ativo. Se o processo do app não estiver em execução, use as seguintes soluções alternativas:
- Para
BluetoothLeScanner: chamestartScan()com um objetoPendingIntentem vez de um objetoScanCallbackpara receber uma notificação quando um dispositivo que corresponde ao seu filtro for verificado. (Trecho) - Para
CompanionDeviceManager: siga as orientações em Manter apps complementares ativos para ativar o app e mantê-lo ativo enquanto um dispositivo associado anteriormente estiver dentro do alcance. (Trecho)
Conectar a um dispositivo
Para se conectar a um dispositivo depois de encontrá-lo, você precisa receber uma instância
BluetoothDevice para
o dispositivo de uma das seguintes fontes:
- Um resultado de verificação
BluetoothLeScanner, conforme descrito na seção anterior. - A lista de dispositivos vinculados recuperada de
BluetoothAdapter.getBondedDevices(). - O cache
BluetoothAdapter, usandoBluetoothAdapter.getRemoteLeDevice().
Depois de ter uma instância BluetoothDevice, você pode iniciar uma solicitação de conexão
com o dispositivo correspondente chamando um dos métodos
connectGatt(). O valor transmitido para o booleano autoConnect define qual dos
dois modos de conexão a seguir o cliente GATT usa:
- Conexão direta (
autoconnect = false): tenta se conectar diretamente ao dispositivo periférico e falha se ele não estiver disponível. Em caso de desconexão, o cliente GATT não tenta se reconectar automaticamente. - Conexão automática (
autoconnect = true): tenta se conectar automaticamente ao dispositivo periférico sempre que ele estiver disponível. Em caso de desconexão iniciada pelo periférico ou porque ele está fora de alcance, o cliente GATT tenta se reconectar automaticamente quando o periférico está disponível.
Em segundo plano
Não há restrição para se conectar a um dispositivo enquanto o app está em segundo plano, mas a conexão é encerrada se o processo é interrompido. Além disso, há restrições para iniciar atividades (no Android 10 e versões mais recentes) ou serviços em primeiro plano (no Android 12 e versões mais recentes) em segundo plano.
Assim, para realizar uma conexão em segundo plano, os apps podem usar as seguintes soluções:
- Use o WorkManager para se conectar ao
dispositivo.
- É possível definir um
PeriodicWorkRequestou umOneTimeWorkRequestpara realizar uma ação definida, embora restrições de apps possam ser aplicadas. - Além disso, você pode aproveitar os recursos do WorkManager, como restrições de trabalho, trabalho priorizado, política de nova tentativa e muito mais.
- Se a conexão precisar ser mantida ativa pelo maior tempo possível para realizar uma tarefa, como sincronização de dados ou sondagem dos dispositivos periféricos, será necessário iniciar um serviço em primeiro plano seguindo as orientações em Suporte para workers de longa duração. No entanto, as restrições de inicialização de serviços em primeiro plano se aplicam a partir do Android 12.
- É possível definir um
- Inicie um serviço em primeiro plano com o tipo
connectedDevice.- Se a conexão precisar ser mantida ativa pelo maior tempo possível para realizar uma tarefa, como sincronização de dados ou sondagem dos dispositivos periféricos, será necessário iniciar um serviço em primeiro plano seguindo as orientações em Suporte para workers de longa duração. No entanto, as restrições de inicialização de serviços em primeiro plano se aplicam a partir do Android 12.
- Chame
startScan()com um objetoPendingIntent, conforme descrito em Encontrar um dispositivo, para ativar o processo quando o dispositivo estiver presente. O dispositivo periférico precisa estar anunciando.- Recomendamos que você inicie um worker e um job. Isso pode ser interrompido pelo sistema e, portanto, só pode oferecer suporte a comunicações de curta duração.
- Em versões anteriores ao Android 12, é possível iniciar um serviço em primeiro plano
diretamente do objeto
PendingIntent.
- Use
CompanionDeviceServicee as permissõesREQUEST_COMPANION_RUN_IN_BACKGROUNDouREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUNDpara iniciar o serviço em segundo plano.
Manter a conexão com um dispositivo
O ideal é que os apps mantenham conexões com dispositivos periféricos apenas pelo tempo necessário e se desconectem quando a tarefa for concluída. No entanto, há dois casos em que um app pode precisar manter uma conexão ativa indefinidamente:
Nos dois casos, as seguintes opções estão disponíveis:
- Use
CompanionDeviceServicecom a permissãoREQUEST_COMPANION_RUN_IN_BACKGROUNDe o métodoCompanionDeviceManager.startObservingDevicePresence(). - Inicie um serviço em primeiro plano enquanto
o app estiver em primeiro plano (ou em uma das
isenções)
com o tipo
connectedDevice.
Ao alternar entre apps
Encontrar um dispositivo, conectar-se a ele e transferir dados é um processo demorado e
que consome muitos recursos. Para evitar a perda de conexão e a necessidade de realizar todo o
processo sempre que o usuário alternar entre apps ou realizar tarefas
simultâneas, mantenha a conexão ativa até que a operação seja concluída. Você
pode usar um serviço em primeiro plano com o tipo connectedDevice ou a
API Companion Device Presence.
Ao ouvir notificações de periféricos
Para ouvir as notificações do periférico, o app precisa chamar
setCharacteristicNotification(),
ouvir os callbacks usando
onCharacteristicChanged()
e manter a conexão ativa. Para a maioria dos apps, é melhor oferecer suporte a esse caso de uso
com CompanionDeviceService, porque o app provavelmente precisará continuar ouvindo
por longos períodos. No entanto, também é possível usar um serviço em primeiro plano.
Em ambos os casos, é possível se reconectar após um processo encerrado seguindo as instruções na seção Conectar a um dispositivo.