本文简要介绍如何在Android中进行BLE device的读写,实验平台Android 7, 编译SDK 28(android 9).

本文说明在Android BLE Connect connect到device后继续进行数据读写.

获取读写对象 链接到标题

Characteristic 链接到标题

通过UUID从service中找到要读写的Characteristic,例如我这里打算读温度

private static final UUID TEMPE_CHARACTERISTIC_UUID = UUID.fromString("00002A6E-0000-1000-8000-00805f9b34fb");
BluetoothGattCharacteristic mSchr;
for(BluetoothGattService ser: mServiceList){
    mSchr = ser.getCharacteristic(TEMPE_CHARACTERISTIC_UUID);
}

Descriptor 链接到标题

通过UUID从Characteristic中找到要读写的Descriptor,例如我这里打算读温度传感器测量的Trigger方式

private static final UUID EST_DESCRIPTOR_UUID = UUID.fromString("0000290d-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor mSdes;
for(BluetoothGattService ser: mServiceList){

    List<BluetoothGattCharacteristic> chrs = ser.getCharacteristics();

    for(BluetoothGattCharacteristic chr:chrs){
        mSdes = chr.getDescriptor(EST_DESCRIPTOR_UUID);
        break;
    }
}

读&写 链接到标题

值得注意的是无论读写都是异步的,在调用读/写API后需要等到回调执行后才能再调用读/写API,如果回调发生之前调用读/写API无效

Characteristic 链接到标题

链接到标题

//发起读
mGatt.readCharacteristic(mSchr);

//mGattCallback(BluetoothGattCallback) 中重写onCharacteristicRead
//当读完成后,会回调中重写onCharacteristicRead,使用getXXXValue取回数据
 @Override
 public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    super.onCharacteristicRead(gatt, characteristic, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        mStr = " ";
        if (characteristic.getUuid().equals(TEMPE_CHARACTERISTIC_UUID)) {
            //温度是以u16_t传输,因此按照FORMAT_UINT16读
            mStr = "Temp: " + characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 0);
        } 

        mShowString.add(mStr);
    }

}

回调中通过getValue有下面几种方式,这个需要根据使用的GATT profiles定义或自定义的Characteristic 的Value格式来决定给用那种

  • byte[] getValue()
  • Integer getIntValue(int formatType, int offset)
  • Float getFloatValue(int formatType, int offset)
  • String getStringValue(int offset)

链接到标题

Characteristic的写和Descriptor类似,见后面Descriptor的说明,步骤大致如下:

//写入
mStr.setValue(xxx);
mGatt.writeCharacteristic(mStr);

//等待回调通知完成写入
 @Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    super.onCharacteristicWrite(gatt, characteristic, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        //写入完成
    }
}

和getXXXValue,写入也有对应的一组

  • boolean setValue(byte[] value)
  • boolean setValue(int value, int formatType, int offset)
  • boolean setValue(int mantissa, int exponent, int formatType, int offset)
  • boolean setValue(String value)

Descriptor 链接到标题

链接到标题

//发起读
mGatt.readDescriptor(mSdes);

//mGattCallback(BluetoothGattCallback) onDescriptorRead
//当读完成后,会回调中重写onDescriptorRead,使用getValue取回数据
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    super.onDescriptorRead(gatt, descriptor, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        mStr = " ";

        if(descriptor.getUuid().equals(EST_DESCRIPTOR_UUID)){
            byte[] x = descriptor.getValue();
            mStr = "Name: " + x[0];
        }

        mShowString.add(mStr);
    }
}

与Characteristic不一样Descriptor的读取数据只有byte[] getValue() ,那回的是ram数据完全靠自己解析

链接到标题

//写入
byte[] x = new byte[]{2};
mSdes.setValue(x);
mGatt.writeDescriptor(mSdes);

//mGattCallback(BluetoothGattCallback) onDescriptorWrite
//当写完成后,会回调中重写onDescriptorWrite,之后方可进行下一次读写
 @Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
    super.onDescriptorWrite(gatt, descriptor, status);
    if (status == BluetoothGatt.GATT_SUCCESS) {
        if(descriptor.getUuid().equals(EST_DESCRIPTOR_UUID)){
            mHandler.post(new Runnable() {

                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, "Write Des done", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}

和Descriptor读一样,写入也只有boolean setValue(byte[] value),需要又使用者自己控制raw数据

参考 链接到标题

https://developer.android.com/guide/topics/connectivity/bluetooth-le#read