Answer the question
In order to leave comments, you need to log in
Why do BLE callbacks "interrupt" the execution of the handler's code?
In my Android application, I work with BLE. I make requests to a remote device and receive asynchronous responses from it in callbacks.
At the same time, I use handler.postDelayed() which closes the connection after a given time if the device is not responding.
poll = true;
deviceNumber = 0;
characteristicValues = new String[bleDevices.size()];
characteristicValues[deviceNumber] = "ERROR"; // в случае успеха "ERROR" заменится на значение характеристики
handler.postDelayed(responseWaiting, RESPONSE_TIMEOUT); //RESPONSE_TIMEOUT=10000
bleDevices.get(deviceNumber).connectGatt(appContext, false, bluetoothGattCallback);
private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
handler.removeCallbacks(responseWaiting);
currentGatt = gatt;
switch (newState) {
case BluetoothGatt.STATE_CONNECTED:
if (poll) {
if (status == BluetoothGatt.GATT_SUCCESS) {
handler.postDelayed(responseWaiting, RESPONSE_TIMEOUT);
gatt.discoverServices();
} else {
nextDevice();
}
} else {
handler.postDelayed(disconnectWaiting, RESPONSE_TIMEOUT);
currentGatt.disconnect();
}
break;
case BluetoothGatt.STATE_DISCONNECTED:
if (poll) {
nextDevice();
} else {
currentGatt.close();
}
break;
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
//…
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
//…
}
};
private void nextDevice() {
currentGatt.close();
deviceNumber++;
if (deviceNumber < bleDevices.size()) {
characteristicValues[deviceNumber] = "ERROR"; // в случае успеха "ERROR" заменится на значение характеристики
handler.postDelayed(responseWaiting, RESPONSE_TIMEOUT);
bleDevices.get(deviceNumber).connectGatt(appContext, false, bluetoothGattCallback);
} else {
fireListeners();
}
}
private void fireListeners() {
for (BLEClientListener bleClientListener : bleClientListeners) {
if (poll) {
poll = false;
bleClientListener.onValuesReceived(characteristicValues);
}
}
}
Answer the question
In order to leave comments, you need to log in
Because work with BLE takes place in a separate service thread (the system itself creates it, and this is the only correct approach for working with any network). And callbacks, respectively, are also called in another thread. You can use the same Handler or BroadcastReceivers to interact with the UI thread. And use your own status flags, of course (like ETA_SHTUKA_CONNECTED, ETA_SHTUCA_WAITING).
Probably the request arises in a separate flow? Try to introduce a timeout function for example, but in general it is desirable that you show the code in which this happens, because it is not clear on the fingers.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question