Android平台getServices()返回BLE GATT服务不完整的问题求助
BLE服务发现异常排查:HCI日志显示4个服务,但应用仅识别3个
嘿,我来帮你捋捋这个头疼的BLE问题!你现在遇到的情况是:连接自定义固件的BLE设备后,Wireshark抓的HCI日志明明显示有4个服务(2个标准+2个自定义),但不管是自己写的Android代码还是nRF蓝牙应用,调用getServices()都只拿到3个服务——第三个服务丢了唯一的自定义特征,第四个服务直接找不到。咱们一步步排查可能的原因:
可能的问题点&排查方向
1. 服务/特征的UUID或属性配置有问题
BLE对UUID的格式要求很严格,尤其是128位的自定义UUID,大小写、连字符位置错一点都不行。另外得重点检查自定义特征的属性权限:
- 如果那个缺失的特征没设置
READ/NOTIFY等可发现属性,或者权限要求加密但连接没做加密,应用层就识别不到它。 - 第四个服务的UUID会不会和某个标准服务冲突了?或者固件里把它标记成了隐藏服务,不让主动发现?
2. 服务发现过程不完整或超时
Android的BLE栈默认有服务发现超时机制,如果固件响应太慢,或者分批次返回服务时丢包,discoverServices()可能提前结束,没拿到完整列表。你可以试试:
- 一定要在
BluetoothGattCallback的onServicesDiscovered回调里处理服务,确认回调返回的状态码是BluetoothGatt.GATT_SUCCESS再调用getServices(),别提前去拿。 - 看看HCI日志里第四个服务的服务发现响应包是不是真的发出来了?有没有被Android的BLE栈过滤掉——有些品牌的Android设备对非标准服务兼容性不太好。
3. 固件侧的服务注册/响应逻辑有问题
虽然HCI日志里能看到4个服务,但有可能固件在连接后的服务发现响应里没正确返回第四个服务:
- 去查固件的GATT服务注册代码,确认第四个服务和它的特征是不是都正确调用
addService()、addCharacteristic()加进去了,有没有漏写。 - 有些固件会根据连接的安全状态(比如是否加密)动态隐藏服务,看看你的连接是不是没满足固件要求的安全条件,导致第四个服务被藏起来了。
具体操作步骤
- 把HCI日志里的4个服务UUID全抄出来,和Android代码里你用来过滤服务的UUID逐字符对比,别放过大小写和连字符的细节。
- 在
onServicesDiscovered里打印所有返回的服务UUID,以及每个服务下的特征UUID,和HCI日志的内容做对比,定位是哪个环节丢了数据。 - 用nRF Connect的高级扫描功能,看看设备广播的服务UUID里有没有第四个服务——如果广播里有但连接后找不到,基本就是固件在连接后的服务响应里没返回它。
- 换一台不同品牌的Android设备测试,排除设备BLE栈的兼容性问题。
内容的提问来源于stack exchange,提问作者jamesw6811




