mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-24 01:03:20 +02:00
Try to run all ble commands on the main thread
This commit is contained in:
@@ -80,7 +80,6 @@ public abstract class BluetoothCommunication {
|
||||
private Queue<GattObjectValue<BluetoothGattDescriptor>> descriptorRequestQueue;
|
||||
private Queue<GattObjectValue<BluetoothGattCharacteristic>> characteristicRequestQueue;
|
||||
private boolean openRequest;
|
||||
private final Object lock = new Object();
|
||||
|
||||
public BluetoothCommunication(Context context)
|
||||
{
|
||||
@@ -240,11 +239,9 @@ public abstract class BluetoothCommunication {
|
||||
* @param btMachineState the machine state that should be set.
|
||||
*/
|
||||
protected void setBtMachineState(BT_MACHINE_STATE btMachineState) {
|
||||
synchronized (lock) {
|
||||
this.btMachineState = btMachineState;
|
||||
handleRequests();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a byte array to a Bluetooth device.
|
||||
@@ -254,14 +251,12 @@ public abstract class BluetoothCommunication {
|
||||
* @param bytes the bytes that should be write
|
||||
*/
|
||||
protected void writeBytes(UUID service, UUID characteristic, byte[] bytes) {
|
||||
synchronized (lock) {
|
||||
characteristicRequestQueue.add(
|
||||
new GattObjectValue<>(
|
||||
bluetoothGatt.getService(service).getCharacteristic(characteristic),
|
||||
bytes));
|
||||
handleRequests();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bytes from a Bluetooth device.
|
||||
@@ -301,14 +296,12 @@ public abstract class BluetoothCommunication {
|
||||
bluetoothGatt.getService(service).getCharacteristic(characteristic);
|
||||
bluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
|
||||
|
||||
synchronized (lock) {
|
||||
descriptorRequestQueue.add(
|
||||
new GattObjectValue<>(
|
||||
gattCharacteristic.getDescriptor(descriptor),
|
||||
BluetoothGattDescriptor.ENABLE_INDICATION_VALUE));
|
||||
handleRequests();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
@@ -328,14 +321,12 @@ public abstract class BluetoothCommunication {
|
||||
bluetoothGatt.getService(service).getCharacteristic(characteristic);
|
||||
bluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
|
||||
|
||||
synchronized (lock) {
|
||||
descriptorRequestQueue.add(
|
||||
new GattObjectValue<>(
|
||||
gattCharacteristic.getDescriptor(descriptor),
|
||||
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
|
||||
handleRequests();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
@@ -354,14 +345,12 @@ public abstract class BluetoothCommunication {
|
||||
bluetoothGatt.getService(service).getCharacteristic(characteristic);
|
||||
bluetoothGatt.setCharacteristicNotification(gattCharacteristic, false);
|
||||
|
||||
synchronized (lock) {
|
||||
descriptorRequestQueue.add(
|
||||
new GattObjectValue<>(
|
||||
gattCharacteristic.getDescriptor(descriptor),
|
||||
BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
|
||||
handleRequests();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a byte array to hex for debugging purpose
|
||||
@@ -415,6 +404,8 @@ public abstract class BluetoothCommunication {
|
||||
* @param hwAddress the Bluetooth address to connect to
|
||||
*/
|
||||
public void connect(String hwAddress) {
|
||||
disconnect(false);
|
||||
|
||||
logBluetoothStatus();
|
||||
|
||||
// Some good tips to improve BLE connections:
|
||||
@@ -481,6 +472,7 @@ public abstract class BluetoothCommunication {
|
||||
if (!device.getAddress().equals(hwAddress)) {
|
||||
return;
|
||||
}
|
||||
// Stop scan and connect to the device on the main thread
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -496,15 +488,14 @@ public abstract class BluetoothCommunication {
|
||||
Timber.d("Starting LE scan for device [%s]", hwAddress);
|
||||
btAdapter.startLeScan(leScanCallback);
|
||||
|
||||
// Stop scan and try to connect to the device directly if the device isn't found in time
|
||||
handler.postAtTime(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Timber.d("Device not found in LE scan, connecting directly");
|
||||
synchronized (lock) {
|
||||
stopLeScan();
|
||||
connectGatt(hwAddress);
|
||||
}
|
||||
}
|
||||
}, leScanCallback, SystemClock.uptimeMillis() + LE_SCAN_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
@@ -521,7 +512,6 @@ public abstract class BluetoothCommunication {
|
||||
* Disconnect from a Bluetooth device
|
||||
*/
|
||||
public void disconnect(boolean doCleanup) {
|
||||
synchronized (lock) {
|
||||
stopLeScan();
|
||||
|
||||
if (bluetoothGatt == null) {
|
||||
@@ -530,9 +520,6 @@ public abstract class BluetoothCommunication {
|
||||
|
||||
Timber.i("Disconnecting%s", doCleanup ? " (with cleanup)" : "");
|
||||
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
callbackBtHandler = null;
|
||||
|
||||
if (doCleanup) {
|
||||
if (btMachineState != BT_MACHINE_STATE.BT_CLEANUP_STATE) {
|
||||
setBtMachineState(BT_MACHINE_STATE.BT_CLEANUP_STATE);
|
||||
@@ -541,13 +528,12 @@ public abstract class BluetoothCommunication {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (lock) {
|
||||
if (openRequest) {
|
||||
handler.postDelayed(this, 10);
|
||||
} else {
|
||||
bluetoothGatt.close();
|
||||
bluetoothGatt = null;
|
||||
}
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -556,7 +542,9 @@ public abstract class BluetoothCommunication {
|
||||
bluetoothGatt.close();
|
||||
bluetoothGatt = null;
|
||||
}
|
||||
}
|
||||
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
callbackBtHandler = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -586,7 +574,6 @@ public abstract class BluetoothCommunication {
|
||||
}
|
||||
|
||||
private void handleRequests() {
|
||||
synchronized (lock) {
|
||||
// check for pending request
|
||||
if (openRequest) {
|
||||
Timber.d("Request pending (queue %d %d)",
|
||||
@@ -615,8 +602,9 @@ public abstract class BluetoothCommunication {
|
||||
if (characteristic != null) {
|
||||
characteristic.gattObject.setValue(characteristic.value);
|
||||
|
||||
Timber.d("Write characteristic %s: %s (queue: %d %d)",
|
||||
Timber.d("Write characteristic %s: %s (type: %d; queue: %d %d)",
|
||||
characteristic.gattObject.getUuid(), byteInHex(characteristic.gattObject.getValue()),
|
||||
characteristic.gattObject.getWriteType(),
|
||||
descriptorRequestQueue.size(), characteristicRequestQueue.size());
|
||||
if (!bluetoothGatt.writeCharacteristic(characteristic.gattObject)) {
|
||||
Timber.e("Failed to initiate write of characteristic %s",
|
||||
@@ -629,7 +617,6 @@ public abstract class BluetoothCommunication {
|
||||
// After every command was executed, continue with the next step
|
||||
nextMachineStateStep();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Gatt callback class to set up a Bluetooth state machine.
|
||||
@@ -640,9 +627,10 @@ public abstract class BluetoothCommunication {
|
||||
Timber.d("onConnectionStateChange: status=%d, newState=%d", status, newState);
|
||||
|
||||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||
synchronized (lock) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
stopLeScan();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
gatt.readPhy();
|
||||
@@ -650,25 +638,32 @@ public abstract class BluetoothCommunication {
|
||||
|
||||
connectionEstablished = true;
|
||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_ESTABLISHED);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Empty
|
||||
}
|
||||
// Wait a short while after connecting before scanning for services
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!gatt.discoverServices()) {
|
||||
Timber.e("Could not start service discovery");
|
||||
setBtStatus(BT_STATUS_CODE.BT_CONNECTION_LOST);
|
||||
disconnect(false);
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setBtStatus(connectionEstablished
|
||||
? BT_STATUS_CODE.BT_CONNECTION_LOST
|
||||
: BT_STATUS_CODE.BT_NO_DEVICE_FOUND);
|
||||
disconnect(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -677,12 +672,22 @@ public abstract class BluetoothCommunication {
|
||||
status, gatt.getServices().size());
|
||||
|
||||
if (gatt.getServices().isEmpty()) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setBtStatus(BT_STATUS_CODE.BT_UNEXPECTED_ERROR, "No services found");
|
||||
disconnect(false);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
// Sleeping a while after discovering services fixes connection problems.
|
||||
// See https://github.com/NordicSemiconductor/Android-DFU-Library/issues/10
|
||||
// for some technical background.
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cmdStepNr = 0;
|
||||
initStepNr = 0;
|
||||
cleanupStepNr = 0;
|
||||
@@ -691,21 +696,12 @@ public abstract class BluetoothCommunication {
|
||||
characteristicRequestQueue = new LinkedList<>();
|
||||
descriptorRequestQueue = new LinkedList<>();
|
||||
openRequest = false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Sleeping a while after discovering services fixes connection problems.
|
||||
// See https://github.com/NordicSemiconductor/Android-DFU-Library/issues/10
|
||||
// for some technical background.
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
// Start the state machine
|
||||
setBtMachineState(BT_MACHINE_STATE.BT_INIT_STATE);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
|
||||
@@ -723,11 +719,9 @@ public abstract class BluetoothCommunication {
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (lock) {
|
||||
openRequest = false;
|
||||
handleRequests();
|
||||
}
|
||||
}
|
||||
}, 60);
|
||||
}
|
||||
|
||||
@@ -746,27 +740,33 @@ public abstract class BluetoothCommunication {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCharacteristicRead(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic,
|
||||
int status) {
|
||||
public void onCharacteristicRead(final BluetoothGatt gatt,
|
||||
final BluetoothGattCharacteristic characteristic,
|
||||
final int status) {
|
||||
Timber.d("onCharacteristicRead %s (status=%d): %s",
|
||||
characteristic.getUuid(), status, byteInHex(characteristic.getValue()));
|
||||
|
||||
synchronized (lock) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onBluetoothDataRead(gatt, characteristic, status);
|
||||
postDelayedHandleRequests();
|
||||
}
|
||||
});
|
||||
postDelayedHandleRequests();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
public void onCharacteristicChanged(final BluetoothGatt gatt,
|
||||
final BluetoothGattCharacteristic characteristic) {
|
||||
Timber.d("onCharacteristicChanged %s: %s",
|
||||
characteristic.getUuid(), byteInHex(characteristic.getValue()));
|
||||
|
||||
synchronized (lock) {
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onBluetoothDataChange(gatt, characteristic);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Reference in New Issue
Block a user