rxandroidblerxbluetooth

onScanFailure after a certain of time when scanning ble devices in android


I am using rxbleandroid library for scanning Bluetooth devices

fun startScan() {
    if(rxBleClient.isScanRuntimePermissionGranted) {
        Log.d("TAG", "All permission granted")
    }
    else {
        Log.d("TAG", "Not all permission granted\"")
    }
    val scanSettings = ScanSettings.Builder()
        .setScanMode(SCAN_MODE_BALANCED)
        .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
        .build()
    val scanFilter = ScanFilter.Builder()
        .build()
    rxBleClient.scanBleDevices(scanSettings, scanFilter)
        .observeOn(AndroidSchedulers.mainThread())
        .doFinally { dispose() }
        .subscribe({scanResult ->
            Log.d("TAG", scanResult?.bleDevice?.name!!)


        },
            {
            onScanFailure(it) })

        .let {
            scanDisposable = it}//
}

private fun dispose() {
    //scanDisposable = null
}
private fun onScanFailure(throwable: Throwable) {
    Log.d("TAG", "onScanFailure ${throwable. Cause}")
    viewModelScope.launch{
        delay(6000)
        scanDisposable?.dispose()
        startScan()
    }
}

After a short while a get a onScanFailure event. The output on the screen is onScanFailure null

The only way to fix it is to wait little bit and restart the scanning. I am using the latest version of android on a pixel6. The version number of rxAndroidLibraryble is 1.17.0 Am i using the library wrong?


Solution

  • In the callback function you are using this line:

    Log.d("TAG", scanResult?.bleDevice?.name!!)

    It will throw an NPE once a device with no advertised name will get scanned and that NPE will have no cause.

    You could use this:

    Log.d("TAG", scanResult?.bleDevice?.name ?: "no name")