public static String parseBroad(byte[] scanResult){ if(scanResult!=null){ byte [] data = null; // 存储广播中的自定义数据 try { for (int i = 0; i < scanResult.length; ) { byte v = scanResult[i]; // 长度为0且有效,取长度 if (v > 0) { // 判断类型 if ((scanResult[i + 1]&0xff) == 0xFF) { data = new byte[v-1]; // 0A-FF-6F-73-6E-61-76-2D-78-62-79 (i为0x0a表示长度10, 0xFF为类型,i+2表示从FF之后取数据,取v-1=9个数据,不包含开始的类型) System.arraycopy(scanResult, i+2, data, 0, v - 1); return byte2Str(data); } i = i+v; } i++; continue; } }catch(ArrayIndexOutOfBoundsException e){ Log.e(TAG, "parseBroad: " + e.toString()); } } return null; }
时间: 2024-02-10 14:35:14 浏览: 47
这段代码是解析蓝牙广播包中的自定义数据的方法,下面是每一句代码的解释:
1. `public static String parseBroad(byte[] scanResult)`:定义一个静态方法 parseBroad,接收一个 byte[] 类型的参数 scanResult,表示蓝牙广播包的字节数组,返回一个字符串。
2. `if(scanResult!=null)`:判断 scanResult 是否为 null,如果不为 null,继续执行下面的代码。
3. `byte [] data = null;`:定义一个 byte[] 类型的变量 data,用于存储广播中的自定义数据。
4. `for (int i = 0; i < scanResult.length; )`:使用 for 循环,循环遍历蓝牙广播包中的每一个字节。由于 i 变化不是在循环体中控制,因此不需要写 i++。
5. `byte v = scanResult[i];`:获取 scanResult 数组中第 i 个位置的字节,赋值给变量 v。
6. `if (v > 0) { ... }`:如果 v 大于 0,则说明该字节表示的是数据长度。进入内层 if 判断。
7. `if ((scanResult[i + 1]&0xff) == 0xFF) { ... }`:如果接下来的一个字节是 0xFF,则说明该广播包中包含自定义数据。进入内层 if 判断。
8. `data = new byte[v-1];`:根据数据长度创建一个长度为 v-1 的 byte[] 数组,用于存储自定义数据。因为这个字节表示的是数据长度,所以需要将其减一才能得到实际的数据长度。
9. `System.arraycopy(scanResult, i+2, data, 0, v - 1);`:使用 System.arraycopy 方法将广播包中的自定义数据拷贝到 data 数组中。scanResult 表示源数组,i+2 表示目标数组 data 中拷贝数据的起始位置,v-1 表示要拷贝的数据长度。
10. `return byte2Str(data);`:将 data 数组中的字节码转换为字符串,并返回解析出的自定义数据。
11. `i = i+v;`:将循环变量 i 的值加上 v,跳过已经解析过的字节。
12. `i++;`:将循环变量 i 的值加 1,进入下一个字节的解析。
13. `continue;`:如果执行到这里,说明当前字节不是数据长度也不是自定义数据,进入下一个循环。这里 continue 可以省略,因为下面不再有代码。
14. `catch(ArrayIndexOutOfBoundsException e){...}`:捕获异常,如果出现 ArrayIndexOutOfBoundsException 异常,说明解析过程中访问了 scanResult 数组中不存在的位置,打印异常信息。
15. `return null;`:如果没有解析出自定义数据,则返回 null。
阅读全文