From 2a967252498ca0b06c1cc8f155ac658edf4af366 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Mon, 25 Jan 2021 13:58:20 +0100 Subject: [PATCH 1/3] Fixed permission callback. --- .../net/touchcapture/qr/flutterqr/QRView.kt | 19 +++ ios/Classes/QRView.swift | 153 +++++++++++------- lib/src/qr_code_scanner.dart | 29 ++-- 3 files changed, 133 insertions(+), 68 deletions(-) diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt index 91ad6f3..ca4f639 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt @@ -89,7 +89,10 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap?, result: MethodChannel.Result) { + if (!hasCameraPermission()) { + return cameraPermissionNotSet(result) + } + val allowedBarcodeTypes = mutableListOf() try { arguments?.forEach { diff --git a/ios/Classes/QRView.swift b/ios/Classes/QRView.swift index c400d4d..1674187 100644 --- a/ios/Classes/QRView.swift +++ b/ios/Classes/QRView.swift @@ -46,7 +46,7 @@ public class QRView:NSObject,FlutterPlatformView { switch(call.method){ case "setDimensions": let arguments = call.arguments as! Dictionary - self?.setDimensions(width: arguments["width"] ?? 0, height: arguments["height"] ?? 0, scanArea: arguments["scanArea"] ?? 0) + self?.setDimensions(result, width: arguments["width"] ?? 0, height: arguments["height"] ?? 0, scanArea: arguments["scanArea"] ?? 0) case "startScan": self?.startScan(call.arguments as! Array, result) case "flipCamera": @@ -71,32 +71,39 @@ public class QRView:NSObject,FlutterPlatformView { return previewView } - func setDimensions(width: Double, height: Double, scanArea: Double) -> Void { - // First set the size of the preview area. - previewView.frame = CGRect(x: 0, y: 0, width: width, height: height) - - // Then set the size of the scan area. - let midX = self.view().bounds.midX - let midY = self.view().bounds.midY - - // Check if the scanner is already created. - if let sc: MTBBarcodeScanner = scanner { - if let previewLayer = sc.previewLayer { - previewLayer.frame = previewView.bounds; - } - if (scanArea != 0) { - sc.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea) - } - } else { - // Create a scanner view if it doesn't exist yet. - scanner = MTBBarcodeScanner(previewView: previewView) - - if (scanArea != 0) { - scanner?.didStartScanningBlock = { - self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea) + func setDimensions(_ result: @escaping FlutterResult, width: Double, height: Double, scanArea: Double) -> Void { + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + // First set the size of the preview area. + self.previewView.frame = CGRect(x: 0, y: 0, width: width, height: height) + + // Then set the size of the scan area. + let midX = self.view().bounds.midX + let midY = self.view().bounds.midY + + // Check if the scanner is already created. + if let sc: MTBBarcodeScanner = self.scanner { + if let previewLayer = sc.previewLayer { + previewLayer.frame = self.previewView.bounds; + } + if (scanArea != 0) { + sc.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea) + } + } else { + // Create a scanner view if it doesn't exist yet. + self.scanner = MTBBarcodeScanner(previewView: self.previewView) + + if (scanArea != 0) { + self.scanner?.didStartScanningBlock = { + self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea) + } + } } + return result(width) + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) } - } + }) } func startScan(_ arguments: Array, _ result: @escaping FlutterResult) -> Void { @@ -154,21 +161,27 @@ public class QRView:NSObject,FlutterPlatformView { }) } catch { let error = FlutterError(code: "unknown-error", message: "Unable to start scanning", details: nil) - result(error) + return result(error) } } else { - let error = FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil) - result(error) + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) } }) + } - func stopScan(){ - if let sc: MTBBarcodeScanner = scanner { - if sc.isScanning() { - sc.stopScanning() + func stopScan(_ result: @escaping FlutterResult){ + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + if let sc: MTBBarcodeScanner = self.scanner { + if sc.isScanning() { + sc.stopScanning() + } + } + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) } - } + }) } func getCameraInfo(_ result: @escaping FlutterResult) -> Void { @@ -181,13 +194,19 @@ public class QRView:NSObject,FlutterPlatformView { } func flipCamera(_ result: @escaping FlutterResult){ - if let sc: MTBBarcodeScanner = scanner { - if sc.hasOppositeCamera() { - sc.flipCamera() + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + if let sc: MTBBarcodeScanner = self.scanner { + if sc.hasOppositeCamera() { + sc.flipCamera() + } + return result(sc.camera.rawValue) + } + return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) } - return result(sc.camera.rawValue) - } - return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + }) } func getFlashInfo(_ result: @escaping FlutterResult) -> Void { @@ -200,34 +219,52 @@ public class QRView:NSObject,FlutterPlatformView { } func toggleFlash(_ result: @escaping FlutterResult){ - if let sc: MTBBarcodeScanner = scanner { - if sc.hasTorch() { - sc.toggleTorch() - return result(sc.torchMode == MTBTorchMode(rawValue: 1)) + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + if let sc: MTBBarcodeScanner = self.scanner { + if sc.hasTorch() { + sc.toggleTorch() + return result(sc.torchMode == MTBTorchMode(rawValue: 1)) + } + return result(FlutterError(code: "404", message: "This device doesn\'t support flash", details: nil)) + } + return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) } - return result(FlutterError(code: "404", message: "This device doesn\'t support flash", details: nil)) - } - return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + }) } func pauseCamera(_ result: @escaping FlutterResult) { - if let sc: MTBBarcodeScanner = scanner { - if sc.isScanning() { - sc.freezeCapture() + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + if let sc: MTBBarcodeScanner = self.scanner { + if sc.isScanning() { + sc.freezeCapture() + } + return result(true) + } + return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) } - return result(true) - } - return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + }) } func resumeCamera(_ result: @escaping FlutterResult) { - if let sc: MTBBarcodeScanner = scanner { - if !sc.isScanning() { - sc.unfreezeCapture() + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + if let sc: MTBBarcodeScanner = self.scanner { + if !sc.isScanning() { + sc.unfreezeCapture() + } + return result(true) + } + return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) } - return result(true) - } - return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil)) + }) } func getSystemFeatures(_ result: @escaping FlutterResult) -> Void { diff --git a/lib/src/qr_code_scanner.dart b/lib/src/qr_code_scanner.dart index da0fc18..0ef137e 100644 --- a/lib/src/qr_code_scanner.dart +++ b/lib/src/qr_code_scanner.dart @@ -211,9 +211,14 @@ class QRViewController { Future _startScan(GlobalKey key, double cutOutSize, List barcodeFormats) async { // We need to update the dimension before the scan is started. - QRViewController.updateDimensions(key, _channel, scanArea: cutOutSize); - return _channel.invokeMethod( - 'startScan', barcodeFormats?.map((e) => e.asInt())?.toList() ?? []); + try { + await QRViewController.updateDimensions(key, _channel, + scanArea: cutOutSize); + return await _channel.invokeMethod( + 'startScan', barcodeFormats?.map((e) => e.asInt())?.toList() ?? []); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } } /// Gets information about which camera is active. @@ -289,15 +294,19 @@ class QRViewController { } /// Updates the view dimensions for iOS. - static void updateDimensions(GlobalKey key, MethodChannel channel, - {double scanArea}) { + static Future updateDimensions(GlobalKey key, MethodChannel channel, + {double scanArea}) async { if (defaultTargetPlatform == TargetPlatform.iOS) { final RenderBox renderBox = key.currentContext.findRenderObject(); - channel.invokeMethod('setDimensions', { - 'width': renderBox.size.width, - 'height': renderBox.size.height, - 'scanArea': scanArea ?? 0 - }); + try { + await channel.invokeMethod('setDimensions', { + 'width': renderBox.size.width, + 'height': renderBox.size.height, + 'scanArea': scanArea ?? 0 + }); + } on PlatformException catch (e) { + throw CameraException(e.code, e.message); + } } } } From 7c40d4f00cca7e94137c4e3d02519e35a1740a3f Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Wed, 3 Feb 2021 21:25:15 +0100 Subject: [PATCH 2/3] Fixed android bug not pausing or flipping camera --- .../kotlin/net/touchcapture/qr/flutterqr/QRView.kt | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt index ca4f639..498911d 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt @@ -182,18 +182,7 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap Date: Wed, 3 Feb 2021 22:45:45 +0100 Subject: [PATCH 3/3] Fixed camerainfo returning null after permission --- ios/Classes/QRView.swift | 41 ++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/ios/Classes/QRView.swift b/ios/Classes/QRView.swift index 1674187..a564c1c 100644 --- a/ios/Classes/QRView.swift +++ b/ios/Classes/QRView.swift @@ -74,6 +74,7 @@ public class QRView:NSObject,FlutterPlatformView { func setDimensions(_ result: @escaping FlutterResult, width: Double, height: Double, scanArea: Double) -> Void { MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in if permissionGranted { +// self?.channel.invokeMethod("onPermissionSet", arguments: true) // First set the size of the preview area. self.previewView.frame = CGRect(x: 0, y: 0, width: width, height: height) @@ -111,14 +112,14 @@ public class QRView:NSObject,FlutterPlatformView { scanner = MTBBarcodeScanner(previewView: previewView) } - var allowedBarcodeTypes: Array = [] arguments.forEach { arg in allowedBarcodeTypes.append( QRCodeTypes[arg]!) } - + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in if permissionGranted { + self.channel.invokeMethod("onPermissionSet", arguments: true) do { try self.scanner?.startScanning(with: self.cameraFacing, resultBlock: { [weak self] codes in if let codes = codes { @@ -185,12 +186,18 @@ public class QRView:NSObject,FlutterPlatformView { } func getCameraInfo(_ result: @escaping FlutterResult) -> Void { - if let sc: MTBBarcodeScanner = scanner { - result(sc.camera.rawValue) - } else { - let error = FlutterError(code: "cameraInformationError", message: "Could not get camera information", details: nil) - result(error) - } + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + if let sc: MTBBarcodeScanner = self.scanner { + result(sc.camera.rawValue) + } else { + let error = FlutterError(code: "cameraInformationError", message: "Could not get camera information", details: nil) + result(error) + } + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) + } + }) } func flipCamera(_ result: @escaping FlutterResult){ @@ -210,12 +217,18 @@ public class QRView:NSObject,FlutterPlatformView { } func getFlashInfo(_ result: @escaping FlutterResult) -> Void { - if let sc: MTBBarcodeScanner = scanner { - result(sc.torchMode.rawValue != 0) - } else { - let error = FlutterError(code: "cameraInformationError", message: "Could not get flash information", details: nil) - result(error) - } + MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in + if permissionGranted { + if let sc: MTBBarcodeScanner = self.scanner { + result(sc.torchMode.rawValue != 0) + } else { + let error = FlutterError(code: "cameraInformationError", message: "Could not get flash information", details: nil) + result(error) + } + } else { + return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)) + } + }) } func toggleFlash(_ result: @escaping FlutterResult){