Android系统中BLE设备特征值达到特定阈值时如何实现后台通知?
实现BLE特定特征值阈值通知+后台运行方案
第一步:开启目标特征值的主动通知
仅靠主动读取特征值无法拿到实时变化推送,需要先开启BLE特征的主动通知权限,让设备在数值变化时主动上报:
// 找到标准电量服务对应的特征后执行 val batteryService = gatt?.getService(UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb")) val batteryChar = batteryService?.getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")) // 开启本地层的特征监听 gatt?.setCharacteristicNotification(batteryChar, true) // 写入CCCD描述符,触发设备端主动上报数值变化 val cccdDescriptor = batteryChar?.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")) cccdDescriptor?.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE gatt?.writeDescriptor(cccdDescriptor)
第二步:修改特征值回调,添加阈值过滤逻辑
新增onCharacteristicChanged回调接收主动上报的数值,添加阈值判断和重复触发拦截逻辑,你原本的读取逻辑可以保留不影响:
// 新增全局标记,避免50%电量时重复触发通知 private var hasNotified50Percent = false override fun onCharacteristicChanged( gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic? ) { super.onCharacteristicChanged(gatt, characteristic) // 仅处理电量特征的上报 if (characteristic?.uuid == UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")) { val batteryLevel = characteristic.value?.first()?.toInt() ?: return // 仅在电量等于50%且未触发过通知时执行提醒 if (batteryLevel == 50 && !hasNotified50Percent) { hasNotified50Percent = true // 此处写入你的通知逻辑,例如弹系统通知、执行业务操作 sendSystemNotification() } // 可选:电量低于50%时重置标记,下次到50%可以再次触发 if (batteryLevel < 50) { hasNotified50Percent = false } } } // 你原有的主动读取逻辑保留即可 override fun onCharacteristicRead(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int) { super.onCharacteristicRead(gatt, characteristic, status) bluetoothGatt = gatt var charValue = characteristic?.value var decode = charValue?.toString(Charset.defaultCharset()) Log.d("onCharacteristicRead", "Hits here: ${bluetoothGatt?.device} $decode ${charValue?.first()?.toInt()}") }
第三步:后台运行适配
要实现后台稳定运行,需要做系统适配:
- 申请对应权限:安卓12及以上需要申请
BLUETOOTH_SCAN、BLUETOOTH_CONNECT、POST_NOTIFICATIONS、FOREGROUND_SERVICE_CONNECTED_DEVICE权限,低版本需要申请蓝牙、位置权限 - 将BLE连接逻辑放到前台服务中运行,绑定一个常驻前台通知,避免系统杀死蓝牙连接进程
- 如果允许少量延迟,也可以配合定时唤醒机制主动拉取电量,避免长连接耗电
内容的提问来源于stack exchange,提问作者rboyg
相关产品推荐
相关产品推荐

