Android 平板 APP 蓝牙控制美容仪器设备

文章目录

    在 Android 平板 APP 上增加了控制空调功能之后,又要蓝牙控制美容仪器,这真是变成了一个万能遥控器。

    本以为一两个小时就能搞定,没想到 android 上 kotlin 处理多个 bit 位组合异常麻烦,最终整整耗费了一个下午才搞定。今天的计划彻底被打乱了。

    TODO

    • [x] 新 fragment 页面。增加一个调试页面
    • [x] 扩充蓝牙 MTU 字节数,及读取的字节数。这里犯了一个错误,忽略了 0 号寄存器位,导致拉取的时候,少读取了一个字节,怪不得最后一个字节总是跟预期不符,数值乱跳,原来是读到了校验位。
    • [x] 控制字段的解析。界面数值显示
    • [x] 美容功能的控制按钮。点击事件处理
    • [x] 蓝牙控制指令发送

    为了减少传输的蓝牙数据包,协议中使用了大量的bit位组合,例如 3,4,7 个 bit 代表一个设置值,而非用一个字节表示。用 kotlin 解析起来就得注意,多做单元测试。

    这里记录一下:

    控制协议的解析

    两个字节中,每四个 bit 位解析为一个数值。

    以下为 Android Koltin 测试代码:

    fun extractBits(byte: Byte): Pair<Int, Int> {
        // 取出前四个 bit. shr 是右移位
        val firstFourBits = (byte.toInt() and 0b11110000) shr 4
        
        // 取出后四个 bit
        val lastFourBits = byte.toInt() and 0b00001111
        
        return Pair(firstFourBits, lastFourBits)
    }
    
    fun main() {
    	val byte: Byte = 0b10101111.toByte()
    	val (firstFour, lastFour) = extractBits(byte)
    	println("First four bits: $firstFour")  // 10
    	println("Last four bits: $lastFour")    // 15
    }
    

    注意,val byte: Byte = 0b10101111.toByte() 在定义 byte 时,需要将数值通过 toByte 转换位 byte 类型,否则会报错

    The integer literal does not conform to the expected type Byte

    控制协议的拼装

    将一个字节中高四位,或者低四位修改为某个整数。

    以下为 Android Koltin 测试代码:

    fun setHighFourBits(byte: Byte, value: Int): Int {
        return (byte.toInt() and 0b00001111) or (value shl 4)
    }
    
    fun setLowFourBits(byte: Byte, value: Int): Int {
        return (byte.toInt() and 0b11110000) or value
    }
    
    
    fun main() { 
        val originalByte: Byte = 0b10101010.toByte()
    
    	// 修改高四位为 0b1110
    	val newByte1 = setHighFourBits(originalByte, 0b1110)
        println("0b${newByte1.toString(2)}")  // 0b11101010
    
    	// 修改低四位为 0b1011
    	val newByte2 = setLowFourBits(originalByte, 0b1011)
        println("0b${newByte2.toString(2)}")  // 0b10101011
    }
    

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式