使用Bleno BLE库模拟IoT外设时特征值传输异常求助
问题原因与解决方案
首先,咱们来拆解你遇到的问题:
核心原因:数据编码与解析的不匹配
你在Bleno里用new Buffer('12345')创建特征值时,Node.js会默认把字符串'12345'按UTF-8编码转换成字节数组。每个字符对应它的ASCII码字节:
'1'→0x31'2'→0x32- ...以此类推
所以这个Buffer的实际内容是[0x31, 0x32, 0x33, 0x34, 0x35]。而你的Android代码里用bytesToHex方法把收到的字节数组直接转换成了十六进制字符串,自然就得到了'3132333435'这类结果——这其实是字节的十六进制表示,不是你预期的原字符串。
而实体外设和应用配合良好,说明实体外设的发送逻辑和应用的解析逻辑是匹配的,要么是:
- 实体外设发送字符串的UTF-8字节,应用直接把字节转成字符串;
- 实体外设发送的是十六进制数值对应的字节,应用用
bytesToHex解析后得到目标字符串。
针对性解决方案
方案一:调整Android解析逻辑(和实体外设匹配)
如果实体外设是发送字符串的UTF-8字节,那你只需要把Android代码里的bytesToHex换成字符串解码即可:
@Override public void onCharacteristicRead(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) { ... // 用UTF-8解码字节数组为字符串 String payload = new String(characteristic.getValue(), StandardCharsets.UTF_8); ... }
这样就能直接得到你预期的'12345'了。
方案二:调整Bleno的特征值编码(匹配实体外设的发送逻辑)
如果实体外设是发送十六进制数值对应的字节(比如要传输'12345'作为十六进制数据),那你需要在Bleno里直接创建对应字节的Buffer:
- 如果你想把字符串
'12345'作为十六进制编码的字节数组(即'12'→0x12,'34'→0x34,'5'补零为'05'→0x05),可以用:var bleCharacteristic = function() { bleCharacteristic.super_.call(this, { uuid: '0321', properties: ['read'], value: Buffer.from('12345', 'hex') // 自动按十六进制解析字符串为字节 }); }; - 如果你知道实体外设发送的具体字节数组(比如
[0x12, 0x34, 0x05]),直接传入数组即可:value: Buffer.from([0x12, 0x34, 0x05])
额外说明
你不需要调整Bleno的广播配置——广播只负责让手机发现BLE设备,特征值的读取是设备连接后的操作,和广播数据无关。只要你的特征UUID、权限(properties: ['read'])设置正确,连接后就能正常读取值。
内容的提问来源于stack exchange,提问作者wheresmycookie
相关产品推荐
相关产品推荐

