【问题标题】:RxAndroidBLE do not find devices on android 4.3RxAndroidBLE 在 android 4.3 上找不到设备
【发布时间】:2018-04-28 13:04:42
【问题描述】:

您好,我正在使用 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
    }
}

我的APP

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"

【问题讨论】:

    标签: android kotlin rxandroidble


    【解决方案1】:

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

    您可能遇到的是特定于您的设备的行为(请随时分享您的手机型号),其中它仅在首次扫描特定外围设备时回调。已有some 线程与此主题相关,如this one

    【讨论】:

      猜你喜欢
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多