本指南简要介绍了当您的应用在后台运行时,如何为与外围设备通信的关键用例提供支持:
这些用例都有多个支持选项。每种方法各有优缺点,可能使其更适合或不太符合您的具体需求。
下图为本页指南的简化视图:
查找设备
首先,您的应用需要查找要连接的设备。如需查找 BLE 设备,您可以使用以下任一 API:
BluetoothLeScanner
(如查找 BLE 设备中所述)。 (示例)CompanionDeviceManager
(如配套设备配对中所述)。 (示例)
在后台
在应用不可见时使用其中任一 API 不受限制,但它们都需要您的应用进程保持活跃状态。如果应用进程未运行,您可以使用以下解决方法:
- 对于
BluetoothLeScanner
:使用PendingIntent
对象(而不是ScanCallback
对象)调用startScan()
,以便在扫描到与您的过滤条件匹配的设备时收到通知。(示例) - 对于
CompanionDeviceManager
:请按照让配套应用保持唤醒状态中的指南来唤醒应用,并在之前关联的设备在范围内时使其保持唤醒状态。(示例)
连接到设备
如需在找到设备后连接到该设备,您需要从以下来源之一获取该设备的 BluetoothDevice
实例:
BluetoothLeScanner
扫描结果(如上一部分中所述)。- 从
BluetoothAdapter.getBondedDevices()
检索到的绑定设备列表。 - 使用
BluetoothAdapter.getRemoteLeDevice()
的BluetoothAdapter
缓存。
有了 BluetoothDevice
实例后,您便可以通过调用 connectGatt()
方法之一向相应设备发起连接请求。您传递到 autoConnect
布尔值的值决定了 GATT 客户端使用以下两种连接模式中的哪一种:
- Direct connect (
autoconnect = false
):尝试直接连接到外围设备,如果设备不可用,则尝试连接失败。如果断开连接,GATT 客户端不会自动尝试重新连接。 - 自动连接 (
autoconnect = true
):在外围设备可用时尝试自动连接。如果外围设备发起断开连接或外围设备不在覆盖范围内,GATT 客户端会在外围设备可用时自动尝试重新连接。
在后台
当应用在后台运行时,连接设备不受限制,但如果您的进程被终止,连接会关闭。此外,从后台启动 activity(在 Android 10 及更高版本中)或前台服务(在 Android 12 及更高版本中)存在限制。
因此,如需在后台建立连接,应用可以使用以下解决方案:
- 使用 WorkManager 连接到设备。
- 您可以设置
PeriodicWorkRequest
或OneTimeWorkRequest
来执行定义的操作,不过可能会受到应用限制。 - 此外,您还可以受益于工作约束条件、加急工作、重试政策等 WorkManager 功能。
- 如果需要尽可能让连接保持活跃状态以执行任务(例如同步数据或从外围设备进行轮询),则需要按照对长时间运行的 worker 的支持中的指南启动前台服务。不过,从 Android 12 开始,将适用前台服务启动限制。
- 您可以设置
- 启动一项具有
connectedDevice
类型的前台服务。- 如果需要尽可能让连接保持活跃状态以执行任务(例如同步数据或从外围设备进行轮询),则需要按照对长时间运行的 worker 的支持中的指南启动前台服务。不过,从 Android 12 开始,将适用前台服务启动限制。
- 如查找设备中所述,使用
PendingIntent
对象调用startScan()
,以在设备存在时唤醒您的进程。外围设备必须进行广播。- 我们建议您启动一个 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
来支持此用例,因为应用可能需要长时间保持监听。不过,您也可以使用前台服务。
无论是哪种情况,您都可以在终止进程后按照连接到设备部分中的说明重新连接。