Wait for writeWithoutResponse completion (#166)

* Wait for writeWithoutResponse request completion on Android

* Wait for writeWithoutResponse request completion on Darwin

* Add WriteWithoutResponse button in example app

* Update changelog and bump version

* Apply suggestions from code review

Co-authored-by: Foti Dim <foti@navideck.com>

---------

Co-authored-by: Foti Dim <foti@navideck.com>
This commit is contained in:
Rohit Sangwan
2025-06-26 11:35:59 +05:30
committed by GitHub
parent 0008231bdf
commit d56851cbfb
7 changed files with 60 additions and 34 deletions
@@ -153,6 +153,9 @@ fun Int.parseGattErrorCode(): String? {
BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION -> "GATT_INSUFFICIENT_ENCRYPTION"
BluetoothGatt.GATT_CONNECTION_CONGESTED -> "GATT_CONNECTION_CONGESTED"
BluetoothGatt.GATT_FAILURE -> "GATT_FAILURE"
BluetoothStatusCodes.ERROR_GATT_WRITE_NOT_ALLOWED -> "ERROR_GATT_WRITE_NOT_ALLOWED"
BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY -> "ERROR_GATT_WRITE_REQUEST_BUSY"
BluetoothStatusCodes.FEATURE_NOT_CONFIGURED -> "FEATURE_NOT_CONFIGURED"
0x01 -> "GATT_INVALID_HANDLE"
0x04 -> "GATT_INVALID_PDU"
0x09 -> "GATT_PREPARE_QUEUE_FULL"
@@ -469,34 +469,39 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
}
val writeFuture = WriteResultFuture(
gatt.device.address,
gattCharacteristic.uuid.toString(),
gattCharacteristic.service.uuid.toString(),
callback
)
// Wait for the result
writeResultFutureList.add(writeFuture)
val result = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val writeResult = gatt.writeCharacteristic(gattCharacteristic, value, writeType)
writeResult == BluetoothGatt.GATT_SUCCESS
gatt.writeCharacteristic(gattCharacteristic, value, writeType)
} else {
@Suppress("DEPRECATION")
gattCharacteristic.value = value
gattCharacteristic.writeType = writeType
@Suppress("DEPRECATION")
gatt.writeCharacteristic(gattCharacteristic)
val status = gatt.writeCharacteristic(gattCharacteristic)
if (status) BluetoothGatt.GATT_SUCCESS else BluetoothGatt.GATT_FAILURE
}
if (!result) {
callback(Result.failure(FlutterError("Failed", "Failed to write", null)))
return
}
if (writeType == BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT) {
// wait for the result
writeResultFutureList.add(
WriteResultFuture(
gatt.device.address,
gattCharacteristic.uuid.toString(),
gattCharacteristic.service.uuid.toString(),
callback
if (result != BluetoothGatt.GATT_SUCCESS) {
writeResultFutureList.remove(writeFuture)
callback(
Result.failure(
FlutterError(
"WriteError",
"Failed to write: ${result.parseGattErrorCode()}",
null
)
)
)
} else {
callback(Result.success(Unit))
}
} catch (e: FlutterError) {
callback(Result.failure(e))