Android BLE读取单片机数据异常:BluetoothLeGatt模板显示多余服务
嘿,作为刚接触BLE、Android和Java的新手,遇到这个问题其实挺常见的——别慌,咱们一步步来梳理解决:
首先,你用nRF Connect看到的服务是你自己创建的,但Android的BluetoothLeGatt模板会读取所有服务,包括BLE设备默认带的标准服务,这就是数量不一致的核心原因。蓝牙规范里定义了很多通用服务(比如设备信息服务、电池服务),很多BLE模块/单片机SDK会自动启用这些服务,而你可能没把它们算在“实际创建的服务”里。
接下来是具体的解决步骤:
1. 过滤出你自定义的服务
先明确你在单片机上创建的自定义服务的UUID,然后在Gatt回调的onServicesDiscovered方法里,只保留和这个UUID匹配的服务。修改BluetoothLeService里的对应逻辑:
@Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { // 替换成你自己的自定义服务UUID String myCustomServiceUuid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; List<BluetoothGattService> myServices = new ArrayList<>(); for (BluetoothGattService service : gatt.getServices()) { String serviceUuid = service.getUuid().toString(); Log.d("BLE_DEBUG", "检测到服务UUID: " + serviceUuid); // 调试用,打印所有服务 if (serviceUuid.equalsIgnoreCase(myCustomServiceUuid)) { myServices.add(service); } } // 接下来只处理myServices里的内容,就是你自己创建的服务了 broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED, myServices); } else { Log.w(TAG, "服务发现失败,状态码: " + status); } }
2. 核对nRF Connect里的完整服务列表
打开nRF Connect连接你的设备后,仔细扫一遍服务列表——除了你自己创建的,是不是还有比如Device Information Service(UUID: 0000180A-0000-1000-8000-00805F9B34FB)这类标准服务?这些就是模板多读到的服务,它们是蓝牙协议默认提供的,并非你额外创建的。
3. 关闭单片机端的默认标准服务
如果不需要这些默认服务,可以在单片机的BLE初始化代码里关闭它们。不同的单片机BLE SDK方法不一样,比如有些SDK会有disableDefaultServices()或者类似的配置项,具体可以查你用的BLE库文档,关掉后设备就只会广播你自定义的服务了。
4. 调试确认服务来源
通过上面代码里的Log.d打印所有服务的UUID,对比nRF Connect的列表,就能清晰区分哪些是你自定义的,哪些是系统默认的,这样就能彻底搞清楚数量差异的来源。
总结一下:这个问题本质是Android Gatt模板会枚举设备上的所有BLE服务,包括规范自带的标准服务,而你只关注了自己创建的自定义服务。通过过滤UUID或者关闭默认服务,就能得到你想要的服务列表啦。
内容的提问来源于stack exchange,提问作者stellarhawk 34

