我想使用 Kotlin 协程处理 BLE 的异步回调。连接到一个 BLE 设备需要一个回调对象,就像这样:
现在,
下面是使用
如果我想要编写如下的“顺序代码”:
connectToBle(Context, Boolean, GattCallback)
结果会异步返回,在 GattCallback 对象的方法 onConnectionStateChanged
中实现。在文档中, 我使用了 suspendCoroutine<BluetoothGatt>
来实现它。现在,
onConnectionStateChanged
返回一个 BluetoothGatt 对象,我必须将其保存为全局变量,并用于调用其他方法,例如 discoverServices
、readCharacteristic
、writeCharacteristic
等等,所有这些都会在 GattCallback 对象的不同回调方法中异步返回,如 onServicesDiscovered
, onCharacteristicRead
, onCharacteristicWrite
, 等等。下面是使用
suspendCoroutine
的代码:suspend fun BluetoothDevice.connectToBleDevice(
context: Context,
autoConnect: Boolean = false
) = suspendCoroutine<BluetoothGatt?> { cont ->
connectGatt(context, autoConnect, object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
super.onConnectionStateChange(gatt, status, newState)
Timber.d("onConnectionStateChange: ")
if (status != BluetoothGatt.GATT_SUCCESS) cont.resume(null) else cont.resume(gatt)
// save gatt instance here if success
}
override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
super.onServicesDiscovered(gatt, status)
if (status != BluetoothGatt.GATT_SUCCESS) cont.resume(null) else cont.resume(gatt)
// return list of services if success
}
override fun onCharacteristicRead(
gatt: BluetoothGatt?,
characteristic: BluetoothGattCharacteristic?,
status: Int
) {
super.onCharacteristicRead(gatt, characteristic, status)
if (status != BluetoothGatt.GATT_SUCCESS) cont.resume(null) else cont.resume(gatt)
// return read value if success
}
})
}
在保存的GATT实例上调用的方法:
fun discoverServices() {
gatt?.discoverServices() // result received in onServicesDiscovered
}
fun readCharacteristic(serviceUUID: UUID, characteristicUUID: UUID) {
gatt?.apply {
val characteristic =
getService(serviceUUID).getCharacteristic(characteristicUUID)
readCharacteristic(characteristic) // result received in onCharacteristicRead
}
}
如果我想要编写如下的“顺序代码”:
val gatt = connectToBle(context, false, gattCallback) // suspend until onConnectionStateChanged returns successfully
discoverServices() // suspend until discoverServices returns successfully
writeCharacteristic(characteristic, valueToWrite) // suspend until value is written successfully
val valueRead = readCharacteristic(characteristic) // suspend until the value is read successfully
disconnect()
我需要做哪些更改?除了suspendCoroutine以外,我应该使用其他什么东西吗?
suspendCoroutine
相同的类中,所有其他方法都在此实例本身上调用。onConnectionStateChange
是返回connectToBle
的回调,并且一旦它返回,继续执行将恢复。 如果我希望所有GATT方法都是“暂停”的,即在其相应的回调返回后返回,该怎么办? - Mahima MSBluetoothGattCallback
有多个回调函数。 - tyczj