From d75d7f8ffa75d88807bdac1a30fe78cbef6085d4 Mon Sep 17 00:00:00 2001 From: ipcjs Date: Mon, 7 Dec 2020 11:24:23 +0800 Subject: [PATCH 1/6] Fix the problem that the scan stops immediately --- lib/src/bridge/scanning_mixin.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/bridge/scanning_mixin.dart b/lib/src/bridge/scanning_mixin.dart index d05a9809..80dd0179 100644 --- a/lib/src/bridge/scanning_mixin.dart +++ b/lib/src/bridge/scanning_mixin.dart @@ -40,7 +40,11 @@ mixin ScanningMixin on FlutterBLE { ); streamController - .addStream(_scanEvents, cancelOnError: true) + // When an error occurs, the native will end the stream, so there is no + // need to set cancelOnError to true. If set to true, it may cause the + // problem that the scan will be terminated immediately when the scan + // starts again after an error occurs. + .addStream(_scanEvents, cancelOnError: false) .then((_) => streamController?.close()); return streamController.stream; From 0b032c2fe8f8d1905a1afa9a41a4281579d6dbb4 Mon Sep 17 00:00:00 2001 From: ipcjs Date: Mon, 7 Dec 2020 17:31:12 +0800 Subject: [PATCH 2/6] Refactor and use EventChannel correctly. --- .../flutter_ble_lib/FlutterBleLibPlugin.java | 39 +------ .../event/ScanningStreamHandler.java | 104 +++++++++++++++--- lib/src/bridge/scanning_mixin.dart | 59 ++++------ 3 files changed, 110 insertions(+), 92 deletions(-) diff --git a/android/src/main/java/com/polidea/flutter_ble_lib/FlutterBleLibPlugin.java b/android/src/main/java/com/polidea/flutter_ble_lib/FlutterBleLibPlugin.java index e2007224..a9d799a2 100644 --- a/android/src/main/java/com/polidea/flutter_ble_lib/FlutterBleLibPlugin.java +++ b/android/src/main/java/com/polidea/flutter_ble_lib/FlutterBleLibPlugin.java @@ -12,8 +12,8 @@ import com.polidea.flutter_ble_lib.delegate.DescriptorsDelegate; import com.polidea.flutter_ble_lib.delegate.DeviceConnectionDelegate; import com.polidea.flutter_ble_lib.delegate.DevicesDelegate; -import com.polidea.flutter_ble_lib.delegate.LogLevelDelegate; import com.polidea.flutter_ble_lib.delegate.DiscoveryDelegate; +import com.polidea.flutter_ble_lib.delegate.LogLevelDelegate; import com.polidea.flutter_ble_lib.delegate.MtuDelegate; import com.polidea.flutter_ble_lib.delegate.RssiDelegate; import com.polidea.flutter_ble_lib.event.AdapterStateStreamHandler; @@ -23,15 +23,11 @@ import com.polidea.flutter_ble_lib.event.ScanningStreamHandler; import com.polidea.multiplatformbleadapter.BleAdapter; import com.polidea.multiplatformbleadapter.BleAdapterFactory; -import com.polidea.multiplatformbleadapter.OnErrorCallback; import com.polidea.multiplatformbleadapter.OnEventCallback; -import com.polidea.multiplatformbleadapter.ScanResult; -import com.polidea.multiplatformbleadapter.errors.BleError; import java.util.LinkedList; import java.util.List; -import androidx.annotation.NonNull; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -88,6 +84,7 @@ private void setupAdapter(Context context) { delegates.add(new CharacteristicsDelegate(bleAdapter, characteristicsMonitorStreamHandler)); delegates.add(new DevicesDelegate(bleAdapter)); delegates.add(new DescriptorsDelegate(bleAdapter)); + scanningStreamHandler.attachAdapter(bleAdapter); } @Override @@ -107,11 +104,8 @@ public void onMethodCall(MethodCall call, Result result) { case MethodName.DESTROY_CLIENT: destroyClient(result); break; - case MethodName.START_DEVICE_SCAN: - startDeviceScan(call, result); - break; case MethodName.STOP_DEVICE_SCAN: - stopDeviceScan(result); + scanningStreamHandler.stopDeviceScan(result); break; case MethodName.CANCEL_TRANSACTION: cancelTransaction(call, result); @@ -140,38 +134,13 @@ public void onEvent(Integer restoreStateIdentifier) { private void destroyClient(Result result) { bleAdapter.destroyClient(); - scanningStreamHandler.onComplete(); + scanningStreamHandler.detachAdapter(); connectionStateStreamHandler.onComplete(); bleAdapter = null; delegates.clear(); result.success(null); } - private void startDeviceScan(@NonNull MethodCall call, Result result) { - List uuids = call.>argument(ArgumentKey.UUIDS); - bleAdapter.startDeviceScan(uuids.toArray(new String[uuids.size()]), - call.argument(ArgumentKey.SCAN_MODE), - call.argument(ArgumentKey.CALLBACK_TYPE), - new OnEventCallback() { - @Override - public void onEvent(ScanResult data) { - scanningStreamHandler.onScanResult(data); - } - }, new OnErrorCallback() { - @Override - public void onError(BleError error) { - scanningStreamHandler.onError(error); - } - }); - result.success(null); - } - - private void stopDeviceScan(Result result) { - bleAdapter.stopDeviceScan(); - scanningStreamHandler.onComplete(); - result.success(null); - } - private void cancelTransaction(MethodCall call, Result result) { bleAdapter.cancelTransaction(call.argument(ArgumentKey.TRANSACTION_ID)); result.success(null); diff --git a/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java b/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java index 0e2fc50c..a91949a4 100644 --- a/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java +++ b/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java @@ -1,47 +1,117 @@ package com.polidea.flutter_ble_lib.event; +import android.util.Log; + +import com.polidea.flutter_ble_lib.constant.ArgumentKey; +import com.polidea.flutter_ble_lib.constant.ChannelName; import com.polidea.flutter_ble_lib.converter.BleErrorJsonConverter; import com.polidea.flutter_ble_lib.converter.ScanResultJsonConverter; +import com.polidea.multiplatformbleadapter.BleAdapter; +import com.polidea.multiplatformbleadapter.OnErrorCallback; +import com.polidea.multiplatformbleadapter.OnEventCallback; import com.polidea.multiplatformbleadapter.ScanResult; import com.polidea.multiplatformbleadapter.errors.BleError; +import com.polidea.multiplatformbleadapter.errors.BleErrorCode; + +import org.json.JSONObject; + +import java.util.List; +import java.util.Map; import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; public class ScanningStreamHandler implements EventChannel.StreamHandler { + /** + * @see MethodCall#argument(java.lang.String) + */ + @SuppressWarnings("unchecked") + public static T argument(Object arguments, String key) { + if (arguments == null) { + return null; + } else if (arguments instanceof Map) { + return (T) ((Map) arguments).get(key); + } else if (arguments instanceof JSONObject) { + return (T) ((JSONObject) arguments).opt(key); + } else { + throw new ClassCastException(); + } + } private EventChannel.EventSink scanResultsSink; private ScanResultJsonConverter scanResultJsonConverter = new ScanResultJsonConverter(); private BleErrorJsonConverter bleErrorJsonConverter = new BleErrorJsonConverter(); + private BleAdapter bleAdapter; - @Override - synchronized public void onListen(Object o, EventChannel.EventSink eventSink) { - scanResultsSink = eventSink; + synchronized public void attachAdapter(BleAdapter bleAdapter) { + this.bleAdapter = bleAdapter; } - @Override - synchronized public void onCancel(Object o) { + synchronized public void detachAdapter() { + if (scanResultsSink != null) { + onError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, "detach adapter", null)); + } + // There is no need to `stopDeviceScan`, bleAdapter will do it. + // bleAdapter.stopDeviceScan(); scanResultsSink = null; + bleAdapter = null; } - synchronized public void onScanResult(ScanResult scanResult) { + synchronized public void stopDeviceScan(MethodChannel.Result result) { if (scanResultsSink != null) { - scanResultsSink.success(scanResultJsonConverter.toJson(scanResult)); + onError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, "stop device scan", null)); + scanResultsSink = null; } + bleAdapter.stopDeviceScan(); + result.success(null); } - synchronized public void onError(BleError error) { + @Override + synchronized public void onListen(Object arguments, final EventChannel.EventSink eventSink) { + Log.d("FlutterBleLibPlugin", "on native side listen: " + ChannelName.SCANNING_EVENTS); + // force stop prev scanning. if (scanResultsSink != null) { - scanResultsSink.error( - String.valueOf(error.errorCode.code), - error.reason, - bleErrorJsonConverter.toJson(error)); - scanResultsSink.endOfStream(); + onError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, "Restart the scan", null)); } + bleAdapter.stopDeviceScan(); + scanResultsSink = eventSink; + + List uuids = argument(arguments, ArgumentKey.UUIDS); + int scanMode = argument(arguments, ArgumentKey.SCAN_MODE); + int callbackType = argument(arguments, ArgumentKey.CALLBACK_TYPE); + bleAdapter.startDeviceScan(uuids.toArray(new String[uuids.size()]), scanMode, callbackType, + new OnEventCallback() { + @Override + public void onEvent(ScanResult data) { + ScanningStreamHandler.this.onScanResult(eventSink, data); + } + }, + new OnErrorCallback() { + @Override + public void onError(BleError error) { + ScanningStreamHandler.this.onError(eventSink, error); + } + } + ); } - synchronized public void onComplete() { - if (scanResultsSink != null) { - scanResultsSink.endOfStream(); - } + @Override + synchronized public void onCancel(Object arguments) { + Log.d("FlutterBleLibPlugin", "on native side cancel: " + ChannelName.SCANNING_EVENTS); + bleAdapter.stopDeviceScan(); + scanResultsSink = null; + } + + private void onScanResult(EventChannel.EventSink eventSink, ScanResult scanResult) { + eventSink.success(scanResultJsonConverter.toJson(scanResult)); + } + + private void onError(EventChannel.EventSink eventSink, BleError error) { + eventSink.error( + String.valueOf(error.errorCode.code), + error.reason, + bleErrorJsonConverter.toJson(error)); + eventSink.endOfStream(); } } diff --git a/lib/src/bridge/scanning_mixin.dart b/lib/src/bridge/scanning_mixin.dart index 80dd0179..3de25510 100644 --- a/lib/src/bridge/scanning_mixin.dart +++ b/lib/src/bridge/scanning_mixin.dart @@ -1,11 +1,26 @@ part of _internal; mixin ScanningMixin on FlutterBLE { - Stream _scanEvents; + EventChannel _eventChannel; - void _prepareScanEventsStream() { - _scanEvents = const EventChannel(ChannelName.scanningEvents) - .receiveBroadcastStream() + EventChannel get eventChannel => + _eventChannel ??= const EventChannel(ChannelName.scanningEvents); + + Stream startDeviceScan( + int scanMode, + int callbackType, + List uuids, + bool allowDuplicates, + ) { + return eventChannel + .receiveBroadcastStream( + { + ArgumentName.scanMode: scanMode, + ArgumentName.callbackType: callbackType, + ArgumentName.uuids: uuids, + ArgumentName.allowDuplicates: allowDuplicates, + }, + ) .handleError( (errorJson) => throw BleError.fromJson(jsonDecode(errorJson.details)), test: (error) => error is PlatformException, @@ -16,43 +31,7 @@ mixin ScanningMixin on FlutterBLE { ); } - Stream startDeviceScan( - int scanMode, - int callbackType, - List uuids, - bool allowDuplicates, - ) { - if (_scanEvents == null) { - _prepareScanEventsStream(); - } - - StreamController streamController = StreamController.broadcast( - onListen: () => _methodChannel.invokeMethod( - MethodName.startDeviceScan, - { - ArgumentName.scanMode: scanMode, - ArgumentName.callbackType: callbackType, - ArgumentName.uuids: uuids, - ArgumentName.allowDuplicates: allowDuplicates, - }, - ), - onCancel: () => stopDeviceScan(), - ); - - streamController - // When an error occurs, the native will end the stream, so there is no - // need to set cancelOnError to true. If set to true, it may cause the - // problem that the scan will be terminated immediately when the scan - // starts again after an error occurs. - .addStream(_scanEvents, cancelOnError: false) - .then((_) => streamController?.close()); - - return streamController.stream; - } - Future stopDeviceScan() async { await _methodChannel.invokeMethod(MethodName.stopDeviceScan); - _scanEvents = null; - return; } } From 4a35b9b6c6b3bd7479b40a85e1090ec676932bc7 Mon Sep 17 00:00:00 2001 From: ipcjs Date: Tue, 8 Dec 2020 15:59:00 +0800 Subject: [PATCH 3/6] extract `cancelPreviousScanning()` method. --- .../event/ScanningStreamHandler.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java b/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java index a91949a4..7607b132 100644 --- a/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java +++ b/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java @@ -40,8 +40,8 @@ public static T argument(Object arguments, String key) { } private EventChannel.EventSink scanResultsSink; - private ScanResultJsonConverter scanResultJsonConverter = new ScanResultJsonConverter(); - private BleErrorJsonConverter bleErrorJsonConverter = new BleErrorJsonConverter(); + private final ScanResultJsonConverter scanResultJsonConverter = new ScanResultJsonConverter(); + private final BleErrorJsonConverter bleErrorJsonConverter = new BleErrorJsonConverter(); private BleAdapter bleAdapter; synchronized public void attachAdapter(BleAdapter bleAdapter) { @@ -49,32 +49,27 @@ synchronized public void attachAdapter(BleAdapter bleAdapter) { } synchronized public void detachAdapter() { - if (scanResultsSink != null) { - onError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, "detach adapter", null)); - } - // There is no need to `stopDeviceScan`, bleAdapter will do it. - // bleAdapter.stopDeviceScan(); - scanResultsSink = null; + cancelPreviousScanning("detach adapter"); bleAdapter = null; } - synchronized public void stopDeviceScan(MethodChannel.Result result) { + private void cancelPreviousScanning(String reason) { if (scanResultsSink != null) { - onError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, "stop device scan", null)); + endOfStreamWithError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, reason, null)); scanResultsSink = null; } bleAdapter.stopDeviceScan(); + } + + synchronized public void stopDeviceScan(MethodChannel.Result result) { + cancelPreviousScanning("stop device scan"); result.success(null); } @Override synchronized public void onListen(Object arguments, final EventChannel.EventSink eventSink) { Log.d("FlutterBleLibPlugin", "on native side listen: " + ChannelName.SCANNING_EVENTS); - // force stop prev scanning. - if (scanResultsSink != null) { - onError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, "Restart the scan", null)); - } - bleAdapter.stopDeviceScan(); + cancelPreviousScanning("Restart the scan"); scanResultsSink = eventSink; List uuids = argument(arguments, ArgumentKey.UUIDS); @@ -84,13 +79,13 @@ synchronized public void onListen(Object arguments, final EventChannel.EventSink new OnEventCallback() { @Override public void onEvent(ScanResult data) { - ScanningStreamHandler.this.onScanResult(eventSink, data); + onScanResult(eventSink, data); } }, new OnErrorCallback() { @Override public void onError(BleError error) { - ScanningStreamHandler.this.onError(eventSink, error); + endOfStreamWithError(eventSink, error); } } ); @@ -107,7 +102,7 @@ private void onScanResult(EventChannel.EventSink eventSink, ScanResult scanResul eventSink.success(scanResultJsonConverter.toJson(scanResult)); } - private void onError(EventChannel.EventSink eventSink, BleError error) { + private void endOfStreamWithError(EventChannel.EventSink eventSink, BleError error) { eventSink.error( String.valueOf(error.errorCode.code), error.reason, From 4f0061f9494d012fd91e4a99ffdf98c73dc7aaa4 Mon Sep 17 00:00:00 2001 From: "ipcjs.wf" Date: Tue, 8 Dec 2020 16:09:07 +0800 Subject: [PATCH 4/6] refactor scanning on ios --- ios/Classes/Event/ScanningStreamHandler.h | 5 ++- ios/Classes/Event/ScanningStreamHandler.m | 48 ++++++++++++++++++----- ios/Classes/FlutterBleLibPlugin.m | 21 ++-------- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/ios/Classes/Event/ScanningStreamHandler.h b/ios/Classes/Event/ScanningStreamHandler.h index 90ae9724..95a79ca5 100644 --- a/ios/Classes/Event/ScanningStreamHandler.h +++ b/ios/Classes/Event/ScanningStreamHandler.h @@ -1,8 +1,11 @@ #import +@import MultiplatformBleAdapter; @interface ScanningStreamHandler : NSObject +- (void)attachAdatper:(id )adapter; +- (void)detachAdapter; +- (void)stopDeviceScan:(FlutterResult)result; - (void)onScanResult:(NSArray *)scanResult; -- (void)onComplete; @end diff --git a/ios/Classes/Event/ScanningStreamHandler.m b/ios/Classes/Event/ScanningStreamHandler.m index f49f7514..ca60beba 100644 --- a/ios/Classes/Event/ScanningStreamHandler.m +++ b/ios/Classes/Event/ScanningStreamHandler.m @@ -2,13 +2,45 @@ #import "ArgumentHandler.h" #import "JSONStringifier.h" #import "FlutterErrorFactory.h" +#import "ArgumentKey.h" @implementation ScanningStreamHandler { FlutterEventSink scanResultsSink; + id bleAdapter; +} + +- (void) attachAdatper:(id)adapter { + bleAdapter = adapter; +} + +- (void) detachAdapter{ + [self cancelPreviousScanning:@"detach adapter"]; + bleAdapter = nil; +} + +- (void) cancelPreviousScanning:(NSString *)message{ + if (scanResultsSink != nil){ + NSString *errorCode = @"2"; // OperationCancelled + NSDictionary *json = @{@"errorCode": errorCode, @"reason": message}; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:json options:0 error:nil]; + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + scanResultsSink([FlutterError errorWithCode:@"2" message:message details: jsonString]); + scanResultsSink(FlutterEndOfEventStream); + scanResultsSink = nil; + } + [bleAdapter stopDeviceScan]; +} + +- (void)stopDeviceScan:(FlutterResult)result { + @synchronized (self) { + [self cancelPreviousScanning:@"stop device scan"]; + result(nil); + } } - (FlutterError * _Nullable)onCancelWithArguments:(id _Nullable)arguments { @synchronized (self) { + [bleAdapter stopDeviceScan]; scanResultsSink = nil; return nil; } @@ -16,7 +48,11 @@ - (FlutterError * _Nullable)onCancelWithArguments:(id _Nullable)arguments { - (FlutterError * _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(nonnull FlutterEventSink)events { @synchronized (self) { + [self cancelPreviousScanning:@"Restart the scan"]; scanResultsSink = events; + + NSArray* expectedArguments = [NSArray arrayWithObjects:ARGUMENT_KEY_ALLOW_DUPLICATES, nil]; + [bleAdapter startDeviceScan:[ArgumentHandler stringArrayOrNil:arguments[ARGUMENT_KEY_UUIDS]] options:[ArgumentHandler dictionaryOrNil:expectedArguments in:arguments]]; return nil; } } @@ -27,27 +63,19 @@ - (void)onScanResult:(NSArray *)scanResult { if (!(scanResult.count == 2 && (scanResult[0] == [NSNull null] || (scanResult[1] == [NSNull null] && [scanResult[0] isKindOfClass:NSString.class])))) { scanResultsSink([FlutterError errorWithCode:@"-1" message:@"Invalid scanResult format." details:nil]); - [self onComplete]; + scanResultsSink(FlutterEndOfEventStream); } else { if (scanResult[0] == [NSNull null]) { scanResultsSink([JSONStringifier jsonStringFromJSONObject:scanResult[1]]); } else { scanResultsSink([FlutterErrorFactory flutterErrorFromJSONString:scanResult[0]]); - [self onComplete]; + scanResultsSink(FlutterEndOfEventStream); } } } } } -- (void)onComplete { - @synchronized (self) { - if (scanResultsSink != nil) { - scanResultsSink(FlutterEndOfEventStream); - } - } -} - - (nullable NSString *)validStringOrNil:(id)argument { if (argument != nil && (NSNull *)argument != [NSNull null] && [argument isKindOfClass:[NSString class]]) { return (NSString *)argument; diff --git a/ios/Classes/FlutterBleLibPlugin.m b/ios/Classes/FlutterBleLibPlugin.m index f8cfea44..b582a5bb 100644 --- a/ios/Classes/FlutterBleLibPlugin.m +++ b/ios/Classes/FlutterBleLibPlugin.m @@ -77,10 +77,8 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result [self disable:call result:result]; } else if ([METHOD_NAME_GET_STATE isEqualToString:call.method]) { [self state:call result:result]; - } else if ([METHOD_NAME_START_DEVICE_SCAN isEqualToString:call.method]) { - [self startDeviceScan:call result:result]; } else if ([METHOD_NAME_STOP_DEVICE_SCAN isEqualToString:call.method]) { - [self stopDeviceScan:result]; + [self.scanningStreamHandler stopDeviceScan:result]; } else if ([METHOD_NAME_CONNECT_TO_DEVICE isEqualToString:call.method]) { [self connectToDevice:call result:result]; } else if ([METHOD_NAME_CANCEL_CONNECTION isEqualToString:call.method]) { @@ -162,10 +160,12 @@ - (void)createClient:(FlutterMethodCall *)call result:(FlutterResult)result { _adapter = [BleAdapterFactory getNewAdapterWithQueue:dispatch_get_main_queue() restoreIdentifierKey:[ArgumentHandler stringOrNil:call.arguments[ARGUMENT_KEY_RESTORE_STATE_IDENTIFIER]]]; _adapter.delegate = self; + [self.scanningStreamHandler attachAdatper:_adapter]; result(nil); } - (void)destroyClient { + [self.scanningStreamHandler detachAdapter]; [_adapter invalidate]; _adapter = nil; } @@ -193,21 +193,6 @@ - (void)state:(FlutterMethodCall *)call result:(FlutterResult)result { reject:[self rejectForFlutterResult:result]]; } -// MARK: - MBA Methods - Scanning - -- (void)startDeviceScan:(FlutterMethodCall *)call result:(FlutterResult)result { - NSArray* expectedArguments = [NSArray arrayWithObjects:ARGUMENT_KEY_ALLOW_DUPLICATES, nil]; - [_adapter startDeviceScan:[ArgumentHandler stringArrayOrNil:call.arguments[ARGUMENT_KEY_UUIDS]] - options:[ArgumentHandler dictionaryOrNil:expectedArguments in:call.arguments]]; - result(nil); -} - -- (void)stopDeviceScan:(FlutterResult)result { - [_adapter stopDeviceScan]; - [self.scanningStreamHandler onComplete]; - result(nil); -} - // MARK: - MBA Methods - Connection - (void)connectToDevice:(FlutterMethodCall *)call result:(FlutterResult)result { From 71a7c132f32ca58ca57677f64f4d36817b732b7f Mon Sep 17 00:00:00 2001 From: ipcjs Date: Thu, 10 Dec 2020 19:14:22 +0800 Subject: [PATCH 5/6] Don't `endOfStream()` when sending error events. --- .../flutter_ble_lib/event/ScanningStreamHandler.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java b/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java index 7607b132..66f9613d 100644 --- a/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java +++ b/android/src/main/java/com/polidea/flutter_ble_lib/event/ScanningStreamHandler.java @@ -55,7 +55,7 @@ synchronized public void detachAdapter() { private void cancelPreviousScanning(String reason) { if (scanResultsSink != null) { - endOfStreamWithError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, reason, null)); + onError(scanResultsSink, new BleError(BleErrorCode.OperationCancelled, reason, null)); scanResultsSink = null; } bleAdapter.stopDeviceScan(); @@ -85,7 +85,7 @@ public void onEvent(ScanResult data) { new OnErrorCallback() { @Override public void onError(BleError error) { - endOfStreamWithError(eventSink, error); + ScanningStreamHandler.this.onError(eventSink, error); } } ); @@ -102,11 +102,10 @@ private void onScanResult(EventChannel.EventSink eventSink, ScanResult scanResul eventSink.success(scanResultJsonConverter.toJson(scanResult)); } - private void endOfStreamWithError(EventChannel.EventSink eventSink, BleError error) { + private void onError(EventChannel.EventSink eventSink, BleError error) { eventSink.error( String.valueOf(error.errorCode.code), error.reason, bleErrorJsonConverter.toJson(error)); - eventSink.endOfStream(); } } From fd2ee4c3cfb32a3b440a165acb0455c9cff80701 Mon Sep 17 00:00:00 2001 From: "ipcjs.wf" Date: Thu, 10 Dec 2020 19:46:19 +0800 Subject: [PATCH 6/6] Don't `endOfStream` on ios --- ios/Classes/Event/ScanningStreamHandler.m | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ios/Classes/Event/ScanningStreamHandler.m b/ios/Classes/Event/ScanningStreamHandler.m index ca60beba..43f4a365 100644 --- a/ios/Classes/Event/ScanningStreamHandler.m +++ b/ios/Classes/Event/ScanningStreamHandler.m @@ -24,8 +24,7 @@ - (void) cancelPreviousScanning:(NSString *)message{ NSDictionary *json = @{@"errorCode": errorCode, @"reason": message}; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:json options:0 error:nil]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - scanResultsSink([FlutterError errorWithCode:@"2" message:message details: jsonString]); - scanResultsSink(FlutterEndOfEventStream); + scanResultsSink([FlutterError errorWithCode:errorCode message:message details: jsonString]); scanResultsSink = nil; } [bleAdapter stopDeviceScan]; @@ -63,13 +62,11 @@ - (void)onScanResult:(NSArray *)scanResult { if (!(scanResult.count == 2 && (scanResult[0] == [NSNull null] || (scanResult[1] == [NSNull null] && [scanResult[0] isKindOfClass:NSString.class])))) { scanResultsSink([FlutterError errorWithCode:@"-1" message:@"Invalid scanResult format." details:nil]); - scanResultsSink(FlutterEndOfEventStream); } else { if (scanResult[0] == [NSNull null]) { scanResultsSink([JSONStringifier jsonStringFromJSONObject:scanResult[1]]); } else { scanResultsSink([FlutterErrorFactory flutterErrorFromJSONString:scanResult[0]]); - scanResultsSink(FlutterEndOfEventStream); } } }