问题描述
我很感谢您可能已经回答了这个问题,但是我找不到适合我的解决方案.
I appreciate that this may have already been answered but I'm unable to find a solution that works for me.
Tl; dr:如何制作功能块?
Tl;dr: How do make a function block?
我有以下Kotlin中为Android API 28编写的与BLE相关的代码.
I have the following BLE-related code written in Kotlin for Android API 28.
override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
for (gattService: BluetoothGattService in gatt!!.services) {
for (gattChar: BluetoothGattCharacteristic in gattService.characteristics) {
if (gattChar.uuid.toString().contains(ADC_SAMPLESET_0) && !subscribed_0) {
subscribed_0 = true
gatt.setCharacteristicNotification(gattChar, true)
val descriptor = gattChar.getDescriptor(
UUID.fromString(BleNamesResolver.CLIENT_CHARACTERISTIC_CONFIG)
)
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
gatt.writeDescriptor(descriptor)
}
上面的if语句被重复多次以促进订阅多个BLE特性.不幸的是,gatt.writeDescriptor()
函数异步运行.在调用gatt.writeDescriptor()
获取下一个特性之前,我需要等待它返回.我该如何实现?
The if-statement above is repeated multiple times to facilitate subscription to multiple BLE characteristics. Unfortunately, the gatt.writeDescriptor()
function runs asynchronously. I need to wait for it to return before calling gatt.writeDescriptor()
for the next characteristic. How do I achieve this?
我已经尝试在kotlinx.coroutines.experimental.*
中使用runBlocking
和GlobalScope.launch
,但是我不能完全确定它们是否正确.
I've tried using runBlocking
and GlobalScope.launch
in kotlinx.coroutines.experimental.*
but I'm not entirely sure that they're the right thing.
谢谢,亚当
推荐答案
onDescriptorWrite()
方法可能会有所帮助.您应该已经覆盖了它.
The onDescriptorWrite()
method might be helpful. You should already be overriding it.
请尝试以下操作:
private var canContinue = false;
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { //gatt shouldn't be null, so the null-safe ? isn't needed
loopAsync(gatt);
}
override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
canContinue = true; //allow the loop to continue once a descriptor is written
}
private fun loopAsync(gatt: BluetoothGatt) {
async { //Run it async
gatt.services.forEach { gattService -> //Kotlin has a handy Collections.forEach() extension function
gattService.characteristics.forEach { gattChar -> //Same for this one
if (gattChar.uuid.toString().contains(ADC_SAMPLESET_0) && !subscribed_0) {
subscribed_0 = true
gatt.setCharacteristicNotification(gattChar, true)
val descriptor = gattChar.getDescriptor(
UUID.fromString(BleNamesResolver.CLIENT_CHARACTERISTIC_CONFIG)
}
descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
gatt.writeDescriptor(descriptor)
while(!canContinue); //wait until canContinue becomes true and then continue
}
}
}
}
}
这有点hacky.可能有一种使用递归的方法,但是嵌套的for循环使这一过程变得棘手.
This is a little hacky. There is probably a way to do this with recursion, but the nested for loops make that tricky.
这篇关于在Kotlin中制作功能块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!