3

Currently i am working in a application where it involves ble device. I created a service and grnated all permission that a bluetooth application requires and bluetooth is enabled. When the service is started it scans for the ble devices and connects to it. But while scanning sometimes it give me this exception.

com.polidea.rxandroidble2.exceptions.BleScanException: Scan failed because application registration failed (code 6)

I am using this library

[https://github.com/Polidea/RxAndroidBle][1]

Here is my Service

package mypackage.name

import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import com.cambfit.android.bluetoothdriver.*
import com.cambfit.android.core.base.viewmodel.SingleLiveEvent
import com.orhanobut.logger.Logger
import com.polidea.rxandroidble2.RxBleClient
import com.polidea.rxandroidble2.RxBleDevice
import com.polidea.rxandroidble2.exceptions.BleScanException
import com.polidea.rxandroidble2.scan.ScanFilter
import com.polidea.rxandroidble2.scan.ScanResult
import com.polidea.rxandroidble2.scan.ScanSettings
import dagger.android.AndroidInjection
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit
import javax.inject.Inject

class BluetoothService : Service() {

    @Inject
    lateinit var rxBleClient: RxBleClient

    private val binder by lazy { BluetoothServiceBinder() }

    private val compositeDisposable by lazy { CompositeDisposable() }
    private lateinit var scanDisposable: Disposable

    override fun onCreate() {
        AndroidInjection.inject(this)
        super.onCreate()
        observeBlueToothState()
    }

    override fun onDestroy() {
        compositeDisposable.dispose()
        super.onDestroy()
    }

    override fun onBind(intent: Intent?): IBinder? {
        return binder
    }

    private fun observeBlueToothState() {

        scanDisposable = rxBleClient.observeStateChanges()
            .startWith(rxBleClient.state)
            .switchMap { state ->
                when (state) {
                    RxBleClient.State.READY -> {
                        Logger.d("READY")
                        return@switchMap scanDevices()
                    }

                    RxBleClient.State.BLUETOOTH_NOT_AVAILABLE -> {
                        Logger.e("BLUETOOTH_NOT_AVAILABLE")
                        return@switchMap Observable.empty<ScanResult>()
                    }

                    RxBleClient.State.LOCATION_PERMISSION_NOT_GRANTED -> {
                        Logger.w("LOCATION_PERMISSION_NOT_GRANTED")
                        return@switchMap Observable.empty<ScanResult>()
                    }

                    RxBleClient.State.BLUETOOTH_NOT_ENABLED -> {
                        Logger.w("BLUETOOTH_NOT_ENABLED")
                        binder.enableBluetoothEvent.call()
                        return@switchMap Observable.empty<ScanResult>()
                    }

                    RxBleClient.State.LOCATION_SERVICES_NOT_ENABLED -> {
                        Logger.w("LOCATION_SERVICES_NOT_ENABLED")
                        return@switchMap Observable.empty<ScanResult>()
                    }

                    else -> {
                        Logger.w("OTHER")
                        return@switchMap Observable.empty<ScanResult>()
                    }
                }
            }
            .filter { scanResult -> scanResult.bleDevice.name != null }
            .subscribe({ scanResult ->

                //Logger.d(scanResult.toString())


            }, { throwable ->
                throwable.printStackTrace()
            })

        compositeDisposable.add(scanDisposable)
    }

    private fun scanDevices(): Observable<ScanResult> {
        return rxBleClient.scanBleDevices(ScanSettings.Builder().build(), ScanFilter.Builder().build())
            .retryWhen { errors ->
                errors.flatMap { error ->
                    if (error is BleScanException) return@flatMap Observable.timer(30, TimeUnit.SECONDS)
                    else return@flatMap Observable.error<Exception>(error)
                }
            }
    }

}

Any kind of help will be appreciated. Thanks.

Anik Dey
  • 616
  • 8
  • 17

1 Answers1

4

This seem to be an Android bug and/or excessive scans being performed in other places on the phone. Quick googling shows that it is a known problem

Basically your phone is running out of system resources.

It does not look like something that can be fixed programatically in your code.

A workaround would be to turn your BT off/on so BT resources would get cleared.

Dariusz Seweryn
  • 3,212
  • 2
  • 14
  • 21
  • Just wanted to add to this. I'm seeing it on a Galaxy S5E. I was turning off and on BT to get to this state so turning it off again didn't help. Re-scanning later worked though (after ~10 seconds) – behelit Nov 20 '19 at 00:32