В этом руководстве рассказывается, как поддерживать ключевые сценарии использования для связи с периферийными устройствами, когда ваше приложение работает в фоновом режиме:
Для каждого из этих случаев есть несколько вариантов. У каждого из них есть свои преимущества и недостатки, которые могут сделать его более или менее подходящим для ваших конкретных потребностей.
На схеме ниже показано, как выбрать подходящий вариант.

Устройства
Сначала приложение должно найти устройство, к которому нужно подключиться. Чтобы найти устройство BLE, можно использовать любой из следующих API:
BluetoothLeScanner, как описано в разделе Поиск устройств BLE. (Пример)CompanionDeviceManager, как описано в разделе Подключение дополнительного устройства. (Пример)
В фоновом режиме
Ограничений на использование этих API, когда приложение не видно, нет, но для их работы процесс приложения должен быть активен. Если процесс приложения не запущен, вы можете использовать следующие обходные решения:
- Для
BluetoothLeScanner: вызовитеstartScan()с объектомPendingIntentвместо объектаScanCallback, чтобы получать уведомления, когда сканируется устройство, соответствующее вашему фильтру. (Пример) - Для
CompanionDeviceManager: следуйте инструкциям в разделе Как поддерживать активность сопутствующих приложений, чтобы активировать приложение и поддерживать его активность, пока ранее связанное устройство находится в зоне действия. (Пример)
Выберите устройство
Чтобы подключиться к устройству после того, как вы его нашли, вам нужно получить экземпляр BluetoothDevice для устройства из одного из следующих источников:
- Результат сканирования
BluetoothLeScanner, как описано в предыдущем разделе. - Список связанных устройств, полученный из
BluetoothAdapter.getBondedDevices(). - Кеш
BluetoothAdapter, используяBluetoothAdapter.getRemoteLeDevice().
Получив экземпляр BluetoothDevice, вы можете запустить запрос на подключение к соответствующему устройству, вызвав один из методов connectGatt(). Логическое значение, которое вы передаете в autoConnect, определяет, какой из двух режимов подключения использует клиент GATT:
- Прямое подключение (
autoconnect = false). Попытаться подключиться к периферийному устройству напрямую. Если устройство недоступно, подключение не будет установлено. В случае отключения клиент GATT не пытается автоматически подключиться заново. - Автоматическое подключение (
autoconnect = true). Попытка автоматически подключиться к периферийному устройству, когда оно доступно. Если отключение инициировано периферийным устройством или оно находится вне зоны действия, клиент GATT автоматически пытается повторно подключиться, когда периферийное устройство становится доступным.
В фоновом режиме
Ограничений на подключение к устройству, когда приложение работает в фоновом режиме, нет, но если процесс будет завершен, подключение закроется. Кроме того, в Android 10 и более поздних версиях действуют ограничения на запуск действий, а в Android 12 и более поздних версиях – ограничения на запуск активных служб из фонового режима.
Чтобы установить подключение в фоновом режиме, приложения могут использовать следующие решения:
- Для подключения к устройству используйте WorkManager.
- Вы можете настроить
PeriodicWorkRequestилиOneTimeWorkRequestдля выполнения определенного действия, хотя могут действовать ограничения для приложений. - Кроме того, вы можете использовать такие функции WorkManager, как ограничения, приоритетные задачи, правила повторных попыток и т. д.
- Если подключение должно оставаться активным как можно дольше для выполнения задачи, например синхронизации данных или опроса периферийных устройств, вам необходимо запустить активную службу, следуя инструкциям в разделе Поддержка долго работающих воркеров. Однако начиная с Android 12 действуют ограничения на запуск активных служб.
- Вы можете настроить
- Запустите активную службу с типом
connectedDevice.- Если подключение должно оставаться активным как можно дольше для выполнения задачи, например синхронизации данных или опроса периферийных устройств, вам необходимо запустить активную службу, следуя инструкциям в разделе Поддержка долго работающих воркеров. Однако начиная с Android 12 действуют ограничения на запуск активных служб.
- Вызовите
startScan()с объектомPendingIntent, как описано в разделе Поиск устройства, чтобы запустить процесс, когда устройство будет найдено. Периферийное устройство должно быть доступно для обнаружения.- Рекомендуем запустить Worker и Job. Система может прервать его, поэтому оно подходит только для коротких разговоров.
- В версиях ниже Android 12 вы можете запустить активную службу непосредственно из объекта
PendingIntent.
- Чтобы запустить службу из фонового режима, используйте разрешение
CompanionDeviceServiceи одно из разрешенийREQUEST_COMPANION_RUN_IN_BACKGROUNDилиREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND.
Как оставаться на связи с устройством
В идеале приложения должны поддерживать подключение к периферийным устройствам только до тех пор, пока это необходимо, и отключаться после выполнения задачи. Однако есть два случая, когда приложению может потребоваться поддерживать соединение неограниченное время:
В обоих случаях доступны следующие варианты:
- Используйте
CompanionDeviceServiceс разрешениемREQUEST_COMPANION_RUN_IN_BACKGROUNDи методомCompanionDeviceManager.startObservingDevicePresence(). - Запустите активную службу, пока приложение работает в активном режиме (или в одном из исключений), с типом
connectedDevice.
При переключении между приложениями
Поиск устройства, подключение к нему и передача данных требуют времени и ресурсов. Чтобы избежать потери соединения и необходимости выполнять весь процесс каждый раз, когда пользователь переключается между приложениями или выполняет одновременные задачи, вы должны поддерживать соединение до завершения операции. Вы можете использовать активную службу с типом connectedDevice или Companion Device Presence API.
Во время прослушивания уведомлений от периферийных устройств
Чтобы получать уведомления от периферийного устройства, приложение должно вызвать метод setCharacteristicNotification(), прослушивать обратные вызовы с помощью onCharacteristicChanged() и поддерживать подключение. Для большинства приложений лучше всего поддерживать этот вариант использования с помощью CompanionDeviceService, поскольку приложению, скорее всего, потребуется продолжать прослушивание в течение длительного периода времени. Однако вы также можете использовать активную службу.
В обоих случаях вы можете повторно подключиться после завершения процесса, следуя инструкциям в разделе Подключение к устройству.