deprecate onPermissionSet; refactor error handling for start(); return instead o…
…f trowing if there is no torch
Showing
1 changed file
with
51 additions
and
28 deletions
| @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; | @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; | ||
| 6 | import 'package:flutter/services.dart'; | 6 | import 'package:flutter/services.dart'; |
| 7 | import 'package:mobile_scanner/mobile_scanner.dart'; | 7 | import 'package:mobile_scanner/mobile_scanner.dart'; |
| 8 | import 'package:mobile_scanner/src/barcode_utility.dart'; | 8 | import 'package:mobile_scanner/src/barcode_utility.dart'; |
| 9 | +import 'package:mobile_scanner/src/enums/mobile_scanner_error_code.dart'; | ||
| 9 | import 'package:mobile_scanner/src/mobile_scanner_exception.dart'; | 10 | import 'package:mobile_scanner/src/mobile_scanner_exception.dart'; |
| 10 | 11 | ||
| 11 | /// The [MobileScannerController] holds all the logic of this plugin, | 12 | /// The [MobileScannerController] holds all the logic of this plugin, |
| @@ -18,7 +19,10 @@ class MobileScannerController { | @@ -18,7 +19,10 @@ class MobileScannerController { | ||
| 18 | this.torchEnabled = false, | 19 | this.torchEnabled = false, |
| 19 | this.formats, | 20 | this.formats, |
| 20 | this.returnImage = false, | 21 | this.returnImage = false, |
| 21 | - this.onPermissionSet, | 22 | + @Deprecated( |
| 23 | + 'Instead, handle permission errors using the result of the `start()` method.', | ||
| 24 | + ) | ||
| 25 | + this.onPermissionSet, | ||
| 22 | }) { | 26 | }) { |
| 23 | // In case a new instance is created before calling dispose() | 27 | // In case a new instance is created before calling dispose() |
| 24 | if (controllerHashcode != null) { | 28 | if (controllerHashcode != null) { |
| @@ -74,6 +78,9 @@ class MobileScannerController { | @@ -74,6 +78,9 @@ class MobileScannerController { | ||
| 74 | static const EventChannel _eventChannel = | 78 | static const EventChannel _eventChannel = |
| 75 | EventChannel('dev.steenbakker.mobile_scanner/scanner/event'); | 79 | EventChannel('dev.steenbakker.mobile_scanner/scanner/event'); |
| 76 | 80 | ||
| 81 | + @Deprecated( | ||
| 82 | + 'Instead, handle permission errors using the result of the `start()` method.', | ||
| 83 | + ) | ||
| 77 | Function(bool permissionGranted)? onPermissionSet; | 84 | Function(bool permissionGranted)? onPermissionSet; |
| 78 | 85 | ||
| 79 | /// Listen to events from the platform specific code | 86 | /// Listen to events from the platform specific code |
| @@ -115,8 +122,14 @@ class MobileScannerController { | @@ -115,8 +122,14 @@ class MobileScannerController { | ||
| 115 | return arguments; | 122 | return arguments; |
| 116 | } | 123 | } |
| 117 | 124 | ||
| 118 | - /// Start barcode scanning. This will first check if the required permissions | ||
| 119 | - /// are set. | 125 | + /// Start scanning for barcodes. |
| 126 | + /// Upon calling this method, the necessary camera permission will be requested. | ||
| 127 | + /// | ||
| 128 | + /// Returns an instance of [MobileScannerArguments] | ||
| 129 | + /// when the scanner was successfully started. | ||
| 130 | + /// Returns null if the scanner is currently starting. | ||
| 131 | + /// | ||
| 132 | + /// Throws a [MobileScannerException] if starting the scanner failed. | ||
| 120 | Future<MobileScannerArguments?> start({ | 133 | Future<MobileScannerArguments?> start({ |
| 121 | CameraFacing? cameraFacingOverride, | 134 | CameraFacing? cameraFacingOverride, |
| 122 | }) async { | 135 | }) async { |
| @@ -124,6 +137,7 @@ class MobileScannerController { | @@ -124,6 +137,7 @@ class MobileScannerController { | ||
| 124 | debugPrint("Called start() while starting."); | 137 | debugPrint("Called start() while starting."); |
| 125 | return null; | 138 | return null; |
| 126 | } | 139 | } |
| 140 | + | ||
| 127 | isStarting = true; | 141 | isStarting = true; |
| 128 | 142 | ||
| 129 | // Check authorization status | 143 | // Check authorization status |
| @@ -136,16 +150,17 @@ class MobileScannerController { | @@ -136,16 +150,17 @@ class MobileScannerController { | ||
| 136 | await _methodChannel.invokeMethod('request') as bool? ?? false; | 150 | await _methodChannel.invokeMethod('request') as bool? ?? false; |
| 137 | if (!result) { | 151 | if (!result) { |
| 138 | isStarting = false; | 152 | isStarting = false; |
| 139 | - onPermissionSet?.call(result); | ||
| 140 | - throw MobileScannerException('User declined camera permission.'); | 153 | + throw const MobileScannerException( |
| 154 | + errorCode: MobileScannerErrorCode.permissionDenied, | ||
| 155 | + ); | ||
| 141 | } | 156 | } |
| 142 | break; | 157 | break; |
| 143 | case MobileScannerState.denied: | 158 | case MobileScannerState.denied: |
| 144 | isStarting = false; | 159 | isStarting = false; |
| 145 | - onPermissionSet?.call(false); | ||
| 146 | - throw MobileScannerException('User declined camera permission.'); | 160 | + throw const MobileScannerException( |
| 161 | + errorCode: MobileScannerErrorCode.permissionDenied, | ||
| 162 | + ); | ||
| 147 | case MobileScannerState.authorized: | 163 | case MobileScannerState.authorized: |
| 148 | - onPermissionSet?.call(true); | ||
| 149 | break; | 164 | break; |
| 150 | } | 165 | } |
| 151 | } | 166 | } |
| @@ -158,18 +173,27 @@ class MobileScannerController { | @@ -158,18 +173,27 @@ class MobileScannerController { | ||
| 158 | _argumentsToMap(cameraFacingOverride: cameraFacingOverride), | 173 | _argumentsToMap(cameraFacingOverride: cameraFacingOverride), |
| 159 | ); | 174 | ); |
| 160 | } on PlatformException catch (error) { | 175 | } on PlatformException catch (error) { |
| 161 | - debugPrint('${error.code}: ${error.message}'); | 176 | + MobileScannerErrorCode errorCode = MobileScannerErrorCode.genericError; |
| 177 | + | ||
| 162 | if (error.code == "MobileScannerWeb") { | 178 | if (error.code == "MobileScannerWeb") { |
| 163 | - onPermissionSet?.call(false); | 179 | + errorCode = MobileScannerErrorCode.permissionDenied; |
| 164 | } | 180 | } |
| 165 | isStarting = false; | 181 | isStarting = false; |
| 166 | - return null; | 182 | + |
| 183 | + throw MobileScannerException( | ||
| 184 | + errorCode: errorCode, | ||
| 185 | + errorDetails: MobileScannerErrorDetails( | ||
| 186 | + code: error.code, | ||
| 187 | + details: error.details as Object?, | ||
| 188 | + message: error.message, | ||
| 189 | + ), | ||
| 190 | + ); | ||
| 167 | } | 191 | } |
| 168 | 192 | ||
| 169 | if (startResult == null) { | 193 | if (startResult == null) { |
| 170 | isStarting = false; | 194 | isStarting = false; |
| 171 | - throw MobileScannerException( | ||
| 172 | - 'Failed to start mobileScanner, no response from platform side', | 195 | + throw const MobileScannerException( |
| 196 | + errorCode: MobileScannerErrorCode.genericError, | ||
| 173 | ); | 197 | ); |
| 174 | } | 198 | } |
| 175 | 199 | ||
| @@ -178,13 +202,6 @@ class MobileScannerController { | @@ -178,13 +202,6 @@ class MobileScannerController { | ||
| 178 | torchState.value = TorchState.on; | 202 | torchState.value = TorchState.on; |
| 179 | } | 203 | } |
| 180 | 204 | ||
| 181 | - if (kIsWeb) { | ||
| 182 | - // If we reach this line, it means camera permission has been granted | ||
| 183 | - onPermissionSet?.call( | ||
| 184 | - true, | ||
| 185 | - ); | ||
| 186 | - } | ||
| 187 | - | ||
| 188 | isStarting = false; | 205 | isStarting = false; |
| 189 | return startArguments.value = MobileScannerArguments( | 206 | return startArguments.value = MobileScannerArguments( |
| 190 | size: kIsWeb | 207 | size: kIsWeb |
| @@ -210,14 +227,18 @@ class MobileScannerController { | @@ -210,14 +227,18 @@ class MobileScannerController { | ||
| 210 | 227 | ||
| 211 | /// Switches the torch on or off. | 228 | /// Switches the torch on or off. |
| 212 | /// | 229 | /// |
| 213 | - /// Only works if torch is available. | 230 | + /// Does nothing if the device has no torch. |
| 231 | + /// | ||
| 232 | + /// Throws if the controller was not initialized. | ||
| 214 | Future<void> toggleTorch() async { | 233 | Future<void> toggleTorch() async { |
| 215 | - if (_hasTorch == null) { | ||
| 216 | - throw MobileScannerException( | ||
| 217 | - 'Cannot toggle torch if start() has never been called', | 234 | + final hasTorch = _hasTorch; |
| 235 | + | ||
| 236 | + if (hasTorch == null) { | ||
| 237 | + throw const MobileScannerException( | ||
| 238 | + errorCode: MobileScannerErrorCode.controllerUnititialized, | ||
| 218 | ); | 239 | ); |
| 219 | - } else if (!_hasTorch!) { | ||
| 220 | - throw MobileScannerException('Device has no torch'); | 240 | + } else if (!hasTorch) { |
| 241 | + return; | ||
| 221 | } | 242 | } |
| 222 | 243 | ||
| 223 | torchState.value = | 244 | torchState.value = |
| @@ -258,7 +279,6 @@ class MobileScannerController { | @@ -258,7 +279,6 @@ class MobileScannerController { | ||
| 258 | _barcodesController.close(); | 279 | _barcodesController.close(); |
| 259 | if (hashCode == controllerHashcode) { | 280 | if (hashCode == controllerHashcode) { |
| 260 | controllerHashcode = null; | 281 | controllerHashcode = null; |
| 261 | - onPermissionSet = null; | ||
| 262 | } | 282 | } |
| 263 | } | 283 | } |
| 264 | 284 | ||
| @@ -307,7 +327,10 @@ class MobileScannerController { | @@ -307,7 +327,10 @@ class MobileScannerController { | ||
| 307 | ); | 327 | ); |
| 308 | break; | 328 | break; |
| 309 | case 'error': | 329 | case 'error': |
| 310 | - throw MobileScannerException(data as String); | 330 | + throw MobileScannerException( |
| 331 | + errorCode: MobileScannerErrorCode.genericError, | ||
| 332 | + errorDetails: MobileScannerErrorDetails(message: data as String?), | ||
| 333 | + ); | ||
| 311 | default: | 334 | default: |
| 312 | throw UnimplementedError(name as String?); | 335 | throw UnimplementedError(name as String?); |
| 313 | } | 336 | } |
-
Please register or login to post a comment