蓝牙开发协议封装
一般通讯协议格式类似下面这样
一般在蓝牙开发中数据的传输是以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进制转数字等等. 主要是用于解析数据和生成数据的作用.