簡體   English   中英

有什么方法可以在不連接的情況下監控發現的BLE外設?

[英]Any way to monitor discovered BLE peripherals without connecting?

如果發現的BLE外設超出范圍或以其他方式失明,是否可以通過任何方式得到通知? 我正在使用rxBleClient.scanBleDevices()在要發布的區域中構建設備列表,但是在將該列表發送到主應用程序之前,我想確保所有設備仍然可以訪問。 最好的方法是什么?

Vanilla Android Scan API允許使用以下回調類型掃描BLE設備:

/**
 * A result callback is only triggered for the first advertisement packet received that matches
 * the filter criteria.
 */
public static final int CALLBACK_TYPE_FIRST_MATCH = 2;

/**
 * Receive a callback when advertisements are no longer received from a device that has been
 * previously reported by a first match callback.
 */
public static final int CALLBACK_TYPE_MATCH_LOST = 4;

可以通過RxBleClient.scanBleDevices(ScanSettings, ScanFilter...)使用相同的API

CALLBACK_TYPE_FIRST_MATCHCALLBACK_TYPE_MATCH_LOST是可以放入ScanSettings

觸發CALLBACK_TYPE_MATCH_LOST的超時時間約為10秒。 這可能表明特定設備不在范圍/可用范圍內。

您可以創建一個Transformer ,該Transformer將收集掃描的設備並發出一個列表,該列表保持最新狀態,具體取決於最近看到該設備的時間。

羅伯特,那可能不完全是您所期望的,但請以它為例。 無論是因為掃描儀的更新還是驅逐發生(每秒檢查一次),我的Transformer都會在更改項目時發出項目列表。

class RollingPairableDeviceReducer(
        private val systemTime: SystemTime,
        private val evictionTimeSeconds: Long,
        private val pairableDeviceFactory: PairableDeviceFactory
) : Observable.Transformer<ScannedDevice, List<PairableDevice>> {
    override fun call(source: Observable<ScannedDevice>): Observable<List<PairableDevice>> {
        val accumulator: MutableSet<PairableDevice> = Collections.synchronizedSet(mutableSetOf())
        return source
                .map { createPairableDevice(it) }
                .map { pairableDevice ->
                    val added = updateOrAddDevice(accumulator, pairableDevice)
                    val removed = removeOldDevices(accumulator)
                    added || removed
                }
                .mergeWith(checkEvictionEverySecond(accumulator))
                .filter { addedOrRemoved -> addedOrRemoved == true }
                .map { accumulator.toList() }
    }

    private fun createPairableDevice(scannedDevice: ScannedDevice)
            = pairableDeviceFactory.create(scannedDevice)

    private fun updateOrAddDevice(accumulator: MutableSet<PairableDevice>, emittedItem: PairableDevice): Boolean {
        val existingPairableDevice = accumulator.find { it.deviceIdentifier.hardwareId == emittedItem.deviceIdentifier.hardwareId }
        return if (existingPairableDevice != null) {
            accumulator.remove(existingPairableDevice)
            existingPairableDevice.updateWith(emittedItem)
            accumulator.add(existingPairableDevice)
            false
        } else {
            accumulator.add(emittedItem)
            true
        }
    }

    private fun checkEvictionEverySecond(collector: MutableSet<PairableDevice>): Observable<Boolean>
            = Observable.interval(1, TimeUnit.SECONDS)
            .map { removeOldDevices(collector) }

    private fun removeOldDevices(accumulator: MutableSet<PairableDevice>): Boolean {
        val currentTimeInMillis = systemTime.currentTimeInMillis()
        val evictionTimeMillis = TimeUnit.SECONDS.toMillis(evictionTimeSeconds)
        return accumulator.removeAll { (currentTimeInMillis - it.lastSeenTime) >= evictionTimeMillis }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM