Reputation: 121
In my application, I got the READ and WRITE to work on specific BluetoothGattCharacteristic
objects.
The BluetoothGattCallback
onCharacteristicWrite
and onCharacteristicRead
are properly called.
I have then tried to setup the NOTIFY option so my Android app gets notified when a specific characteristic on the device changes.
I have set this up via the following code:
// Local notifications
mGatt.setCharacteristicNotification(statusTypeCharacteristic, notify);
// Remote notifications
BluetoothGattDescriptor desc = statusTypeCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
Log.d("Descriptor", desc.toString());
boolean test;
test = desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); // return value = true
test = mGatt.writeDescriptor(desc); // return value = true
When the characteristic changes, the callback: onCharacteristicChanged
is being called as expected
However, now all READ and WRITE operations do not work anymore. When I comment the lines dealing with the descriptor, the READ and WRITE work again.
A part I am very unclear is around the UUID
used to get the descriptor. Is it correct? Should I scan instead all descriptors from the characteristic and enable notification on one? How do I know which one to set as I have multiple ones coming back?
Upvotes: 3
Views: 3580
Reputation: 121
Ok, so I have figured out the issue. At the beginning of my application, I am configuring (i.e. writing) to lots of descriptors. 2 issues with it: 1- A descriptor can only be written one at a time 2- No read/write operations can happen when a descriptor is being written to
The fix is to create a queue of write descriptor operations and perform the next descriptor write in the onDescriptorWrite callback.
private void writeGattDescriptor(BluetoothGattDescriptor d) {
//put the descriptor into the write queue
descriptorWriteQueue.add(d);
//if there is only 1 item in the queue, then write it. If more than 1, we handle asynchronously in the
// callback
if(descriptorWriteQueue.size() == 1) {
mGatt.writeDescriptor(d);
}
}
And then in the callback:
@Override
public void onDescriptorWrite (BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
// Called when the descriptor is updated for notification
Log.d("onDescriptorWrite", descriptor.getUuid().toString());
// pop the item that we just finishing writing
descriptorWriteQueue.remove();
// if there is more to write, do it!
if(descriptorWriteQueue.size() > 0) {
mGatt.writeDescriptor(descriptorWriteQueue.element());
}
// Inform the framework that the scope has connected, configured and ready to process commands
if(descriptorWriteQueue.size() == 0) {
// Do something else, such as reads and writes
}
}
Upvotes: 1