RxAndroidBLE在Android 4.3上找不到设备

时间:2018-04-28 13:04:42

标签: android kotlin rxandroidble

您好我使用RxAndroidBLE来检测BLE设备。在android 6 >=上,一切似乎都运行正常,但在4.3设备上却没有。 我的应用只能在开始时才发现一次所需的BLE设备。在我重新启动应用程序之前,发现设备后根本没有新的发现。任何建议都将受到高度赞赏。 低于最小(非)工作代码示例:

MainActivity

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.util.Log
import com.polidea.rxandroidble.RxBleClient
import com.polidea.rxandroidble.exceptions.BleScanException
import com.polidea.rxandroidble.scan.ScanResult
import com.polidea.rxandroidble.scan.ScanSettings
import rx.Subscription
import rx.android.schedulers.AndroidSchedulers
import java.util.*
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startLeScan(applicationContext)
    }

    private var rxBleClient: RxBleClient? = null
    private var scanSubscription: Subscription? = null

    private var handler: Handler? = null
    private var timer: Timer? = null
    private var timerTask: TimerTask? = null
    private var delay: Int = 0

    private fun isScanning(): Boolean {
        return scanSubscription != null
    }

    fun startLeScan(context: Context) {
        rxBleClient = MyaPP.getRxBleClient(context)

        if (isScanning()) {
            scanSubscription?.unsubscribe()
        } else {
            scanSubscription = rxBleClient?.scanBleDevices(
                    com.polidea.rxandroidble.scan.ScanSettings.Builder()
                            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                            .build())
                    ?.observeOn(AndroidSchedulers.mainThread())
                    //?.doOnNext(this::newDevicesFound)
                    ?.doOnUnsubscribe(this::clearSubscription)
                    ?.subscribe(this::newDevicesFound, this::onScanFailure)
        }

        if(handler == null) {
            handler = Handler()
            timer = Timer(false)
            timerTask = object : TimerTask() {
                override fun run() {
                    handler?.post {
                        if (delay > 7) {
                            delay = 0

                            val service = Executors.newSingleThreadExecutor()
                            service.submit(Runnable {

                                //startLeScan(context)
                            })

                        } else {
                            delay = delay + 1
                        }
                    }
                }
            }
            timer?.scheduleAtFixedRate(timerTask, 0, 300)
        }
    }

    private fun newDevicesFound(devices: ScanResult) {
        Log.d("WHYY??", devices.bleDevice.name)
    }

    fun stopScan() {
        scanSubscription?.unsubscribe()
        destroy()
    }

    private fun clearSubscription() {
        scanSubscription = null
    }

    private fun onScanFailure(throwable: Throwable) {
        if (throwable is BleScanException) {
            handleBleScanException(throwable)
        }
    }

    private fun handleBleScanException(bleScanException: BleScanException) {
        val text: String

        when (bleScanException.reason) {
            BleScanException.BLUETOOTH_NOT_AVAILABLE -> text = "Bluetooth is not available"
            BleScanException.BLUETOOTH_DISABLED -> text = "Enable bluetooth and try again"
            BleScanException.LOCATION_PERMISSION_MISSING -> text = "On Android 6.0 location permission is required. Implement Runtime Permissions"
            BleScanException.LOCATION_SERVICES_DISABLED -> text = "Location services needs to be enabled on Android 6.0"
            BleScanException.SCAN_FAILED_ALREADY_STARTED -> text = "Scan with the same filters is already started"
            BleScanException.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED -> text = "Failed to register application for bluetooth scan"
            BleScanException.SCAN_FAILED_FEATURE_UNSUPPORTED -> text = "Scan with specified parameters is not supported"
            BleScanException.SCAN_FAILED_INTERNAL_ERROR -> text = "Scan failed due to internal error"
            BleScanException.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES -> text = "Scan cannot start due to limited hardware resources"
            BleScanException.UNDOCUMENTED_SCAN_THROTTLE -> text = String.format(
                    Locale.getDefault(),
                    "Android 7+ does not allow more scans. Try in %d seconds",
                    secondsTill(bleScanException.retryDateSuggestion)
            )
            BleScanException.UNKNOWN_ERROR_CODE, BleScanException.BLUETOOTH_CANNOT_START -> text = "Unable to start scanning"
            else -> text = "Unable to start scanning"
        }
        Log.w("EXCEPTION", text, bleScanException)
    }

    private fun secondsTill(retryDateSuggestion: Date?): Long {
        if (retryDateSuggestion != null) {
            return TimeUnit.MILLISECONDS.toSeconds(retryDateSuggestion.time - System.currentTimeMillis())
        }

        return 0
    }

    private fun destroy() {
        timer?.cancel()
        handler?.removeCallbacks(timerTask)
        handler = null
        timerTask = null
        timer = null
    }
}

MYAPP

import android.app.Application
import android.content.Context
import com.polidea.rxandroidble.RxBleClient
import com.polidea.rxandroidble.internal.RxBleLog


class MyaPP: Application() {

    private var rxBleClient: RxBleClient? = null

    companion object {
        fun getRxBleClient(context: Context): RxBleClient? {
            val application = context.applicationContext as MyaPP
            return application.rxBleClient
        }
    }

    override fun onCreate() {
        super.onCreate()

        rxBleClient = RxBleClient.create(this)
        RxBleClient.setLogLevel(RxBleLog.DEBUG)
    }
}

的build.gradle

compile "com.polidea.rxandroidble:rxandroidble:1.5.0"
implementation 'io.reactivex:rxandroid:1.2.1'

清单

<application
        android:name=".MyaPP"

1 个答案:

答案 0 :(得分:0)

您的代码看起来很像库的示例应用程序(版本master-rxjava1,分支{5, 4, 3})。我最近在Android 4.4.4上检查过这是我用过的最老的,它运行良好。 4.3和4.4之间没有API更改。

您可能遇到的问题是您的设备特定的行为(随意共享您的手机型号),其中第一次扫描特定外围设备时只会回调。关于此主题的some个帖子已经类似于this one