注册

Android串口通信蓝牙通信中数据格式转换整理

Android 定制开发版上应用开发,免不了使用一些串口通信、蓝牙通信,考虑到每次发送的数据包需要尽可能的小,约定的协议中基本上都是一些字节流表示,因此特地将之前搜集到的一些数据格式转换的方法整理出来。在此感谢将这些code发布出来的博主们。

一、Byte相关的数据转换

  1. 获取Byte指定下标[0 - 7]的Bit的值,和获取Byte的所有Bit的值
/**
* 获取第i位的bit值
*/

fun Byte.getPointedBit(position: Int): Int {
return (this.toInt() shr position) and 0x1
}

/**
* 通过byte获取int类型的字节list
* IntelMode 低字节在前,如 0x55-> 0101 0101
*/

fun Byte.getBitList(intelMode: Boolean = true): List<Int> {
val list = arrayListOf<Int>()
val input = this
for (i in 0 until 8) {
val index = if (intelMode) (7 - i) else i
list.add(input.getPointedBit(index))
}
return list
}
  1. Byte转16进制字符串
/**
* 十六进制字节转字符串,不足2位的字符串则在前补0
* 其实质是Byte->Int->String
*/

fun Byte.toHexString(): String {
var hexStr = Integer.toHexString(this.toInt() and 0xFF)
if (hexStr.length == 1) {
hexStr = "0$hexStr"
}
return hexStr.uppercase(Locale.getDefault())
}
  1. Byte 中修改指定位置的Bit,这个需要绕一下,先将Byte转成一个长度为8的数组,然后修改指定下标的值,然后再将这个数组转换成一个Int,最后Int可以直接转成Byte。目前还未发现其他更好的方法,如有后续补充上。
/**
* 将byte转换成bit组成的数组
*/

fun Byte.toByteArray(): ByteArray {
val bytes = ByteArray(8)
for (i in 0 until 8) {
bytes[i] = this.getPointedBit(i).toByte()
}
return bytes
}

/**
* 一个byte所代表的int值
*/

fun ByteArray.oneByteToIntSum(): Int {
var sum = 0
for (i in this.indices) {
val tmp = this[i]
// 2 的 n 次方
sum += (tmp * 2.0.pow(i.toDouble())).toInt()
}

return sum
}

二、ByteArray相关的数据转换

  1. ByteArray转Int
/**
* 有符号,int 占 2 个字节
*/

fun ByteArray.toIntWithTwo(): Int {
return (this[0].toInt() shl 8) or (this[1].toInt() and 0xFF)
}

/**
* 无符号,int 占 2 个字节
*/

fun ByteArray.toUnSignIntWithTwo(): Int {
return (this[0].toInt() and 0xFF) shl 8 or
(this[1].toInt() and 0xFF)
}

/**
* 有符号, int 占 4 个字节
*/

fun ByteArray.toIntWithFour(): Int {
return (this[0].toInt() shl 24) or
(this[1].toInt() and 0xFF) or
(this[2].toInt() shl 8) or
(this[3].toInt() and 0xFF)
}

/**
* 无符号, int 占 4 个字节
*/

fun ByteArray.toUnSignIntWithFour(): Long {
return ((this[0].toInt() and 0xFF) shl 24 or
(this[1].toInt() and 0xFF) shl 16 or
(this[2].toInt() and 0xFF) shl 8 or
(this[3].toInt() and 0xFF)).toLong()
}

/**
* 一个Int转成2个字节的byte数组
*/

fun Int.toIntArrayFor2(): List<Int> {
val list = arrayListOf<Int>()
val lowH = (this shr 8) and 0xff
val lowL = this and 0xff
list.add(lowH)
list.add(lowL)
return list
}

/**
* 一个Int转成4个字节的byte数组
*/

fun Int.toByteArray4(): ByteArray {
val byteArray = ByteArray(4)
val highH = ((this shr 24) and 0xff).toByte()
val highL = ((this shr 16) and 0xff).toByte()
val lowH = ((this shr 8) and 0xff).toByte()
val lowL = (this and 0xff).toByte()
byteArray[0] = highH
byteArray[1] = highL
byteArray[2] = lowH
byteArray[3] = lowL
return byteArray
}
  1. ByteArray转字符串
/**
* 字节数组转字符串
*/

fun ByteArray.toSimpleString(format: Charset = Charsets.UTF_8): String {
return String(this, format)
}

/**
* 字节数组转换成16进制字符串
*/

fun ByteArray.toHexString(): String {
var result = ""
for (element in this) {
var hexStr = Integer.toHexString(element.toInt() and 0xFF)
if (hexStr.length == 1) {
hexStr = "0$hexStr"
}
result += hexStr.uppercase(Locale.getDefault())
}
return result
}
  1. ByteArray转Long
/**
* 字节数组转换为long 8个byte
*/

fun ByteArray.convertToLong(): Long {
val bais = ByteArrayInputStream(this)
val dis = DataInputStream(bais)
return dis.readLong()
}

/**
* long转换为字节数组 8个byte
*/

fun Long.convertToBytes(): ByteArray {
val baos = ByteArrayOutputStream()
val dos = DataOutputStream(baos)
dos.writeLong(this)
return baos.toByteArray()
}

/**
* Long 类型转成4个字节数组
* 时间只能精确到秒
*/

fun Long.convertToBytes4(): ByteArray {
var tmp = this
val bytes = ByteArray(4)
for (i in bytes.size - 1 downTo 0) {
bytes[i] = (tmp and 0xFF).toByte()
tmp = tmp shr 8
}
return bytes
}

/**
* 4个字节数组转成Long 类型
* 时间只能精确到秒
*/

fun ByteArray.convertToLong4(): Long {
var num: Long = 0
for (i in 0 until 4) {
num = num shl 8
num = num or ((this[i].toInt() and 0xFF).toLong())
}
return num
}
  1. 两个ByteArray拼接
/**
* byte数组拼接一个byte数组
*/

fun ByteArray.appendByteArray(extraBytes: ByteArray): ByteArray {
val inputSize = this.size
val extraSize = extraBytes.size
val totalSize = inputSize + extraSize
val combineBytes = ByteArray(totalSize)
System.arraycopy(this, 0, combineBytes, 0, inputSize)
System.arraycopy(extraBytes, 0, combineBytes, inputSize, extraSize)
return combineBytes
}
  1. ByteArray转Double,此种转换较为复杂,目前未找到稳定可用的代码
none
  1. ByteArray 和 BCD 格式的时间相互转换
/**
* BCD字节数组转为字符串
*/

fun ByteArray.bcdToString(): String {
val sb = StringBuilder(this.size / 2)
for (i in 0 until this.size) {
// 高四位
sb.append((this[i].toInt() and 0xF0) ushr 4)
// 低四位
sb.append(this[i].toInt() and 0x0F)
}
val retStr = sb.toString()
return if (retStr.substring(0, 1).equals("0", ignoreCase = true)) {
retStr.substring(1)
} else {
retStr
}
}

/**
* 字符串转BCD字节数组
*/

fun String.bcdToByteArray(): ByteArray {
var len = this.length
val mod = len % 2
val srcStr = if (0 != mod) {
len += 1
"0$this"
} else this
val bytes = srcStr.toByteArray()
len = if (len >= 2) len / 2 else len
val secondBytes = ByteArray(len)
var j: Int
var k: Int
for (p in 0 until srcStr.length / 2) {
val jIndex = 2 * p
j = if (bytes[jIndex].toInt().toChar() in '0'..'9') {
bytes[jIndex].toInt().toChar() - '0'
} else if (bytes[jIndex].toInt().toChar() in 'a'..'z') {
bytes[jIndex].toInt().toChar() - 'a' + 0x0a
} else {
bytes[jIndex].toInt().toChar() - 'A' + 0x0a
}
val kIndex = 2 * p + 1
k = if (bytes[kIndex].toInt().toChar() in '0'..'9') {
bytes[kIndex].toInt().toChar() - '0'
} else if (bytes[kIndex].toInt().toChar() in 'a'..'z') {
bytes[kIndex].toInt().toChar() - 'a' + 0x0a
} else {
bytes[kIndex].toInt().toChar() - 'A' + 0x0a
}
val a = (j shl 4) + k
val b = a.toByte()
secondBytes[p] = b
}
return secondBytes
}

三、String相关的类型转换,主要是方便把二进制字节流转换成易于查看的字符串

  1. 16进制字符串转ByteArray
private fun char2Byte(input: Char): Byte {
return "0123456789ABCDEF".indexOf(input).toByte()
}

/**
* 16进制字符串转字节数组,提供3种转换方式
*/

fun String.hexStringToBytes(type: Int = 0): ByteArray {
if (this.isEmpty()) {
return ByteArray(0)
}
val hexStr = this.uppercase(Locale.getDefault())
val length = hexStr.length / 2
val outBytes = ByteArray(length)
when (type) {
0 -> {
val hexCharArr = this.toCharArray()
for (i in 0 until length) {
val p = 2 * i
val p1 = char2Byte(hexCharArr[p]).toInt() shl 4
val p2 = char2Byte(hexCharArr[p + 1])
outBytes[i] = p1.toByte() or p2
}
}
1 -> {
for (i in 0 until length step 2) {
val v1 = (this[i].digitToIntOrNull(16) ?: -1) shl 4
val v2 = this[i + 1].digitToIntOrNull(16) ?: -1
outBytes[i / 2] = (v1 + v2).toByte()
}
}
else -> {
for (i in outBytes.indices) {
val subStr = this.substring(2 * i, 2 * i + 2)
outBytes[i] = subStr.toInt(16).toByte()
}
}
}
return outBytes
}
  1. 字符串Json格式转Map
/**
* json 字符串转 Map
*/

fun String.jsonStringToMap(): HashMap? {
val jsonObject: JSONObject
try {
jsonObject = JSONObject(this)
val keyIter: Iterator = jsonObject.keys()
var key: String
var value: Any
val valueMap = HashMap()
while (keyIter.hasNext()) {
key = keyIter.next()
value = jsonObject[key] as Any
valueMap[key] = value
}
return valueMap
} catch (e: JSONException) {
e.printStackTrace()
}
return null
}
,>,>


作者:pursuit_hu
来源:juejin.cn/post/7226629911350542391

0 个评论

要回复文章请先登录注册