Android BLE:如何将onCharacteristicChanged特征值转为64位二进制字节数组?
解决方案:将8字节BLE数据转换为64位二进制数组
方法一:直接遍历字节转换
直接对每个字节进行位提取,把8字节数组转换为64个0/1组成的数组,代码实现如下:
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) { with(characteristic) { val byteArray = value ?: return val binaryArray = IntArray(64) var currentIndex = 0 byteArray.forEach { signedByte -> // 将有符号Byte转为无符号,避免负数干扰位运算 val unsignedByte = signedByte.toUByte() // 从高位到低位提取每一位(若设备是低位优先,改为0 until 8) for (bitPos in 7 downTo 0) { // 提取当前位的0/1值 binaryArray[currentIndex++] = if ((unsignedByte.toInt() shr bitPos) and 1 == 1) 1 else 0 } } Log.d(TAG, "64位二进制数组: ${Arrays.toString(binaryArray)}") } }
方法二:先解析为指定类型再转换
如果需要严格对应设备发送的UInt32 + 两个UInt16结构,可以先解析出对应数值,再转换为二进制数组,能更精准匹配协议定义:
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) { with(characteristic) { val byteArray = value ?: return // 根据设备协议选择字节序,BIG_ENDIAN或LITTLE_ENDIAN val buffer = ByteBuffer.wrap(byteArray).order(ByteOrder.BIG_ENDIAN) // 解析出UInt32和两个UInt16 val uint32Value = buffer.int.toUInt() val uint16Value1 = buffer.short.toUShort() val uint16Value2 = buffer.short.toUShort() // 将无符号整数转换为指定长度的二进制数组 fun uintToBinary(value: UInt, bitLength: Int): IntArray { return IntArray(bitLength) { index -> val shiftPos = bitLength - 1 - index if ((value shr shiftPos) and 1u == 1u) 1 else 0 } } // 分别转换并合并为64位数组 val uint32Binary = uintToBinary(uint32Value, 32) val uint16Binary1 = uintToBinary(uint16Value1.toUInt(), 16) val uint16Binary2 = uintToBinary(uint16Value2.toUInt(), 16) val combinedBinary = uint32Binary + uint16Binary1 + uint16Binary2 Log.d(TAG, "解析后合并的64位二进制数组: ${Arrays.toString(combinedBinary)}") } }
注意事项
- 字节序:BLE设备的数据字节序(大端/小端)需要和代码中的
ByteOrder一致,否则解析结果会错误。 - 位顺序:方法一中的
7 downTo 0是从高位到低位提取,若设备发送的字节内部是低位在前,需要改为0 until 8循环。
内容的提问来源于stack exchange,提问作者Selphiron
相关产品推荐
相关产品推荐

