Reputation: 97008
Android's BLE API (and as far as I can tell, all BLE APIs) are asynchronous and not queued. That is, if you do (pseudocode):
characteristic.write("a");
characteristic.write("b");
The second write will immediately displace the first one, which will never be sent. In practice you have to do something like this:
characteristic.write("a");
void onCharacteristicWrite() {
characteristic.write("b");
}
My question is: Is there a way on Android to check if the BluetoothGatt
has a pending read or write operation, so I can know whether I will be overwriting an existing operation? Or do I need to manually keep track of that myself?
Upvotes: 0
Views: 395
Reputation: 20268
I have another way to propose for you.
Inside a class responsible for sending bluetooth requests declare:
private PriorityBlockingQueue<QueueRequest> queueRequestList;
Then declare a method to send requests:
public void send(byte[] bytes, BTDelegate delegate) {
QueueRequest queueRequest = new QueueRequest(bytes);
if (queueRequestList.size() > 0) {
putOnQueueEnd(queueRequest);
return;
}
putOnQueueEnd(queueRequest);
sendRequest(queueRequest);
}
As you can see this class checks if there are any pending requests. If there are, put on the queue and wait for the last request to complete. If there aren't any elements inside the queue, put it in queue (to know for future requests, that there is a pending request) and immediately send it.
When the response came from BLE device invoke a function:
public void sendNextRequestAgain() {
popFirst();
QueueRequest request = peekFirst();
sendRequest(request);
}
which means: get the next element from queue.
Advantages:
QueueRequest
(data, delegates, time, etc..)A few additional methods:
private void putOnQueueEnd(QueueRequest queueRequest) {
queueRequestList.put(queueRequest);
}
private QueueRequest popFirst() {
return queueRequestList.poll();
}
private QueueRequest peekFirst() {
return queueRequestList.peek();
}
Upvotes: 2