我从蓝牙设备获取字节数组中的数据。为一个字符串保留20个字节,其他字节包含short和int值等数据。使用Charset.UTF_8(或US_ASCII)将字符串的字节转换为字符串。问题是,我无法像c、c#和c++等其他语言中那样驾驭包含普通零的部分。在确定第一个零字符后尝试了droplast。什么都不管用。我错过了什么。代码是这样的:
val bytes = job.characteristic.value
var index = 0;
var tempBytes = ByteArray(30)
while(index < 20) {
if (bytes[index] != 0.toByte())
tempBytes[index] = bytes[index]
else
break
++index
}
val newString = tempBytes.toString(Charsets.ISO_8859_1).dropLast(20 - index)
Log.i("BleDeviceVM", "Received for newString: " + newString)
Android Studio中的结果如下:I/BleDeviceVM:收到newString:LEDServer��������������������
而不是:LED服务器
*谢谢Broot。来自c、c#、一些c++和一些Java Kotlin一开始有点令人困惑。这段代码运行良好,我认为:
var position = job.characteristic.value.indexOf(0)
if ((position > 20) || (-1 == position))
position = 20
_deviceID.value = String(job.characteristic.value, 0, position)
您在dropLast()
中有一个错误。您的tempBytes
大小为30
,但在dropLast
中,您从20
减去index
,而不是从30
减去。这就是为什么通常最好使用常量或直接引用集合大小:
tempBytes.toString(Charsets.ISO_8859_1).dropLast(tempBytes.size - index)
此外,如果我们需要第一个n
项目,就不需要使用dropLast()
,因为take()
正是这样做的:
tempBytes.toString(Charsets.ISO_8859_1).take(index)
但老实说,您的代码过于复杂。您可以通过简单地用替换整个代码来实现类似的效果:
val newString = String(bytes, 0, bytes.indexOf(0))
与您的代码相比有一些不同,例如,它搜索超过索引20的内容,并且在某个地方需要一个空字节。根据您的具体情况,可能需要进行调整。