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

Android开发:如何向BLE设备发送大于127的无符号整数?

解决Android BLE发送大于127数值的问题

我懂你现在的困扰——Java里的byte是有符号类型(范围-128到127),但你需要给BLE设备发送254、239这类超过127的数值。其实核心逻辑很简单:BLE特征值的字节数组是按二进制传输的,Java的有符号byte和BLE设备需要的无符号字节只是解析方式不同,底层二进制完全一致。

你的代码问题分析

你当前用了非常冗余的数值转换方式:new Integer(Integer.parseInt(Integer.toString(254, 16), 16)).byteValue(),这不仅没必要,还容易引入错误。另外还有两个关键问题:

  1. 错误使用FORMAT_UINT32作为写入类型,这个常量是用于解析特征值的格式,不是写入类型;
  2. 年份的字符串拆分逻辑有误,比如2024年时,你取的substring(2,3)会得到"2",这显然不符合时间设置的需求。

修正后的代码

public static boolean writeble_Set_time_Healthyu(BluetoothGatt mBluetoothGatt) {
    try {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int hour = calendar.get(Calendar.HOUR);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        int date = calendar.get(Calendar.DATE);
        int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始,需+1

        byte[] list_data = new byte[15];
        // 直接用(byte)强制转换大于127的数值,Java会自动转成对应有符号byte
        list_data[0] = (byte) 254;
        list_data[1] = (byte) 239;
        list_data[2] = (byte) 1;
        list_data[3] = (byte) 250;
        list_data[4] = (byte) 7;
        list_data[5] = (byte) hour;
        list_data[6] = (byte) minute;
        list_data[7] = (byte) second;
        list_data[8] = (byte) date;
        list_data[9] = (byte) month;
        // 修正年份拆分:假设设备需要四位年份的每一位(比如2024拆为2、0、2、4)
        list_data[10] = (byte) (year / 1000);    // 千位
        list_data[11] = (byte) ((year / 100) % 10); // 百位
        list_data[12] = (byte) ((year / 10) % 10);  // 十位
        list_data[13] = (byte) (year % 10);         // 个位(原代码设为0,可根据设备协议调整)
        list_data[14] = (byte) 165;

        List<BluetoothGattService> serviceList = mBluetoothGatt.getServices();
        for (BluetoothGattService service : serviceList) {
            List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
            for (BluetoothGattCharacteristic characteristic : characteristics) {
                // 设置正确的写入类型,按需选择DEFAULT或NO_RESPONSE
                characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
                characteristic.setValue(list_data);
                boolean status = mBluetoothGatt.writeCharacteristic(characteristic);
                // 可在此判断写入是否成功,或仅写入符合协议的特定特征值
            }
        }
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

关键知识点说明

  1. 数值转换逻辑:
    比如(byte)254在Java中显示为-2,但它的二进制是11111110,和无符号的254完全一致。BLE设备接收后,只要把这个字节当作无符号字节解析(比如C语言用unsigned char接收),就能得到正确的254。

  2. 写入类型的正确设置:
    不要用FORMAT_UINT32这类格式常量,写入类型应使用:

    • BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT:需要设备响应的写入
    • BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE:无需响应的写入(速度更快)
  3. 年份处理:
    你原有的字符串拆分逻辑错误,这里假设设备需要四位年份的每一位数字。如果设备只需要后两位(比如24代表2024),可以改成:

    int yearLastTwo = year % 100;
    list_data[10] = (byte) (yearLastTwo / 10); // 十位
    list_data[11] = (byte) (yearLastTwo % 10); // 个位
    

    具体需根据BLE设备的时间协议调整。

接收端处理(补充)

如果BLE设备固件用C/C++编写,接收时直接把字节转成unsigned char即可:

unsigned char value = received_byte; // 比如received_byte是-2(二进制11111110),转成unsigned char就是254

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:07:32