蓝牙开发协议封装

一般通讯协议格式类似下面这样

android蓝牙传输 安卓6.0蓝牙传输协议_数据


一般在蓝牙开发中数据的传输是以16进制形式传输的,比如 00 06 00 61 01 00 66,

那么遇到这种16进制的数据,我们需要把它转化成实体类, 可以写一个基类,专门处理数据的长度,索引,和校验 . 如果有其他数据类型 只要继承这个基类 就可以制定自己的数据内容. 基类需要做基本的解析数据和生成数据, 子类只需要生成数据和解析数据即可.

基类如下

import com.tongtailian.www.stir.utils.LogUtil;

import java.io.UnsupportedEncodingException;

/**
 * @author liuml
 * @explain
 * @time 2020/10/11 11:21
 */
public class BaseDataFram {
    int data32 = 32;
    int data16 = 16;
    int data8 = 8;
    int data4 = 4;
    int data2 = 2;

    int hex16 = 16;

    public String
            /** 字节长度 从长度开始到数据最后一个字节的字节数量 */
            len,
    /**
     * 命令类型
     */
    type,
    /**
     * 请求的参数
     */
    param,
    /**
     * 返回值有的状态
     */
    state,
    /**
     * 数据
     */
    data,
    /**
     * 所有的发送出去的数据帧
     */
    results,
    /**
     * 接受的数据帧
     */
    receive;

//    public BaseDataFram(String type, String param, String data) {
//        this.type = type;
//        this.param = param;
//        this.data = data;
//    }


    public String getLen() {
        return len;
    }

    public void setLen(String len) {
        this.len = len;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getParam() {
        return param;
    }

    public void setParam(String param) {
        this.param = param;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getResults() {
        return results;
    }

    public void setResults(String results) {
        this.results = results;
    }

    public String getReceive() {
        return receive;
    }

    public void setReceive(String receive) {
        this.receive = receive;
    }

    /**
     * 组成发送的数据
     *
     * @return String
     */
    public String getSendData() {
        LogUtil.d("type = " + type);
        LogUtil.d("param = " + param);
        LogUtil.d("data = " + data);
        //索引 命令, 参数, 数据
        String result = "00" + type + param + data;
        LogUtil.d("result = " + result);
        //计算数据长度 2 是算上最后的校验值
        int len_int = 2 + hexToByteArray(result).length;
        len = Integer.toHexString(len_int);
        ;//10进制转化16进制
//        len = byteToHex(len_int);//10进制转化
        LogUtil.d("len_int = " + len_int);
        LogUtil.d("len = " + len);
        //组成完整的字符串 补0
        len = String.format("%4s", Integer.toHexString(len_int)).replace(' ', '0');
        LogUtil.d("replace = " + len);
        results = len + result;
        String checkXor = checkXor(results);//从长度开始到数据最后一个字节,逐字异或(XOR)得到校验值。
//        LogUtil.d("checkXor = " + checkXor);
        results = results + checkXor;
//        LogUtil.d("result = " + results);
        return results;
    }

    /**
     * 字符串左侧补零
     * @param str
     * @param strLength
     * @return
     */
    public static String addZeroForNumLeft(String str, int strLength) {
        int strLen = str.length();
        if (strLen < strLength) {
            while (strLen < strLength) {
                StringBuffer sb = new StringBuffer();
                sb.append("0").append(str);// 左补0
                // sb.append(str).append("0");//右补0
                str = sb.toString();
                strLen = str.length();
            }
        }

        return str;
    }

    /**
     * 字符串右侧补零
     * @param str
     * @param strLength
     * @return
     */
    public static String addZeroForNumRight(String str, int strLength) {
        int strLen = str.length();
        if (strLen < strLength) {
            while (strLen < strLength) {
                StringBuffer sb = new StringBuffer();
                sb.append(str).append("0");//右补0
                str = sb.toString();
                strLen = str.length();
            }
        }

        return str;
    }

    public int parseIntResult(int position, int move) {
        String sClrSelect = data.substring(position, position + move);
        String temp = reverseHex(sClrSelect);
        int parseInt = Integer.parseInt(temp, hex16);
        return parseInt;
    }

    /**
     * 异或校验
     *
     * @param data 十六进制串
     * @return checkData  十六进制串
     */
    public static String checkXor(String data) {
        int checkData = 0;
        for (int i = 0; i < data.length(); i = i + 2) {
            //将十六进制字符串转成十进制
            int start = Integer.parseInt(data.substring(i, i + 2), 16);
            //进行异或运算
            checkData = start ^ checkData;
        }
        return integerToHexString(checkData);
    }

    public static String chinese2HexFormat(String str, int strLength) {
        return addZeroForNumRight(str2HexStr(str), strLength);
    }

    public static String int2HexFormat(int num, int strLength) {
        return addZeroForNumLeft(byteToHex(num), strLength);
    }

    /**
     * 中文转十六进制
     *
     * @param str
     * @return
     */
    public static String str2HexStr(String str) {
        byte[] arrInput;
        try {
            char[] chars = "0123456789ABCDEF".toCharArray();
            arrInput = str.getBytes("gbk");
            StringBuilder sOutput = new StringBuilder(arrInput.length);
            int bit;
            for (int i = 0; i < arrInput.length; i++) {
                bit = (arrInput[i] & 0x0f0) >> 4;
                sOutput.append(chars[bit]);
                bit = arrInput[i] & 0x0f;
                sOutput.append(chars[bit]);
            }
            return sOutput.toString().toLowerCase();//转小写
        } catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 十六进制转换字符串
     *
     * @param hexStr Byte字符串(Byte之间无分隔符 如:[616C6B])
     * @return String 对应的字符串
     */
    public static String hexStr2Str(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;

        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        try {
            return new String(bytes, "gbk");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 将十进制整数转为十六进制数,并补位
     */
    public static String integerToHexString(int s) {
        String ss = Integer.toHexString(s);
        if (ss.length() % 2 != 0) {
            ss = "0" + ss;//0F格式
        }
        return ss.toUpperCase();
    }


    /**
     * 高低位转换
     *
     * @param hex
     * @return
     */
    static String reverseHex(final String hex) {
        final char[] charArray = hex.toCharArray();
        final int length = charArray.length;
        final int times = length / 2;
        for (int c1i = 0; c1i < times; c1i += 2) {
            final int c2i = c1i + 1;
            final char c1 = charArray[c1i];
            final char c2 = charArray[c2i];
            final int c3i = length - c1i - 2;
            final int c4i = length - c1i - 1;
            charArray[c1i] = charArray[c3i];
            charArray[c2i] = charArray[c4i];
            charArray[c3i] = c1;
            charArray[c4i] = c2;
        }
        return new String(charArray);
    }
    /**
     * 16进制 按位异或
     *
     * @param key   16进制 String
     * @param value 16进制 String
     * @return 16进制 String
     */
//    public static String hexBitwiseXOR(String key, String value) {
//        byte[] bKey = NumUtil.hexString2Bytes(key);
//        byte[] bValue = NumUtil.hexString2Bytes(value);
//        byte[] bResult = new byte[bKey.length];
//
//        for (int i = 0; i < bKey.length; i++) {
//            bResult[i] = (byte) (bKey[i] ^ bValue[i]);
//        }
//        return bytesToHexString(bResult);
//    }

    /**
     * 将byte数组转为16进制字符串
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte aSrc : src) {
            int v = aSrc & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv.toUpperCase());
        }
        return stringBuilder.toString();
    }

    /**
     * 将一个整形化为十六进制,并以字符串的形式返回
     */
    private final static String[] hexArray = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static String byteToHex(int n) {
        if (n < 0) {
            n = n + 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexArray[d1] + hexArray[d2];
    }

    /**
     * hex字符串转byte数组
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte数组结果
     */
    public static byte[] hexToByteArray(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            //奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            //偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    /**
     *  
     *  * Hex字符串转byte 
     *  * @param inHex 待转换的Hex字符串 
     *  * @return  转换后的byte 
     *  
     */

    public static byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

    /**
     * @param frame 接受到的完整数据帧
     * @return data 数据部分
     */
    public void parseFrame(String frame) {
//        if (frame.length()<26) return "";
        receive = frame;
        String dataLenStr = (receive.substring(6, receive.length() - 2));
        LogUtil.d("dataLenStr = " + dataLenStr);
        //命令
        type = dataLenStr.substring(0, 2);

        //状态
        state = dataLenStr.substring(2, 4);

        //数据
        data = dataLenStr.substring(4);
//        // 计算长度
//        int dataLen = hexToByteArray(dataLenStr).length;
//        // 计算总长度
//        int totalLength = (13 + 3 + dataLen) * 2;
//        if (receive.length() >= totalLength) {
//            return receive.substring(26, 26 + dataLen * 2);
//        }
    }


}

里面有一些工具类, 中文转16进制数据,16进制数据转中文,数字转16进制,16进制转数字等等. 主要是用于解析数据和生成数据的作用.