RxAndroidBle :定期广告扫描

RxAndroidBle : Periodic advertising scan

我需要在未连接到我的设备时永久扫描 ble 广告以找到它并知道何时连接到它(特定产品)。此扫描在前台服务中实现,以匹配 8.0 前提条件。

为了节省电量,我想定期扫描(同时遵守 Android 7 启动限制 amount/time)。我看到 2 个不同的实现:


我想用 Rx 风格而不是简单的计时器来做(我不是 RX 专家)。我不知道要开发什么解决方案better/easier。 这对客户端必须是透明的,并且必须保持原来的 RxAndroidBle 正常工作,订阅 = 启动进程,取消订阅 = 停止进程。

我想我必须使用 Obersable.interval 但我不知道如何管理它 任何片段/示例?

原始的 Android BLE API 有 BluetoothLeScanner class 允许使用四种模式之一开始扫描:

  • SCAN_MODE_LOW_LATENCY—扫描是连续的
  • SCAN_MODE_BALANCED—扫描每 5 秒工作 2 秒
  • SCAN_MODE_LOW_POWER—扫描每 5 秒工作 0.5 秒
  • SCAN_MODE_OPPORTUNISTIC—扫描仅在其他应用程序启动时有效

时间测量由 Nordic Semiconductors 员工执行,并以 comprehensive guide 的形式发布给 Android BLE 开发人员。

RxAndroidBle 库还有一个函数 RxBleClient.scanBleDevices(ScanSettings, ScanFilter...),它在 ScanSettings 对象中接受相同的模式。

如果需要实现不同的扫描参数,可以简单地使用 Observable.takeUntil()Observable.repeatWhen():

的组合
Observable<ScanResult> lowLatencyScanObservable = rxBleClient.scanBleDevices(
  new ScanSettings.Builder()
    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // make sure that the scanning will be always on by default
    .build()
);

Observable<ScanResult> periodicalScan = lowLatencyScanObservable
  .takeUntil(Observable.timer(SCAN_TIME, SCAN_TIMEUNIT)) // scan for a specific amount of time and then unsubscribe to the upstream
  .repeatWhen(completionObservable -> completionObservable.delay(PAUSE_TIME, PAUSE_TIMEUNIT)); // when the upstream will complete because of `takeUntil()` wait for the pause time and resubscribe to the upstream

人们仍然需要记住 API 24+ 的未记录的 "feature",它会阻止在 30 秒内开始超过 5 次扫描。