我使用了很棒的rxandroidble库进行BLE控制 我保持活动之间的联系。 在开始扫描之前,我想先断开所有连接的设备。 有时如果有很多连接,它就无法工作。 这是我正在使用的解决方案:
public void doScan() {
if (isScanning()) return;
// disconnect all connected devices first:
while(BleController.getDefault().getDisconnectTriggerSubject().hasObservers()){
BleController.getDefault().getDisconnectTriggerSubject().onNext(null);
}
scanSubscription = rxBleClient.scanBleDevices(
new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.build(),
new ScanFilter.Builder()
// add custom filters if needed
.build()
)
.filter(rxBleScanResult -> !TextUtils.isEmpty(rxBleScanResult.getBleDevice().getName()))
.observeOn(AndroidSchedulers.mainThread())
.doOnUnsubscribe(this::clearSubscription)
.subscribe(resultsAdapter::addScanResult, this::onScanFailure);
updateButtonUIState();
}
使用主应用程序的上下文初始化 BleController
并保留connectionObservable
,disconnectTriggerSubject
,rxBleClient
。
什么是更好的解决方案? 任何帮助将不胜感激!
答案 0 :(得分:2)
从您的帖子中我可以看到您正在将BLE扫描/连接逻辑与UI /活动逻辑混合。这可能是正确管理连接的问题。
你可以做的是将所有BLE逻辑放到已经有一个好名字的BleController
,但似乎在你的情况下是BleObjectsContainer
。
例如,您只能通过BleController
只能以Activities
不需要处理的方式来实现您的特定用例的BleController
可观察对象。即你的private final BehaviorRelay<Boolean> isScanningPublishRelay = BehaviorRelay.create(false); // a relay (that cannot emit an error) that emits when a scan is ongoing
private Observable<ScanResult> scanDevicesWithNonNullNameObs = rxBleClient.scanBleDevices(new ScanSettings.Builder().build())
.filter(scanResult -> !TextUtils.isEmpty(scanResult.getBleDevice().getName()))
.doOnSubscribe(() -> isScanningPublishRelay.call(true)) // when scan is subscribed/started emit true
.doOnUnsubscribe(() -> isScanningPublishRelay.call(false)) // when scan is stopped emit false
.subscribeOn(AndroidSchedulers.mainThread()) // the above emissions will happen on the same thread. should be serialized
.unsubscribeOn(AndroidSchedulers.mainThread()) // the above emissions will happen on the same thread. should be serialized
.share(); // share this observable so no matter how many places in the code will subscribe the scan is started once and `isScanningPublishRelay` is called once
public Observable<ScanResult> scanDevicesWithNonNullName() { // getter for the scan observable
return scanDevicesWithNonNullNameObs;
}
可以处理扫描:
Activity
除了扫描之外,它还会处理您需要的每个class ScanInProgress extends Throwable {
// ...
}
public Observable<YourActivityUseCaseModel> doYourSpecificStuff(Observable<RxBleConnection> connectionObservable) {
return Observable.merge(
connectionObservable,
isScanningPublishRelay
.takeFirst(aBoolean -> aBoolean)
.flatMap(ignored -> Observable.error(new ScanInProgress())) // this will only emit an error when a scan is ongoing
)
.flatMap(...); // do the rest of your stuff
}
的特定用例:
BleController
这种方式在您的活动中,您只需要订阅他们需要的任何模型,并在一个专门用于它的地方处理BLE(Observable<RxBleConnection>
)。
在上面的示例中,您需要提供BleController
,但它可以通过多种不同方式实现,并且可以在 import re
# text = "text :)</p>"
text = "text . ) </p>"
result = text
if ":)" not in text:
result = re.sub('\s*', "", text)
中进行管理,因此不会在界面中公开。