网上的Bluetooth BLE Demo都能实现BLE属性的读取,但写这块,我遇到的问题是:这些Demo都无法对BLE设备进行写数据,即无法修改BLE设备下的属性,如Major ,Minor,UUID等属性。这些Demo都是通过characteristic.setValue(byte[]),然后调用BluetoothGatt对象 mBluetoothGatt.writeCharacteristic(characteristic)进行数据写操作的,我用这样的方法能执行到Callback下的onCharacteristicWrite方法,但写入失败。
下面是我修改BLE设备属性的流程:(一般来说,characteristic是手机与BLE设备交换数据的关键,characteristic有很多跟权限相关的字段,要注意的一个地方是:手机与BLE设备是在连接状态下才能进行写数据)
BLE设备写数据主要分为三个流程:
- (第一步)获取修改数据的权限
- 获取service对象,对应的UUID是“0000FFF0-0000-1000-8000-00805f9b34fb” ;(UUID对应功能见下图)
- 获取characteristic,对应UUID是“0000FFFA-0000-1000-8000-00805f9b34fb” ,该特性是指定授权的
- 调用characteristic.setValue(“AcCrEdItiSOK”.getBytes()),这个”AcCrEdItiSOK”具体是什么,我也还没搞懂,照抄上去就可以了。
- 调用writecharacteristic().
代码如下:
BluetoothGattService service = mBluetoothGatt.getService(UUID.fromString(
"0000FFF0-0000-1000-8000-00805f9b34fb"));
public void wirte1()
{
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(
"0000FFFA-0000-1000-8000-00805f9b34fb"));
characteristic.setValue("AcCrEdItiSOK".getBytes());
mBluetoothGatt.writeCharacteristic(characteristic);
}
- (第二步)获取属性对应的characteristic(这里以修改Minor为例)
- service对象不变,获取Minor属性对应的characteristic对象,对应的UUID是”0000FFF3-0000-1000-8000-00805f9b34fb”。如需读取Minor的值,并不能直接通过characteristic.getValue()来读取,而是先使用readCharacteristic(characteristic),然后在OncharacteristicRead回调函数中使用characteristic.getValue()来读取。
- setValue(new byte[]{1,1}) ;byte数组中传入你想修改的数据,由下图Ibeacon的功能选项图可知,Minor属性对应的长度是2个byte,十六进制,即写入的数据为0x101,修改后读取出来的数值应为十进制的257。
- 调用writecharacteristic().
代码如下:
public void write2()
{
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(
"0000FFF3-0000-1000-8000-00805f9b34fb"));
characteristic.setValue(new byte[]{1,1});
mBluetoothGatt.writeCharacteristic(characteristic);
}
- (第三步)Reboot BLE (写入数据后要reboot,数据才能生效),这里的reboot指的不是将BLE设备关闭再开启,而是使用java代码写入相关characteristic。
- 获取对应reboot的characteristic,对应的UUID是”0000FFFF-0000-1000-8000-00805f9b34fb”
- setValue(Base64.decode(“bWluZXcxMjM”.getBytes(),Base64.DEFAULT))
- 调用writecharacteristic().
public void write3()
{
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(
"0000FFFF-0000-1000-8000-00805f9b34fb"));
//我这个IBeacon设备的密码是“minew123”,通过UnicodeToBase64转换后是"bWluZXcxMjM"
characteristic.setValue(Base64.decode("bWluZXcxMjM".getBytes(),Base64.DEFAULT));
mBluetoothGatt.writeCharacteristic(characteristic);
}
如何将这三段代码整合进去:
以上三个步骤不可直接按顺序写,应该是每个步骤做完写操作后,在CallBack下的回调函数OncharacteristicWrite(…)中依次执行这三个步骤(这样确保每个步骤都是在上一个步骤完成后再执行的。反之,直接将这三个步骤连着写,是修改不了数据的,个人认为原因是只有执行了回调函数才能确保某一操作真正完成)。在OncharacteristicWrite(…)中作个判断,依次执行这三个write()操作。
注意:同理,读操作和写操作也不能写在一块,应执行玩一个操作后,在对应的回调函数中再执行另一个操作,否则,数据写不进去。