700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【android】蓝牙对接发送指令无响应以及接收响应信息不完全问题解决(附完整代码)

【android】蓝牙对接发送指令无响应以及接收响应信息不完全问题解决(附完整代码)

时间:2019-06-24 00:26:39

相关推荐

【android】蓝牙对接发送指令无响应以及接收响应信息不完全问题解决(附完整代码)

一、问题描述

最近在对接蓝牙水表的代码编写中发现了两个问题:

(1)通过app下发指令无响应,但通过蓝牙调试app下发相同指令有响应;

(2)app接收响应信息不完全。

经查,发现问题出于安卓蓝牙底层,write方法当单次发送、接收信息长度大于20字节时,需要手动分段进行发送与接收,若采用通常的接收与发送方法,则设备只能接收与发送第一段20字节的信息,从而导致以上问题的出现。

二、解决方式

通过简单的分段发送与分段接收拼接即可实现。

三、代码展示

1 分段接收方法

⚠️ 注意:

(1)该部分代码通过比较返回信息中的包长信息与当前接收到的总包长,判断是否完成接收,应根据实际需要修改;

(2)蓝牙初始化、销毁的时候执行this.packageNum = 0;重置包数;

(3)判断到完成接收后需在分段方法中执行this.packageNum = 0;重置包数,而不是在下发方法中执行,否则可能造成包数错误,从而导致超时(开发环境未出现但生产环境会出现)。

private void subpackageReceive(byte[] bytes) {packageNum++;if (packageNum == 1) {packageHex = new StringBuilder();packageLength = bytes[1] & (0xff);}packageHex.append(DataUtils.hex2(bytes, 0, bytes.length - 1));if (packageHex.length() == 2 * packageLength) {this.packageNum = 0;parserData(DataUtils.hexStrToByteArray(packageHex.toString()));}}

2 分段发送方法
2.1 拆分方法

public static synchronized List<byte[]> subpackage(byte[] data) {List<byte[]> bytesList = new ArrayList<>();if (data.length <= 20) {bytesList.add(data);return bytesList;}int partNum = data.length / 20;int lastPartLen = 20;if (data.length % 20 != 0) {partNum += 1;lastPartLen = data.length % 20;}for (int n = 0; n < partNum; n++) {String dataPart = "";if (n == partNum - 1) {dataPart = DataUtils.hex2(data, n * 20, lastPartLen - 1);} else {dataPart = DataUtils.hex2(data, n * 20, 19);}bytesList.add(DataUtils.hexStrToByteArray(dataPart));}return bytesList;}

2.2 发送方法

⚠️ 注意:

循环执行write发送指令时需间隔一小段时间发送,通过线程休眠实现。

for (byte[] data : dataList) {if (dataList.size() > 1) {try {Thread.sleep(10);} catch (InterruptedException e) {}}mBluetoothClient.write(mac, UUID.fromString(serviceUUID), UUID.fromString(writeUUID), data, new BleWriteResponse() {@Overridepublic void onResponse(int code) {if (code == REQUEST_SUCCESS) {}}});}

3 工具类
3.1 字节数组转十六进制字符串

static public String hex2(byte[] buf, int off, int len) {StringBuilder sb = new StringBuilder(len * 2);for (int j = off; j <= off + len; j++) {sb.append(hexString.charAt((buf[j] & 0xf0) >> 4));sb.append(hexString.charAt((buf[j] & 0x0f) >> 0));}return sb.toString();}

3.2 十六进制字符串转字节数组

public static byte[] hexStrToByteArray(String hexStr) {if (hexStr == null) {return null;}if (hexStr.length() == 0) {return new byte[0];}byte[] byteArray = new byte[hexStr.length() / 2];for (int i = 0; i < byteArray.length; i++) {String subStr = hexStr.substring(2 * i, 2 * i + 2);byteArray[i] = ((byte) Integer.parseInt(subStr, 16));}return byteArray;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。