> ####**背景**
BLE中的BluetoothGatt类是是蓝牙4.0 GATT profile的封装。通过这个对象,我们就能和Bluetooth Smart或者Smart Ready设备通信,进行相关操作。期中的关键就是对**characteristic**的读写。Characteristic可以理解为一个数据类型,它包括一个value和0至多个对次value的描述,是构成蓝牙4.0 GATT service的基本元素。
>写Characteristics需要先调用BluetoothGattCharacteristic类中的setValue()方法,更改手机本地的characteristic值。然后调用BluetoothGatt类中writeCharacteristic(BluetoothGattCharacteristic characteristic),修改改远程设备中相应的数据。
setValue()有四个重载的方法:
>> * setValue(int value, int formatType, int offset)
> * setValue(byte[] value)
> * setValue(String value)
> + setValue(int mantissa, int exponent, int formatType, int offset)
> 之前LED灯的蓝牙协议栈中规定的characteristic是6位十六进制数,就必须使用setValue(byte[] value)这个方法。而用Color类获取的RGB值是int类型的,从十进制的int到十六进制的byte数组,这里面的转换还是有点意思的。
现在说说大概的思路:
> 1.将十进制的int数转换成十六进制的String字符
2.将十六进制的Sring字符解析成十六进制的byte数组
看上去很简单的样子...想当初卡在这点很长时间。
比较难的就是int转String中的长度问题。RGB的值是0~255,转换成十六进制是0~0xFF。Integer.toHesString()默认只会将0转换成'0',16转换成"10",长度是不一致的,为了保持数据格式必须将0转换成"00"。我的解决办法是:
```java
int a = 0;
String as = Integer.toHexString(a | 0xFFFFFF00).substring(6) ;
```
int占4个字节32位,a | 0xFFFFFF00表示将正数a的前24位置一,这样toHexString输出一个小于等于15的byte整型的十六进制时,倒数第二位为零且不会被丢弃,然后通过substring方法进行截取最后两位即可。若实际中存在a为负的,使用:
```java
String as = Integer.toHexString((a & 0x000000FF) | 0xFFFFFF00).substring(6) ;
```
进行转换。
就下来就可以将字符转换成十六进制的byte数组:
```java
byte[] ab = Integer.parseInt(as, 16);
```
parseInt(String s, int radix) 表示使用第二个参数指定的基数,将字符串参数解析为有符号的整数。
如何将字符串"aaaaaa"转换成{(byte)0xaa,(byte)0xaa,(byte)0xaa}呢?一种方法是先将"aaaaaa"转换成byte数组,做一个循环,每2个字符转换成一个十六进制数:
```java
public static byte[] hex2byte(byte[] b) {
byte[] b2 = new byte[b.length / 2];
for (int n = 0; n < b.length; n += 2) {
String item = new String(b, n, 2);
// 两位一组
b2[n / 2] = (byte) Integer.parseInt(item, 16);
}
b = null;
return b2;
}
```