В этом руководстве представлен обзор того, как поддерживать ключевые варианты использования связи с периферийными устройствами, когда ваше приложение работает в фоновом режиме:
Существует несколько вариантов поддержки каждого из этих вариантов использования. У каждого из них есть преимущества и недостатки, которые могут сделать его более или менее подходящим для ваших конкретных потребностей.
На следующей диаграмме показано упрощенное представление руководства на этой странице:
Найти устройство
Во-первых, вашему приложению необходимо найти устройство для подключения. Чтобы найти устройство 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
, либо API присутствия сопутствующего устройства .
При прослушивании периферийных уведомлений
Чтобы прослушивать периферийные уведомления, приложение должно вызывать setCharacteristicNotification()
, прослушивать обратные вызовы с помощью onCharacteristicChanged()
и поддерживать соединение. Для большинства приложений лучше всего поддерживать этот вариант использования с помощью CompanionDeviceService
, поскольку приложению, скорее всего, придется продолжать прослушивание в течение длительного периода времени. Однако вы также можете использовать службу переднего плана.
В любом случае вы можете повторно подключиться после завершения процесса, следуя инструкциям в разделе «Подключение к устройству» .