Comunicação em segundo plano

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:

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: chame startScan() com um objeto PendingIntent em vez de um objeto ScanCallback para 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:

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:

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:

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.