You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio Kotlin:如何将蓝牙GATT的两个uint8合并为uint16?

嗨,刚从C转Kotlin的话,确实会因为类型安全的特性遇到字节操作的小坑,我来帮你搞定这个uint16合并的问题~

首先说清楚你之前出错的核心原因:Kotlin里的Byte是有符号类型,直接用它做移位操作会自动转成Int并触发符号扩展,导致结果不符合预期。解决的关键是先把有符号字节转成无符号的UByte,再进行合并操作。

方法一:直接用无符号字节移位合并(最直观,和C逻辑最接近)

这是最贴合你原有思路的写法,先把两个字节转成无符号类型,再按位操作:

// 提取高、低字节并转为无符号类型
val highByte = characteristic.value[1].toUByte()
val lowByte = characteristic.value[2].toUByte()

// 高字节左移8位,再和低字节按位或,得到UShort(对应uint16)
val uint16Value = (highByte shl 8) or lowByte

// 转成字符串赋值给strValue
val strValue = uint16Value.toString()

和C里(highByte << 8) | lowByte的逻辑完全一致,只是Kotlin需要显式转无符号类型来避免符号扩展问题。

方法二:用ByteBuffer解析(适合复杂字节数组场景)

如果后续还要解析更多不同类型的字段,用ByteBuffer会更规范,还能直接指定字节序:

import java.nio.ByteBuffer
import java.nio.ByteOrder

// 包装特征值的字节数组,指定大端序(因为你的高字节在前)
val buffer = ByteBuffer.wrap(characteristic.value).order(ByteOrder.BIG_ENDIAN)

// 跳过第一个字节,读取两个字节转为UShort
val uint16Value = buffer.position(1).getShort().toUShort()

// 转成字符串
val strValue = uint16Value.toString()

getShort()会自动读取当前位置开始的两个字节,toUShort()把有符号的Short转成无符号的uint16类型,完美匹配你的需求。

补充说明:为什么之前的shl会出错?

举个例子,如果你的高字节是0x80(对应有符号Byte的-128),直接做shl 8的话,Kotlin会先把它转成Int的0xFFFFFF80,左移8位后变成0xFFFF8000,这显然不是你要的uint16值。而转成UByte后,0x80就是纯粹的无符号8位值,移位后不会有多余的符号位干扰。

内容的提问来源于stack exchange,提问作者NIXIE_123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:25:25