简体   繁体   中英

Unable to Read from BLE Device, Write is working (Android)

I am trying to read values from BLE device. Steps I followed:

  1. I am able to discover the BLE device and connect to it.
  2. I am able to find the required characteristic by parsing through the services and get the GattCharacteristic.
  3. I am able to write a value to the BLE device characteristic and that's verified.
  4. The properties for that characteristic that I am trying to read the value from are: READ, WRITE and INDICATE/NOTIFY.

The functions I am using for read and write are as follows:

a) Read function:

 public void readCharacteristic(BluetoothGattCharacteristic characteristic) 
{
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }

    boolean status;
Log.w(TAG, "SCBABLe: Writing BLuetooth");
status=mBluetoothGatt.readCharacteristic(characteristic);

if(status) {

    Log.w(TAG, "Read Successfully");
}

else
{
    Log.w(TAG, "Read Unsuccessfully");

}

   }

b) Write function

public void writeCharacteristic(BluetoothGattCharacteristic characteristic)
{
    if (mBluetoothAdapter == null || mBluetoothGatt == null)
    {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    boolean status;
    Log.w(TAG, "SCBABLe: Writing BLuetooth");
    status=mBluetoothGatt.writeCharacteristic(characteristic);

    if(status) {

        Log.w(TAG, "Write Successfully");
    }

    else
    {
        Log.w(TAG, "Write Unuccessfully");

    }
}

I am calling the above two from a different activity, after I get the required characteristic(by matching the UUIDs).

//Current Activity Name: DeviceControlActivity
//BluetoothLeService is the other activity where Read and write are defined


private static final DeviceControlActivity holder1 = new DeviceControlActivity();

public BluetoothGattCharacteristic reqChar;
public BluetoothLeService reqService;
private BluetoothLeService mBluetoothLeService;

private void displayGattServices(List<BluetoothGattService> gattServices) 
{
  if (gattServices == null) return;
    String uuid = null;
  for (BluetoothGattService gattService : gattServices) 
    {
        uuid = gattService.getUuid().toString();
        // Loops through available Characteristics.
        for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) 
        {

                uuid = gattCharacteristic.getUuid().toString();
        //SampleGattAttributes.UNKNOWN_CHARACTERISTIC is the hardcoded uuid against which i am checking     
       if((uuid.equals((SampleGattAttributes.UNKNOWN_CHARACTERISTIC))))
       {
          holder1.reqChar = gattCharacteristic;
          holder1.reqService = mBluetoothLeService;

          //Call for write
          byte [] byte1= {0x01, 0x10};

          holder1.reqChar.setValue(byte1);
          holder1.reqService.writeCharacteristic(holder1.reqChar);

          //Call for read

          holder1.reqService.readCharacteristic(holder1.reqChar);

Result: Read function is returning false and write function is returning true so the value is getting written successfully for the required characteristic.(verified it)

Please, could anyone help and tell why the read is not getting executed? Why is it still returning false when it has Read as property and proper value defined?

The problem is in these few lines.

holder1.reqService.writeCharacteristic(holder1.reqChar);

//Call for read

holder1.reqService.readCharacteristic(holder1.reqChar);

After calling writeCharacteristic, if you do any extra read/write/etc. , the call will not be executed and return false. You have to wait for BluetoothGattCallback.onCharacteristicWrite before doing further operation.

In the Android BLE implementation, the gatt operation calls need to be queued so that only one operation (read, write, etc.) is in effect at a time. So for example, after gatt.readCharacteristic(characteristicX) is called, you need to wait for the gatt callback BluetoothGattCallback.onCharacteristicRead() to indicate the read is finished. If you initiate a second gatt.readCharacteristic() operation before the previous one completes, the second one will fail (by returning false) This goes for all of the gatt.XXX() operations.

Its a little work, but I think the best solution is to create a command queue for all the gatt operations and run them one at a time. You can use the command pattern to accomplish this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM