Android蓝牙串口通信遇到的问题

来源:互联网 发布:教育信息化软件 编辑:程序博客网 时间:2024/04/28 02:36

接上篇的协议开发练习。
课设需要用手机和开发板通信,接收开发板发来的传感器数据进行处理输出,并可以控制开发板的执行器。
在写蓝牙的安卓程序期间遇到了很多问题,在此记录以下。

1.数据传输我们采取16进制字节流进行传输,那么就有了字符串和16进制数据转换的问题

public static String bytesToHexString(byte[] bytes) {  //字节流转为16进制串        String result = "";        int i;        for ( i = 0; i < bytes.length; i++) {            String hexString = Integer.toHexString(bytes[i] & 0xFF);            if (hexString.length() == 1) {                hexString = '0' + hexString;            }            result += hexString.toUpperCase();        }        return result;    }    private byte[] hexStringToBytes(String message) { //16进制串转为字节流        int len = message.length() / 2;        char[] chars = message.toCharArray();        String[] hexStr = new String[len];        byte[] bytes = new byte[len];        for (int i = 0, j = 0; j < len; i += 2, j++) {            hexStr[j] = "" + chars[i] + chars[i + 1];            bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);        }        return bytes;    }

2.接收数据时出现错误,大于20字节时,20字节后面的数据丢失,网上搜索发现如下的说法,但我确实没有找到相关说明,暂且这么记吧。
http://zhidao.baidu.com/link?url=k0LLv63E_716T-tkFrn6n805GA-fh4nTPPIl3RyiUBLVyd8l-iWMf6PV-DNe56YjrLqMDUK93uZE68PDJxmHXKvWBT1-gXrQbSyePJccAne

协议规定,payload 最大 27。在协议第六章中的 2.4,刨去 L2CAP 的头,4 个字节,剩下的就 23 个字节 MTU。就是你看到的。ATT 层会用掉上 1 个字节的 op code, 2 个字节的 attribute handle,就剩下 20了。这剩下的 20 字节就是我们常说的发送的 20 字节的数据。

接下来就是将分片的数据组装成一个完整的数据包

    public final int MES_HEAD_LEN = 3;   //包头长度    public final int MES_TAIL_LEN = 2;   //包尾长度    public static boolean devideFlag = false;    public static int DEVIDE_NUM;        //分片数    public byte[] returnByte = new byte[200];    public int[] devideLength = new int[10];    public byte[][] newbyte = new byte[10][];  //接收数据,判断有无分片,并进行包的拼接    public void devideContent(byte[] bytes)    {        int i = 0;    //    newbyte[DEVIDE_NUM] = bytes;        if(bytes[0] == -69) {            if(bytes[1] == Protocal.SLAVE_STA_READY || bytes[1] == Protocal.SLAVE_EXU_SUCCE) {               //从机就绪                if(bytes[2] == Protocal.DIVIDE_DISABLE) {            //数据无分片                    devideFlag = true;                    newbyte[DEVIDE_NUM] = bytes;                    devideLength[DEVIDE_NUM] = bytes.length;                }                else {                                              //数据有分片                    newbyte[DEVIDE_NUM] = bytes;                    devideLength[DEVIDE_NUM] = bytes.length;                    DEVIDE_NUM++;                }            }        }        if(devideFlag) {            Log.d(TAG, "分片数 "+DEVIDE_NUM);            int len;            System.arraycopy(newbyte[0],0,returnByte,0,devideLength[0]-2);            len = devideLength[0]-2;            for (i = 1; i < DEVIDE_NUM+1; i++) {                System.arraycopy(newbyte[i],3,returnByte,len, devideLength[i]-5);                len += devideLength[i]-5;            }            System.arraycopy(newbyte[DEVIDE_NUM],devideLength[DEVIDE_NUM]-2,returnByte,len,2);            DEVIDE_NUM = 0;        }    }

3.数据解析

 //数据解析    /*    by eagle zhao    将16进制串转换为16进制数组data,16进制串中1个字节代表8位如0x11,在16进制串中存储为'1' '1',故需将两个字符转换为1个16进制数字。     */    public void dataAnalysis(String hex) {        char[] message = hex.toString().toCharArray();        int[] data = new int[message.length];        int[][] datadevide = new int[10][];        int j,i,k=0;        for(i = 0,j=0; i < message.length; i++,j++) {            if(message[i] >= '0' && message[i] <= '9') {                data[j] = message[i] - '0';            }else if(message[i] >= 'A' && message[i] <= 'Z') {                data[j] = message[i] - 'A' + 10;            }            data[j] = data[j] << 4;            i++;            if(message[i] >= '0' && message[i] <= '9') {                data[j] += message[i] - '0';            }else if(message[i] >= 'A' && message[i] <= 'Z') {                data[j] += message[i] - 'A' + 10;            }        }        if(data[1] == 0x11) {            listAdapter.add("执行成功");            messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);        }        else if(data[1] == 0x01){     //从机发来数据            outPutCal(data);    //输出数据        }    }
0 0
原创粉丝点击