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(),这不仅没必要,还容易引入错误。另外还有两个关键问题:
- 错误使用
FORMAT_UINT32作为写入类型,这个常量是用于解析特征值的格式,不是写入类型; - 年份的字符串拆分逻辑有误,比如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; }
关键知识点说明
数值转换逻辑:
比如(byte)254在Java中显示为-2,但它的二进制是11111110,和无符号的254完全一致。BLE设备接收后,只要把这个字节当作无符号字节解析(比如C语言用unsigned char接收),就能得到正确的254。写入类型的正确设置:
不要用FORMAT_UINT32这类格式常量,写入类型应使用:BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT:需要设备响应的写入BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE:无需响应的写入(速度更快)
年份处理:
你原有的字符串拆分逻辑错误,这里假设设备需要四位年份的每一位数字。如果设备只需要后两位(比如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
相关产品推荐
相关产品推荐

