bug: fix start() and stop() crash when called multiple times on iOS and macOS. R…
…emove analyze mode on Android and iOS.
Showing
6 changed files
with
153 additions
and
71 deletions
| @@ -38,8 +38,8 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -38,8 +38,8 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 38 | private var camera: Camera? = null | 38 | private var camera: Camera? = null |
| 39 | private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null | 39 | private var textureEntry: TextureRegistry.SurfaceTextureEntry? = null |
| 40 | 40 | ||
| 41 | - @AnalyzeMode | ||
| 42 | - private var analyzeMode: Int = AnalyzeMode.NONE | 41 | +// @AnalyzeMode |
| 42 | +// private var analyzeMode: Int = AnalyzeMode.NONE | ||
| 43 | 43 | ||
| 44 | @ExperimentalGetImage | 44 | @ExperimentalGetImage |
| 45 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) { | 45 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) { |
| @@ -47,8 +47,8 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -47,8 +47,8 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 47 | "state" -> checkPermission(result) | 47 | "state" -> checkPermission(result) |
| 48 | "request" -> requestPermission(result) | 48 | "request" -> requestPermission(result) |
| 49 | "start" -> start(call, result) | 49 | "start" -> start(call, result) |
| 50 | - "torch" -> switchTorch(call, result) | ||
| 51 | - "analyze" -> switchAnalyzeMode(call, result) | 50 | + "torch" -> toggleTorch(call, result) |
| 51 | +// "analyze" -> switchAnalyzeMode(call, result) | ||
| 52 | "stop" -> stop(result) | 52 | "stop" -> stop(result) |
| 53 | else -> result.notImplemented() | 53 | else -> result.notImplemented() |
| 54 | } | 54 | } |
| @@ -92,8 +92,8 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -92,8 +92,8 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 92 | 92 | ||
| 93 | @ExperimentalGetImage | 93 | @ExperimentalGetImage |
| 94 | val analyzer = ImageAnalysis.Analyzer { imageProxy -> // YUV_420_888 format | 94 | val analyzer = ImageAnalysis.Analyzer { imageProxy -> // YUV_420_888 format |
| 95 | - when (analyzeMode) { | ||
| 96 | - AnalyzeMode.BARCODE -> { | 95 | +// when (analyzeMode) { |
| 96 | +// AnalyzeMode.BARCODE -> { | ||
| 97 | val mediaImage = imageProxy.image ?: return@Analyzer | 97 | val mediaImage = imageProxy.image ?: return@Analyzer |
| 98 | val inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) | 98 | val inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) |
| 99 | 99 | ||
| @@ -106,9 +106,9 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -106,9 +106,9 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 106 | } | 106 | } |
| 107 | .addOnFailureListener { e -> Log.e(TAG, e.message, e) } | 107 | .addOnFailureListener { e -> Log.e(TAG, e.message, e) } |
| 108 | .addOnCompleteListener { imageProxy.close() } | 108 | .addOnCompleteListener { imageProxy.close() } |
| 109 | - } | ||
| 110 | - else -> imageProxy.close() | ||
| 111 | - } | 109 | +// } |
| 110 | +// else -> imageProxy.close() | ||
| 111 | +// } | ||
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | 114 | ||
| @@ -116,6 +116,10 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -116,6 +116,10 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 116 | 116 | ||
| 117 | @ExperimentalGetImage | 117 | @ExperimentalGetImage |
| 118 | private fun start(call: MethodCall, result: MethodChannel.Result) { | 118 | private fun start(call: MethodCall, result: MethodChannel.Result) { |
| 119 | + if (camera != null) { | ||
| 120 | + result.error(TAG, "Called start() while already started!", null) | ||
| 121 | + return | ||
| 122 | + } | ||
| 119 | 123 | ||
| 120 | val facing: Int = call.argument<Int>("facing") ?: 0 | 124 | val facing: Int = call.argument<Int>("facing") ?: 0 |
| 121 | val ratio: Int? = call.argument<Int>("ratio") | 125 | val ratio: Int? = call.argument<Int>("ratio") |
| @@ -186,24 +190,32 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | @@ -186,24 +190,32 @@ class MobileScanner(private val activity: Activity, private val textureRegistry: | ||
| 186 | }, executor) | 190 | }, executor) |
| 187 | } | 191 | } |
| 188 | 192 | ||
| 189 | - private fun switchTorch(call: MethodCall, result: MethodChannel.Result) { | ||
| 190 | - val state = call.arguments == 1 | ||
| 191 | - camera!!.cameraControl.enableTorch(state) | 193 | + private fun toggleTorch(call: MethodCall, result: MethodChannel.Result) { |
| 194 | + if (camera == null) { | ||
| 195 | + result.error(TAG,"Called toggleTorch() while stopped!", null) | ||
| 196 | + return | ||
| 197 | + } | ||
| 198 | + camera!!.cameraControl.enableTorch(call.arguments == 1) | ||
| 192 | result.success(null) | 199 | result.success(null) |
| 193 | } | 200 | } |
| 194 | 201 | ||
| 195 | - private fun switchAnalyzeMode(call: MethodCall, result: MethodChannel.Result) { | ||
| 196 | - analyzeMode = call.arguments as Int | ||
| 197 | - result.success(null) | ||
| 198 | - } | 202 | +// private fun switchAnalyzeMode(call: MethodCall, result: MethodChannel.Result) { |
| 203 | +// analyzeMode = call.arguments as Int | ||
| 204 | +// result.success(null) | ||
| 205 | +// } | ||
| 199 | 206 | ||
| 200 | private fun stop(result: MethodChannel.Result) { | 207 | private fun stop(result: MethodChannel.Result) { |
| 208 | + if (camera == null) { | ||
| 209 | + result.error(TAG,"Called stop() while already stopped!", null) | ||
| 210 | + return | ||
| 211 | + } | ||
| 212 | + | ||
| 201 | val owner = activity as LifecycleOwner | 213 | val owner = activity as LifecycleOwner |
| 202 | camera!!.cameraInfo.torchState.removeObservers(owner) | 214 | camera!!.cameraInfo.torchState.removeObservers(owner) |
| 203 | cameraProvider!!.unbindAll() | 215 | cameraProvider!!.unbindAll() |
| 204 | textureEntry!!.release() | 216 | textureEntry!!.release() |
| 205 | 217 | ||
| 206 | - analyzeMode = AnalyzeMode.NONE | 218 | +// analyzeMode = AnalyzeMode.NONE |
| 207 | camera = null | 219 | camera = null |
| 208 | textureEntry = null | 220 | textureEntry = null |
| 209 | cameraProvider = null | 221 | cameraProvider = null |
| @@ -23,7 +23,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -23,7 +23,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 23 | var latestBuffer: CVImageBuffer! | 23 | var latestBuffer: CVImageBuffer! |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | - var analyzeMode: Int = 0 | 26 | +// var analyzeMode: Int = 0 |
| 27 | var analyzing: Bool = false | 27 | var analyzing: Bool = false |
| 28 | var position = AVCaptureDevice.Position.back | 28 | var position = AVCaptureDevice.Position.back |
| 29 | 29 | ||
| @@ -53,9 +53,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -53,9 +53,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 53 | case "start": | 53 | case "start": |
| 54 | start(call, result) | 54 | start(call, result) |
| 55 | case "torch": | 55 | case "torch": |
| 56 | - switchTorch(call, result) | ||
| 57 | - case "analyze": | ||
| 58 | - switchAnalyzeMode(call, result) | 56 | + toggleTorch(call, result) |
| 57 | +// case "analyze": | ||
| 58 | +// switchAnalyzeMode(call, result) | ||
| 59 | case "stop": | 59 | case "stop": |
| 60 | stop(result) | 60 | stop(result) |
| 61 | default: | 61 | default: |
| @@ -89,10 +89,10 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -89,10 +89,10 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 89 | latestBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) | 89 | latestBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) |
| 90 | registry.textureFrameAvailable(textureId) | 90 | registry.textureFrameAvailable(textureId) |
| 91 | 91 | ||
| 92 | - switch analyzeMode { | ||
| 93 | - case 1: // barcode | 92 | +// switch analyzeMode { |
| 93 | +// case 1: // barcode | ||
| 94 | if analyzing { | 94 | if analyzing { |
| 95 | - break | 95 | + return |
| 96 | } | 96 | } |
| 97 | analyzing = true | 97 | analyzing = true |
| 98 | let buffer = CMSampleBufferGetImageBuffer(sampleBuffer) | 98 | let buffer = CMSampleBufferGetImageBuffer(sampleBuffer) |
| @@ -112,9 +112,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -112,9 +112,9 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 112 | } | 112 | } |
| 113 | analyzing = false | 113 | analyzing = false |
| 114 | } | 114 | } |
| 115 | - default: // none | ||
| 116 | - break | ||
| 117 | - } | 115 | +// default: // none |
| 116 | +// break | ||
| 117 | +// } | ||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | func imageOrientation( | 120 | func imageOrientation( |
| @@ -154,6 +154,13 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -154,6 +154,13 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 156 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| 157 | + if (device != nil) { | ||
| 158 | + result(FlutterError(code: "MobileScanner", | ||
| 159 | + message: "Called start() while already started!", | ||
| 160 | + details: nil)) | ||
| 161 | + return | ||
| 162 | + } | ||
| 163 | + | ||
| 157 | textureId = registry.register(self) | 164 | textureId = registry.register(self) |
| 158 | captureSession = AVCaptureSession() | 165 | captureSession = AVCaptureSession() |
| 159 | 166 | ||
| @@ -219,7 +226,13 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -219,7 +226,13 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 219 | result(answer) | 226 | result(answer) |
| 220 | } | 227 | } |
| 221 | 228 | ||
| 222 | - func switchTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 229 | + func toggleTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| 230 | + if (device == nil) { | ||
| 231 | + result(FlutterError(code: "MobileScanner", | ||
| 232 | + message: "Called toggleTorch() while stopped!", | ||
| 233 | + details: nil)) | ||
| 234 | + return | ||
| 235 | + } | ||
| 223 | do { | 236 | do { |
| 224 | try device.lockForConfiguration() | 237 | try device.lockForConfiguration() |
| 225 | device.torchMode = call.arguments as! Int == 1 ? .on : .off | 238 | device.torchMode = call.arguments as! Int == 1 ? .on : .off |
| @@ -230,12 +243,18 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -230,12 +243,18 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 230 | } | 243 | } |
| 231 | } | 244 | } |
| 232 | 245 | ||
| 233 | - func switchAnalyzeMode(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 234 | - analyzeMode = call.arguments as! Int | ||
| 235 | - result(nil) | ||
| 236 | - } | 246 | +// func switchAnalyzeMode(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| 247 | +// analyzeMode = call.arguments as! Int | ||
| 248 | +// result(nil) | ||
| 249 | +// } | ||
| 237 | 250 | ||
| 238 | func stop(_ result: FlutterResult) { | 251 | func stop(_ result: FlutterResult) { |
| 252 | + if (device == nil) { | ||
| 253 | + result(FlutterError(code: "MobileScanner", | ||
| 254 | + message: "Called stop() while already stopped!", | ||
| 255 | + details: nil)) | ||
| 256 | + return | ||
| 257 | + } | ||
| 239 | captureSession.stopRunning() | 258 | captureSession.stopRunning() |
| 240 | for input in captureSession.inputs { | 259 | for input in captureSession.inputs { |
| 241 | captureSession.removeInput(input) | 260 | captureSession.removeInput(input) |
| @@ -246,7 +265,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | @@ -246,7 +265,7 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan | ||
| 246 | device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) | 265 | device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) |
| 247 | registry.unregisterTexture(textureId) | 266 | registry.unregisterTexture(textureId) |
| 248 | 267 | ||
| 249 | - analyzeMode = 0 | 268 | +// analyzeMode = 0 |
| 250 | latestBuffer = nil | 269 | latestBuffer = nil |
| 251 | captureSession = nil | 270 | captureSession = nil |
| 252 | device = nil | 271 | device = nil |
| @@ -27,7 +27,7 @@ enum TorchState { | @@ -27,7 +27,7 @@ enum TorchState { | ||
| 27 | on, | 27 | on, |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | -enum AnalyzeMode { none, barcode } | 30 | +// enum AnalyzeMode { none, barcode } |
| 31 | 31 | ||
| 32 | class MobileScannerController { | 32 | class MobileScannerController { |
| 33 | MethodChannel methodChannel = | 33 | MethodChannel methodChannel = |
| @@ -62,8 +62,8 @@ class MobileScannerController { | @@ -62,8 +62,8 @@ class MobileScannerController { | ||
| 62 | 62 | ||
| 63 | // Sets analyze mode and barcode stream | 63 | // Sets analyze mode and barcode stream |
| 64 | barcodesController = StreamController.broadcast( | 64 | barcodesController = StreamController.broadcast( |
| 65 | - onListen: () => setAnalyzeMode(AnalyzeMode.barcode.index), | ||
| 66 | - onCancel: () => setAnalyzeMode(AnalyzeMode.none.index), | 65 | + // onListen: () => setAnalyzeMode(AnalyzeMode.barcode.index), |
| 66 | + // onCancel: () => setAnalyzeMode(AnalyzeMode.none.index), | ||
| 67 | ); | 67 | ); |
| 68 | 68 | ||
| 69 | start(); | 69 | start(); |
| @@ -94,20 +94,22 @@ class MobileScannerController { | @@ -94,20 +94,22 @@ class MobileScannerController { | ||
| 94 | } | 94 | } |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | - void setAnalyzeMode(int mode) { | ||
| 98 | - if (hashCode != _controllerHashcode) { | ||
| 99 | - return; | ||
| 100 | - } | ||
| 101 | - methodChannel.invokeMethod('analyze', mode); | ||
| 102 | - } | 97 | + // TODO: Add more analyzers like text analyzer |
| 98 | + // void setAnalyzeMode(int mode) { | ||
| 99 | + // if (hashCode != _controllerHashcode) { | ||
| 100 | + // return; | ||
| 101 | + // } | ||
| 102 | + // methodChannel.invokeMethod('analyze', mode); | ||
| 103 | + // } | ||
| 103 | 104 | ||
| 104 | // List<BarcodeFormats>? formats = _defaultBarcodeFormats, | 105 | // List<BarcodeFormats>? formats = _defaultBarcodeFormats, |
| 105 | /// Start barcode scanning. This will first check if the required permissions | 106 | /// Start barcode scanning. This will first check if the required permissions |
| 106 | /// are set. | 107 | /// are set. |
| 107 | Future<void> start() async { | 108 | Future<void> start() async { |
| 109 | + | ||
| 108 | ensure('startAsync'); | 110 | ensure('startAsync'); |
| 109 | 111 | ||
| 110 | - setAnalyzeMode(AnalyzeMode.barcode.index); | 112 | + // setAnalyzeMode(AnalyzeMode.barcode.index); |
| 111 | // Check authorization status | 113 | // Check authorization status |
| 112 | MobileScannerState state = | 114 | MobileScannerState state = |
| 113 | MobileScannerState.values[await methodChannel.invokeMethod('state')]; | 115 | MobileScannerState.values[await methodChannel.invokeMethod('state')]; |
| @@ -132,8 +134,15 @@ class MobileScannerController { | @@ -132,8 +134,15 @@ class MobileScannerController { | ||
| 132 | if (torchEnabled != null) arguments['torch'] = torchEnabled; | 134 | if (torchEnabled != null) arguments['torch'] = torchEnabled; |
| 133 | 135 | ||
| 134 | // Start the camera with arguments | 136 | // Start the camera with arguments |
| 135 | - final Map<String, dynamic>? startResult = await methodChannel | ||
| 136 | - .invokeMapMethod<String, dynamic>('start', arguments); | 137 | + Map<String, dynamic>? startResult = {}; |
| 138 | + try { | ||
| 139 | + startResult = await methodChannel | ||
| 140 | + .invokeMapMethod<String, dynamic>('start', arguments); | ||
| 141 | + } on PlatformException catch (error) { | ||
| 142 | + debugPrint('${error.code}: ${error.message}'); | ||
| 143 | + // setAnalyzeMode(AnalyzeMode.none.index); | ||
| 144 | + return; | ||
| 145 | + } | ||
| 137 | 146 | ||
| 138 | if (startResult == null) { | 147 | if (startResult == null) { |
| 139 | throw PlatformException(code: 'INITIALIZATION ERROR'); | 148 | throw PlatformException(code: 'INITIALIZATION ERROR'); |
| @@ -146,17 +155,32 @@ class MobileScannerController { | @@ -146,17 +155,32 @@ class MobileScannerController { | ||
| 146 | hasTorch: hasTorch); | 155 | hasTorch: hasTorch); |
| 147 | } | 156 | } |
| 148 | 157 | ||
| 149 | - Future<void> stop() async => await methodChannel.invokeMethod('stop'); | 158 | + Future<void> stop() async { |
| 159 | + try { | ||
| 160 | + await methodChannel.invokeMethod('stop'); | ||
| 161 | + } on PlatformException catch (error) { | ||
| 162 | + debugPrint('${error.code}: ${error.message}'); | ||
| 163 | + } | ||
| 164 | + } | ||
| 150 | 165 | ||
| 151 | /// Switches the torch on or off. | 166 | /// Switches the torch on or off. |
| 152 | /// | 167 | /// |
| 153 | /// Only works if torch is available. | 168 | /// Only works if torch is available. |
| 154 | - void toggleTorch() { | 169 | + Future<void> toggleTorch() async { |
| 155 | ensure('toggleTorch'); | 170 | ensure('toggleTorch'); |
| 156 | - if (!hasTorch) return; | 171 | + if (!hasTorch) { |
| 172 | + debugPrint('Device has no torch/flash.'); | ||
| 173 | + return; | ||
| 174 | + } | ||
| 175 | + | ||
| 157 | TorchState state = | 176 | TorchState state = |
| 158 | torchState.value == TorchState.off ? TorchState.on : TorchState.off; | 177 | torchState.value == TorchState.off ? TorchState.on : TorchState.off; |
| 159 | - methodChannel.invokeMethod('torch', state.index); | 178 | + |
| 179 | + try { | ||
| 180 | + await methodChannel.invokeMethod('torch', state.index); | ||
| 181 | + } on PlatformException catch (error) { | ||
| 182 | + debugPrint('${error.code}: ${error.message}'); | ||
| 183 | + } | ||
| 160 | } | 184 | } |
| 161 | 185 | ||
| 162 | /// Switches the torch on or off. | 186 | /// Switches the torch on or off. |
| @@ -164,10 +188,15 @@ class MobileScannerController { | @@ -164,10 +188,15 @@ class MobileScannerController { | ||
| 164 | /// Only works if torch is available. | 188 | /// Only works if torch is available. |
| 165 | Future<void> switchCamera() async { | 189 | Future<void> switchCamera() async { |
| 166 | ensure('switchCamera'); | 190 | ensure('switchCamera'); |
| 167 | - await stop(); | 191 | + try { |
| 192 | + await methodChannel.invokeMethod('stop'); | ||
| 193 | + } on PlatformException catch (error) { | ||
| 194 | + debugPrint('${error.code}: camera is stopped! Please start before switching camera.'); | ||
| 195 | + return; | ||
| 196 | + } | ||
| 168 | facing = | 197 | facing = |
| 169 | facing == CameraFacing.back ? CameraFacing.front : CameraFacing.back; | 198 | facing == CameraFacing.back ? CameraFacing.front : CameraFacing.back; |
| 170 | - start(); | 199 | + await start(); |
| 171 | } | 200 | } |
| 172 | 201 | ||
| 173 | /// Disposes the controller and closes all listeners. | 202 | /// Disposes the controller and closes all listeners. |
| @@ -22,7 +22,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -22,7 +22,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 22 | var latestBuffer: CVImageBuffer! | 22 | var latestBuffer: CVImageBuffer! |
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | - var analyzeMode: Int = 0 | 25 | +// var analyzeMode: Int = 0 |
| 26 | var analyzing: Bool = false | 26 | var analyzing: Bool = false |
| 27 | var position = AVCaptureDevice.Position.back | 27 | var position = AVCaptureDevice.Position.back |
| 28 | 28 | ||
| @@ -52,9 +52,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -52,9 +52,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 52 | case "start": | 52 | case "start": |
| 53 | start(call, result) | 53 | start(call, result) |
| 54 | case "torch": | 54 | case "torch": |
| 55 | - switchTorch(call, result) | ||
| 56 | - case "analyze": | ||
| 57 | - switchAnalyzeMode(call, result) | 55 | + toggleTorch(call, result) |
| 56 | +// case "analyze": | ||
| 57 | +// switchAnalyzeMode(call, result) | ||
| 58 | case "stop": | 58 | case "stop": |
| 59 | stop(result) | 59 | stop(result) |
| 60 | default: | 60 | default: |
| @@ -92,14 +92,14 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -92,14 +92,14 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 92 | latestBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) | 92 | latestBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) |
| 93 | registry.textureFrameAvailable(textureId) | 93 | registry.textureFrameAvailable(textureId) |
| 94 | 94 | ||
| 95 | - switch analyzeMode { | ||
| 96 | - case 1: // barcode | 95 | +// switch analyzeMode { |
| 96 | +// case 1: // barcode | ||
| 97 | 97 | ||
| 98 | // Limit the analyzer because the texture output will freeze otherwise | 98 | // Limit the analyzer because the texture output will freeze otherwise |
| 99 | if i / 10 == 1 { | 99 | if i / 10 == 1 { |
| 100 | i = 0 | 100 | i = 0 |
| 101 | } else { | 101 | } else { |
| 102 | - break | 102 | + return |
| 103 | } | 103 | } |
| 104 | let imageRequestHandler = VNImageRequestHandler( | 104 | let imageRequestHandler = VNImageRequestHandler( |
| 105 | cvPixelBuffer: latestBuffer, | 105 | cvPixelBuffer: latestBuffer, |
| @@ -129,9 +129,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -129,9 +129,9 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 129 | print(error) | 129 | print(error) |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | - default: // none | ||
| 133 | - break | ||
| 134 | - } | 132 | +// default: // none |
| 133 | +// break | ||
| 134 | +// } | ||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | func checkPermission(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 137 | func checkPermission(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| @@ -159,6 +159,13 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -159,6 +159,13 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 161 | func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| 162 | + if (device != nil) { | ||
| 163 | + result(FlutterError(code: "MobileScanner", | ||
| 164 | + message: "Called start() while already started!", | ||
| 165 | + details: nil)) | ||
| 166 | + return | ||
| 167 | + } | ||
| 168 | + | ||
| 162 | textureId = registry.register(self) | 169 | textureId = registry.register(self) |
| 163 | captureSession = AVCaptureSession() | 170 | captureSession = AVCaptureSession() |
| 164 | 171 | ||
| @@ -222,7 +229,13 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -222,7 +229,13 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 222 | result(answer) | 229 | result(answer) |
| 223 | } | 230 | } |
| 224 | 231 | ||
| 225 | - func switchTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | 232 | + func toggleTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { |
| 233 | + if (device == nil) { | ||
| 234 | + result(FlutterError(code: "MobileScanner", | ||
| 235 | + message: "Called toggleTorch() while stopped!", | ||
| 236 | + details: nil)) | ||
| 237 | + return | ||
| 238 | + } | ||
| 226 | do { | 239 | do { |
| 227 | try device.lockForConfiguration() | 240 | try device.lockForConfiguration() |
| 228 | device.torchMode = call.arguments as! Int == 1 ? .on : .off | 241 | device.torchMode = call.arguments as! Int == 1 ? .on : .off |
| @@ -232,13 +245,19 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -232,13 +245,19 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 232 | result(FlutterError(code: error.localizedDescription, message: nil, details: nil)) | 245 | result(FlutterError(code: error.localizedDescription, message: nil, details: nil)) |
| 233 | } | 246 | } |
| 234 | } | 247 | } |
| 235 | - | ||
| 236 | - func switchAnalyzeMode(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 237 | - analyzeMode = call.arguments as! Int | ||
| 238 | - result(nil) | ||
| 239 | - } | ||
| 240 | - | 248 | + |
| 249 | +// func switchAnalyzeMode(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 250 | +// analyzeMode = call.arguments as! Int | ||
| 251 | +// result(nil) | ||
| 252 | +// } | ||
| 253 | + | ||
| 241 | func stop(_ result: FlutterResult) { | 254 | func stop(_ result: FlutterResult) { |
| 255 | + if (device == nil) { | ||
| 256 | + result(FlutterError(code: "MobileScanner", | ||
| 257 | + message: "Called stop() while already stopped!", | ||
| 258 | + details: nil)) | ||
| 259 | + return | ||
| 260 | + } | ||
| 242 | captureSession.stopRunning() | 261 | captureSession.stopRunning() |
| 243 | for input in captureSession.inputs { | 262 | for input in captureSession.inputs { |
| 244 | captureSession.removeInput(input) | 263 | captureSession.removeInput(input) |
| @@ -249,7 +268,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | @@ -249,7 +268,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, | ||
| 249 | device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) | 268 | device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) |
| 250 | registry.unregisterTexture(textureId) | 269 | registry.unregisterTexture(textureId) |
| 251 | 270 | ||
| 252 | - analyzeMode = 0 | 271 | +// analyzeMode = 0 |
| 253 | latestBuffer = nil | 272 | latestBuffer = nil |
| 254 | captureSession = nil | 273 | captureSession = nil |
| 255 | device = nil | 274 | device = nil |
macos/Classes/Util.swift
deleted
100644 → 0
| 1 | - |
-
Please register or login to post a comment