New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android - observer.collect throws NoSuchElementException #43
Comments
The characteristic lookup in the internal cache when using Generally, val characteristic = characteristicOf(
service = UART_SERVICE,
characteristic = RX_CHARACTERISTIC_UUID
) ...but your approach should also work, and definitely shouldn't result in the exception you're seeing since you are looking up from the list of actual services discovered. What is the value of |
Thanks for the quick response @twyatt. I started out using the
It's a fairly standard UART Service. I haven't investigated further but I assumed that the error was caused here in acquire() in Observers? Please let me know if I can help you troubleshoot in anyway. |
Your issue is actually closely related to #38, in that I believe you're still being hit by the internal characteristic lookup failure within Definitely a shortcoming in how the Unfortunately this means that a lookup (in For Android, in the future, we may consider holding a weak reference in the services/characteristics provided by In the mean time, I'll be sure and get #38 closed out soon and push a
I suspect it is actually here (as described above): kable/core/src/jsMain/kotlin/Peripheral.kt Lines 207 to 212 in c750de5
Thanks for the help and issue report. I'll keep you posted. |
To help us track down the issue, I've added basic logging (to the Android platform only, under When you have a chance, can you try the following dependency and provide the lookup logs? import java.net.URI
repositories {
maven { url = URI("https://oss.sonatype.org/content/repositories/snapshots") }
}
dependencies {
implementation("com.juul.kable:core:0.1.0-issue-43-SNAPSHOT")
} Logs should look similar to: Android logcat
Thanks! |
Switched over to using Log
|
Do you mind pasting your updated sample code that is producing these logs?
That shouldn't be an issue. The services/characteristics are cached just after service discovery (which Kable does automatically upon connection).
Ya, logs look reasonable. The lookup appears to succeed, so it's quite bizarre that you're getting the Thanks for your help debugging this issue! |
I have reproduced similar crash with SensorTag example when disconnect peripheral in during of connecting. You can reproduce this with my peripheral app attached here
|
Very similar to what I posted previously bluetoothScope.launch {
val peripheral: Peripheral? = getPeripheral() // Get Peripheral using Scanner()
if (peripheral != null) {
peripheral.connect()
val characteristic = characteristicOf(
service = UART_SERVICE,
characteristic = RX_CHARACTERISTIC_UUID
)
if (characteristic != null ) {
val observer = peripheral.observe(characteristic)
try {
observer.collect { data ->
Log.d(TAG, data)
}
} catch (e: NoSuchElementException) {
Log.d(TAG, "Did not find characteristic. $e")
}
}
}
}
}
private suspend fun getPeripheral(): Peripheral? {
return try {
val advertisement = Scanner()
.advertisements
.firstOrNull { advertisement ->
advertisement.name?.startsWith(nameofPeripheral) ?: false
}
if (advertisement != null) {
Log.d(TAG, "-> Found the UART advertisement")
bluetoothScope.peripheral(advertisement)
} else {
null
}
} catch (e: Throwable) {
Log.e(TAG, "Problem -> $e")
return null
}
} |
@axelinternet is the peripheral that is causing the crash publicly available? If so, I'll probably purchase one to diagnose the issue. |
No unfortunately not. I can see if I get the same error if I emulate it using some different hardware. I've built other apps that interface it fine (but never tried using android). |
Great, thanks! In the mean time I'll also start integrating a way to toggle detailed logging in Kable, to help track down issues like this. |
@axelinternet just to make sure I'm not going down the wrong rabbit hole: could you provide the stacktrace? So where you do: } catch (e: NoSuchElementException) {
Log.d(TAG, "Did not find characteristic. $e")
} Change it to something like: } catch (e: NoSuchElementException) {
Log.d(TAG, "Did not find characteristic. $e", e)
// I can't quite remember if `Log.d` prints the full trace, if not, this may be needed instead of adding 3rd parameter to `Log.d`
e.printStackTrace()
} |
Oh! I think I've spotted the issue. Somewhat shot in the dark but I think #42 (when fixed) will also fix your issue. @axelinternet In your original issue report, you pasted your characteristic details:
It appears that the characteristic that you're observing does not have the descriptor to enable observation. As pointed out in #42, "It's a violation of BLE specification" but is common enough that Kable should provide a workaround. I should be able to get #42 fixed soon and you can give that a try (disabling writing to descriptor when observing). |
Ah that is true. I didn't think that this was required. There is a lot of "may" and "can" when googling around descriptors but just as said in #42 turns out that this is required if the characteristic is set to notify. |
I'm trying to read some data of a UART Service that provides a "write without response" and a "notify" characteristic. I can write to it fine using cable but Kable but get the following error when using
observer.collect { ... }
to subscribe to notifications.java.util.NoSuchElementException: Collection contains no element matching the predicate.
The characteristic works fine to read using other apps and sends out data about once a second. As probably will be apparent from my sample code below I'm fairly new to Kotlin but as far as I understand after reading up and digging through the source code I can't see why this error is produced.
I looked at issue 38 but since I go through the steps to get the characteristic I get this error even if it is discovered. Or did i misunderstand the cause of that issue?
The characteristic and observer objects looks fine to me, what I can notice is that the
Sample code
Scan result
The text was updated successfully, but these errors were encountered: