From 93aa240cb244c1138d6c1c10f3475edfb6322500 Mon Sep 17 00:00:00 2001 From: Pedro Belfort Date: Thu, 23 Jul 2020 19:03:26 +0100 Subject: [PATCH 01/20] Add padding property to customize overlay shape position --- lib/src/qr_code_scanner.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/qr_code_scanner.dart b/lib/src/qr_code_scanner.dart index fad8126..8bedf5e 100644 --- a/lib/src/qr_code_scanner.dart +++ b/lib/src/qr_code_scanner.dart @@ -11,6 +11,7 @@ class QRView extends StatefulWidget { @required Key key, @required this.onQRViewCreated, this.overlay, + this.overlayMargin = EdgeInsets.zero, }) : assert(key != null), assert(onQRViewCreated != null), super(key: key); @@ -18,6 +19,7 @@ class QRView extends StatefulWidget { final QRViewCreatedCallback onQRViewCreated; final ShapeBorder overlay; + final EdgeInsetsGeometry overlayMargin; @override State createState() => _QRViewState(); @@ -31,6 +33,7 @@ class _QRViewState extends State { _getPlatformQrView(), if (widget.overlay != null) Container( + padding: widget.overlayMargin, decoration: ShapeDecoration( shape: widget.overlay, ), From 2dc74e0fb8c938e46c4f438517eb2ecb111914d3 Mon Sep 17 00:00:00 2001 From: Pedro Belfort Date: Mon, 31 Aug 2020 19:32:09 -0300 Subject: [PATCH 02/20] Restore XCode files --- example/lib/main.dart | 1 + lib/src/qr_code_scanner.dart | 3 --- lib/src/qr_scanner_overlay_shape.dart | 8 +++++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 25855f9..cb5701c 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -40,6 +40,7 @@ class _QRViewExampleState extends State { borderLength: 30, borderWidth: 10, cutOutSize: 300, + cutOutBottomOffset: 24, ), ), ), diff --git a/lib/src/qr_code_scanner.dart b/lib/src/qr_code_scanner.dart index 8bedf5e..fad8126 100644 --- a/lib/src/qr_code_scanner.dart +++ b/lib/src/qr_code_scanner.dart @@ -11,7 +11,6 @@ class QRView extends StatefulWidget { @required Key key, @required this.onQRViewCreated, this.overlay, - this.overlayMargin = EdgeInsets.zero, }) : assert(key != null), assert(onQRViewCreated != null), super(key: key); @@ -19,7 +18,6 @@ class QRView extends StatefulWidget { final QRViewCreatedCallback onQRViewCreated; final ShapeBorder overlay; - final EdgeInsetsGeometry overlayMargin; @override State createState() => _QRViewState(); @@ -33,7 +31,6 @@ class _QRViewState extends State { _getPlatformQrView(), if (widget.overlay != null) Container( - padding: widget.overlayMargin, decoration: ShapeDecoration( shape: widget.overlay, ), diff --git a/lib/src/qr_scanner_overlay_shape.dart b/lib/src/qr_scanner_overlay_shape.dart index 886c533..77c1a14 100644 --- a/lib/src/qr_scanner_overlay_shape.dart +++ b/lib/src/qr_scanner_overlay_shape.dart @@ -10,6 +10,7 @@ class QrScannerOverlayShape extends ShapeBorder { this.borderRadius = 0, this.borderLength = 40, this.cutOutSize = 250, + this.cutOutBottomOffset = 0, }) : assert( cutOutSize != null ?? cutOutSize != null ?? @@ -22,6 +23,7 @@ class QrScannerOverlayShape extends ShapeBorder { final double borderRadius; final double borderLength; final double cutOutSize; + final double cutOutBottomOffset; @override EdgeInsetsGeometry get dimensions => const EdgeInsets.all(10); @@ -86,7 +88,11 @@ class QrScannerOverlayShape extends ShapeBorder { final cutOutRect = Rect.fromLTWH( rect.left + width / 2 - _cutOutSize / 2 + borderOffset, - rect.top + height / 2 - _cutOutSize / 2 + borderOffset, + -cutOutBottomOffset + + rect.top + + height / 2 - + _cutOutSize / 2 + + borderOffset, _cutOutSize - borderOffset * 2, _cutOutSize - borderOffset * 2, ); From 4329569a79f302803e3d589697ca3fa8d1afec55 Mon Sep 17 00:00:00 2001 From: Pedro Belfort Date: Mon, 31 Aug 2020 19:38:50 -0300 Subject: [PATCH 03/20] Put back padding property --- lib/src/qr_code_scanner.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/qr_code_scanner.dart b/lib/src/qr_code_scanner.dart index fad8126..8bedf5e 100644 --- a/lib/src/qr_code_scanner.dart +++ b/lib/src/qr_code_scanner.dart @@ -11,6 +11,7 @@ class QRView extends StatefulWidget { @required Key key, @required this.onQRViewCreated, this.overlay, + this.overlayMargin = EdgeInsets.zero, }) : assert(key != null), assert(onQRViewCreated != null), super(key: key); @@ -18,6 +19,7 @@ class QRView extends StatefulWidget { final QRViewCreatedCallback onQRViewCreated; final ShapeBorder overlay; + final EdgeInsetsGeometry overlayMargin; @override State createState() => _QRViewState(); @@ -31,6 +33,7 @@ class _QRViewState extends State { _getPlatformQrView(), if (widget.overlay != null) Container( + padding: widget.overlayMargin, decoration: ShapeDecoration( shape: widget.overlay, ), From 709c06ddb8a63a9fc60108fa29737df44660684f Mon Sep 17 00:00:00 2001 From: Reid Lai Date: Wed, 30 Sep 2020 10:16:26 +0800 Subject: [PATCH 04/20] replace var to let --- ios/Classes/QRView.swift | 2 +- ios/Classes/QRViewFactory.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/Classes/QRView.swift b/ios/Classes/QRView.swift index 7eff009..376cec1 100644 --- a/ios/Classes/QRView.swift +++ b/ios/Classes/QRView.swift @@ -44,7 +44,7 @@ public class QRView:NSObject,FlutterPlatformView { [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in switch(call.method){ case "setDimensions": - var arguments = call.arguments as! Dictionary + let arguments = call.arguments as! Dictionary self?.setDimensions(width: arguments["width"] ?? 0,height: arguments["height"] ?? 0) case "flipCamera": self?.flipCamera() diff --git a/ios/Classes/QRViewFactory.swift b/ios/Classes/QRViewFactory.swift index 35442de..fff745b 100644 --- a/ios/Classes/QRViewFactory.swift +++ b/ios/Classes/QRViewFactory.swift @@ -17,7 +17,7 @@ public class QRViewFactory: NSObject, FlutterPlatformViewFactory { } public func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView { - var dictionary = args as! Dictionary + let dictionary = args as! Dictionary return QRView(withFrame: CGRect(x: 0, y: 0, width: dictionary["width"] ?? 0, height: dictionary["height"] ?? 0), withRegistrar: registrar!,withId: viewId) } From fed7f7e345e77a4a83b1bfd903f0dd12c55d8121 Mon Sep 17 00:00:00 2001 From: "operator.name" Date: Wed, 14 Oct 2020 17:30:58 +0100 Subject: [PATCH 05/20] Update example REAMD.md code to reflect api changes The example is copied verbatim from ./example/lib/main.dart --- example/README.md | 146 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 29 deletions(-) diff --git a/example/README.md b/example/README.md index 2ec5a26..d9a96cd 100644 --- a/example/README.md +++ b/example/README.md @@ -22,11 +22,15 @@ Demonstrates how to use the qr_code_scanner plugin. ## Example: ```dart import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; void main() => runApp(MaterialApp(home: QRViewExample())); +const flashOn = 'FLASH ON'; +const flashOff = 'FLASH OFF'; +const frontCamera = 'FRONT CAMERA'; +const backCamera = 'BACK CAMERA'; + class QRViewExample extends StatefulWidget { const QRViewExample({ Key key, @@ -37,60 +41,144 @@ class QRViewExample extends StatefulWidget { } class _QRViewExampleState extends State { - final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); - var qrText = ""; + var qrText = ''; + var flashState = flashOn; + var cameraState = frontCamera; QRViewController controller; + final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); + @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Expanded( + flex: 4, child: QRView( key: qrKey, onQRViewCreated: _onQRViewCreated, + overlay: QrScannerOverlayShape( + borderColor: Colors.red, + borderRadius: 10, + borderLength: 30, + borderWidth: 10, + cutOutSize: 300, + ), ), - flex: 4, ), Expanded( - child: Column(children: - [ - Text("This is the result of scan: $qrText"), - RaisedButton( - onPressed: (){ - if(controller != null){ - controller.flipCamera(); - } - }, - child: Text( - 'Flip', - style: TextStyle(fontSize: 20) + flex: 1, + child: FittedBox( + fit: BoxFit.contain, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text('This is the result of scan: $qrText'), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.all(8), + child: RaisedButton( + onPressed: () { + if (controller != null) { + controller.toggleFlash(); + if (_isFlashOn(flashState)) { + setState(() { + flashState = flashOff; + }); + } else { + setState(() { + flashState = flashOn; + }); + } + } + }, + child: + Text(flashState, style: TextStyle(fontSize: 20)), + ), + ), + Container( + margin: EdgeInsets.all(8), + child: RaisedButton( + onPressed: () { + if (controller != null) { + controller.flipCamera(); + if (_isBackCamera(cameraState)) { + setState(() { + cameraState = frontCamera; + }); + } else { + setState(() { + cameraState = backCamera; + }); + } + } + }, + child: + Text(cameraState, style: TextStyle(fontSize: 20)), + ), + ) + ], ), - ) - ], + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: EdgeInsets.all(8), + child: RaisedButton( + onPressed: () { + controller?.pauseCamera(); + }, + child: Text('pause', style: TextStyle(fontSize: 20)), + ), + ), + Container( + margin: EdgeInsets.all(8), + child: RaisedButton( + onPressed: () { + controller?.resumeCamera(); + }, + child: Text('resume', style: TextStyle(fontSize: 20)), + ), + ) + ], + ), + ], + ), ), - flex: 1, ) ], ), ); } + bool _isFlashOn(String current) { + return flashOn == current; + } + + bool _isBackCamera(String current) { + return backCamera == current; + } + void _onQRViewCreated(QRViewController controller) { - final channel = controller.channel; - controller.init(qrKey); this.controller = controller; - channel.setMethodCallHandler((MethodCall call) async { - switch (call.method) { - case "onRecognizeQR": - dynamic arguments = call.arguments; - setState(() { - qrText = arguments.toString(); - }); - } + controller.scannedDataStream.listen((scanData) { + setState(() { + qrText = scanData; + }); }); } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } } + ``` From fb885ff53e0823d78d8079793a1186972e6b903e Mon Sep 17 00:00:00 2001 From: "operator.name" Date: Wed, 14 Oct 2020 21:34:49 +0100 Subject: [PATCH 06/20] Update controller API examples in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cc2991e..ecbe13c 100644 --- a/README.md +++ b/README.md @@ -120,11 +120,11 @@ controller.toggleFlash(); ## Resume/Pause Pause camera stream and scanner. ```dart -controller.pause(); +controller.pauseCamera(); ``` Resume camera stream and scanner. ```dart -controller.resume(); +controller.resumeCamera(); ``` From 1ca3681943dd69851a288e30a5526e506fa33404 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Thu, 10 Dec 2020 11:04:39 +0100 Subject: [PATCH 07/20] Bumped version to 0.0.14. Rebuild outdated podspec. --- CHANGELOG.md | 3 + example/android/gradle.properties | 1 + example/ios/Podfile | 65 +++++-------------- example/ios/Runner.xcodeproj/project.pbxproj | 46 +++++-------- .../xcshareddata/WorkspaceSettings.xcsettings | 8 --- pubspec.yaml | 2 +- 6 files changed, 39 insertions(+), 86 deletions(-) delete mode 100644 example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/CHANGELOG.md b/CHANGELOG.md index b3d9a14..ad7b9bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.0.14 +* Fix disposing camera on iOS 14 (#113) + ## 0.0.13 * Fix misalignment when QRView doesn't start from the top left (#45) * Fix crash on iOS when scanning returns nil (#69, #72) diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 94adc3a..a673820 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true +android.enableR8=true diff --git a/example/ios/Podfile b/example/ios/Podfile index 799e2b4..1e8c3c9 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -4,69 +4,38 @@ # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' - project 'Runner', { 'Debug' => :debug, 'Profile' => :release, 'Release' => :release, } -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches end - pods_ary = [] - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) { |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - pods_ary.push({:name => podname, :path => podpath}); - else - puts "Invalid plugin specification: #{line}" - end - } - return pods_ary + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" end -target 'Runner' do - use_frameworks! +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - system('rm -rf .symlinks') - system('mkdir -p .symlinks/plugins') +flutter_ios_podfile_setup - # Flutter Pods - generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') - if generated_xcode_build_settings.empty? - puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." - end - generated_xcode_build_settings.map { |p| - if p[:name] == 'FLUTTER_FRAMEWORK_DIR' - symlink = File.join('.symlinks', 'flutter') - File.symlink(File.dirname(p[:path]), symlink) - pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) - end - } +target 'Runner' do + use_frameworks! + use_modular_headers! - # Plugin Pods - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.map { |p| - symlink = File.join('.symlinks', 'plugins', p[:name]) - File.symlink(p[:path], symlink) - pod p[:name], :path => File.join(symlink, 'ios') - } + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end post_install do |installer| installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' - end + flutter_additional_ios_build_settings(target) end end diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index e84dd13..1bb97b9 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -9,12 +9,8 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 72CA4F8FC83C02C1B0C5292A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D115C5DD3945F9758AB33CE2 /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -27,8 +23,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -39,18 +33,19 @@ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 4465DBB6FCA236431DE34346 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 87B204D37F3832F9BE4979B0 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9994328F3BE8CB44F875A29E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; D115C5DD3945F9758AB33CE2 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -59,8 +54,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 72CA4F8FC83C02C1B0C5292A /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -71,6 +64,9 @@ 0972BCF1757D16A75C3EC240 /* Pods */ = { isa = PBXGroup; children = ( + 4465DBB6FCA236431DE34346 /* Pods-Runner.debug.xcconfig */, + 9994328F3BE8CB44F875A29E /* Pods-Runner.release.xcconfig */, + 87B204D37F3832F9BE4979B0 /* Pods-Runner.profile.xcconfig */, ); name = Pods; sourceTree = ""; @@ -78,9 +74,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, @@ -174,6 +168,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = 5LSCTACHT8; LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; @@ -224,7 +219,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 3C208BB7148E708611B40C3B /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -253,17 +248,13 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/../Flutter/Flutter.framework", "${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework", "${BUILT_PRODUCTS_DIR}/qr_code_scanner/qr_code_scanner.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework", @@ -271,7 +262,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 9740EEB61CF901F6004384FC /* Run Script */ = { @@ -324,7 +315,6 @@ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -382,7 +372,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 5LSCTACHT8; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -394,7 +384,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = net.touch.capture; + PRODUCT_BUNDLE_IDENTIFIER = dev.steenbakker.capture; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.0; @@ -404,7 +394,6 @@ }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -462,7 +451,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; @@ -522,7 +510,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 5LSCTACHT8; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -534,7 +522,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = net.touch.capture; + PRODUCT_BUNDLE_IDENTIFIER = dev.steenbakker.capture; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -553,7 +541,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 5LSCTACHT8; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -565,7 +553,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = net.touch.capture; + PRODUCT_BUNDLE_IDENTIFIER = dev.steenbakker.capture; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 949b678..0000000 --- a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - BuildSystemType - Original - - diff --git a/pubspec.yaml b/pubspec.yaml index bf98b2b..e0eb626 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: qr_code_scanner description: QR code scanner that can be embedded inside flutter. It uses zxing in Android and MTBBarcode scanner in iOS. -version: 0.0.13 +version: 0.0.14 author: Julius Canute homepage: https://juliuscanute.com repository: https://github.com/juliuscanute/qr_code_scanner From 612051592c84bfa1b2965e73b48338baa10f0ce6 Mon Sep 17 00:00:00 2001 From: Ahmed Fathy Khalid Date: Thu, 10 Dec 2020 21:48:16 +0200 Subject: [PATCH 08/20] Properly implement ActivityLifecycleCallbacks public functions Fixing bug I encountered (Unit defined in android.app.Application.ActivityLifecycleCallbacks) e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (41, 77): Object is not abstract and does not implement abstract member public abstract fun onActivityPaused(@nonnull p0: Activity): Unit defined in android.app.Application.ActivityLifecycleCallbacks e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (42, 13): 'onActivityPaused' overrides nothing e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (48, 13): 'onActivityResumed' overrides nothing e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (54, 13): 'onActivityStarted' overrides nothing e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (57, 13): 'onActivityDestroyed' overrides nothing e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (60, 13): 'onActivitySaveInstanceState' overrides nothing e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (63, 13): 'onActivityStopped' overrides nothing e: C:\src\flutter.pub-cache\hosted\pub.dartlang.org\qr_code_scanner-0.0.14\android\src\main\kotlin\net\touchcapture\qr\flutterqr\QRView.kt: (66, 13): 'onActivityCreated' overrides nothing --- .../kotlin/net/touchcapture/qr/flutterqr/QRView.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 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 d99ddfb..ae6260c 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt @@ -39,31 +39,31 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : channel.setMethodCallHandler(this) checkAndRequestPermission(null) registrar.activity().application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { - override fun onActivityPaused(p0: Activity?) { + override fun onActivityPaused(p0: Activity) { if (p0 == registrar.activity()) { barcodeView?.pause() } } - override fun onActivityResumed(p0: Activity?) { + override fun onActivityResumed(p0: Activity) { if (p0 == registrar.activity()) { barcodeView?.resume() } } - override fun onActivityStarted(p0: Activity?) { + override fun onActivityStarted(p0: Activity) { } - override fun onActivityDestroyed(p0: Activity?) { + override fun onActivityDestroyed(p0: Activity) { } - override fun onActivitySaveInstanceState(p0: Activity?, p1: Bundle?) { + override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) { } - override fun onActivityStopped(p0: Activity?) { + override fun onActivityStopped(p0: Activity) { } - override fun onActivityCreated(p0: Activity?, p1: Bundle?) { + override fun onActivityCreated(p0: Activity, p1: Bundle?) { } }) } From 3d8712c94734476b553b2c404830f8b62e2601f8 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Thu, 10 Dec 2020 22:25:41 +0100 Subject: [PATCH 09/20] Updated Kotlin, Gradle & SDK versions. --- android/build.gradle | 8 ++++---- example/android/app/build.gradle | 8 +++----- example/android/build.gradle | 4 ++-- example/android/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index a5cb848..80bbfaa 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,14 +2,14 @@ group 'net.touchcapture.qr.flutterqr' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.3.21' + ext.kotlin_version = '1.4.21' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.2' + classpath 'com.android.tools.build:gradle:4.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -27,7 +27,7 @@ apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { - compileSdkVersion 28 + compileSdkVersion 30 sourceSets { @@ -48,6 +48,6 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation('com.journeyapps:zxing-android-embedded:4.1.0') { transitive = false } - implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.zxing:core:3.3.0' } diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index f738ff8..18b4d50 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 30 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -37,10 +37,9 @@ android { } defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "net.touchcapture.qr.flutterqrexample" minSdkVersion 19 - targetSdkVersion 27 + targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -48,7 +47,6 @@ android { buildTypes { release { - // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } @@ -61,7 +59,7 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13.1' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } diff --git a/example/android/build.gradle b/example/android/build.gradle index e7e0b02..b198b37 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.4.21' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.android.tools.build:gradle:4.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index aee9768..8d5215f 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu May 14 12:19:05 CEST 2020 +#Thu Dec 10 21:49:57 CET 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip From e0519a8b44770fa174205377d35565f0371ccf73 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Thu, 10 Dec 2020 23:28:15 +0100 Subject: [PATCH 10/20] Upgraded to Flutter Embedding V2. --- .../qr/flutterqr/FlutterQrPlugin.kt | 31 ++++++++++++++----- .../android/app/src/main/AndroidManifest.xml | 19 +++++++----- .../qr/flutterqrexample/MainActivity.kt | 9 +----- .../app/src/main/res/values/styles.xml | 4 +++ 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt index 9336335..4fce11d 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt @@ -1,24 +1,41 @@ package net.touchcapture.qr.flutterqr +import androidx.annotation.NonNull +import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.PluginRegistry.Registrar -class FlutterQrPlugin : MethodCallHandler { + +class FlutterQrPlugin : FlutterPlugin, MethodCallHandler { + + /** Plugin registration embedding v1 */ companion object { @JvmStatic fun registerWith(registrar: Registrar) { - registrar - .platformViewRegistry() - .registerViewFactory( - "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(registrar)) + FlutterQrPlugin().onAttachedToEngine(registrar) } } + /** Plugin registration embedding v2 */ + override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + onAttachedToEngine(flutterPluginBinding) + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + } + + private fun onAttachedToEngine(registrar: Registrar) { + registrar + .platformViewRegistry() + .registerViewFactory( + "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(registrar)) + } + override fun onMethodCall(call: MethodCall, result: Result) { - when { - call.method == "getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}") + when (call.method) { + "getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}") else -> result.notImplemented() } } diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 8a40bfb..3407805 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -13,7 +13,6 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> - + + + android:name="io.flutter.embedding.android.SplashScreenDrawable" + android:resource="@drawable/launch_background" /> + + + diff --git a/example/android/app/src/main/kotlin/net/touchcapture/qr/flutterqrexample/MainActivity.kt b/example/android/app/src/main/kotlin/net/touchcapture/qr/flutterqrexample/MainActivity.kt index fcdee63..3a276af 100644 --- a/example/android/app/src/main/kotlin/net/touchcapture/qr/flutterqrexample/MainActivity.kt +++ b/example/android/app/src/main/kotlin/net/touchcapture/qr/flutterqrexample/MainActivity.kt @@ -1,13 +1,6 @@ package net.touchcapture.qr.flutterqrexample -import android.os.Bundle - -import io.flutter.app.FlutterActivity -import io.flutter.plugins.GeneratedPluginRegistrant +import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - GeneratedPluginRegistrant.registerWith(this) - } } diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml index 00fa441..cd32859 100644 --- a/example/android/app/src/main/res/values/styles.xml +++ b/example/android/app/src/main/res/values/styles.xml @@ -5,4 +5,8 @@ Flutter draws its first frame --> @drawable/launch_background + + From 916c112e83502c9d1359fde89f1358758125a2f2 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Fri, 11 Dec 2020 10:36:00 +0100 Subject: [PATCH 11/20] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 24 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 17 ++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2393c04 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,24 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG] " +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Flutter information** +Always provide the output of `flutter doctor -v` as it is needed in order to know on which Flutter versions the bug exists in. + +**Device (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..864a505 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[FEATURE] " +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Additional context** +Add any other context or screenshots about the feature request here. From 076fdc184176af07232165efd3411e9defd3bb32 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Sun, 13 Dec 2020 20:54:09 +0100 Subject: [PATCH 12/20] Updated to minSdkVersion 20 because of Native View. --- android/build.gradle | 3 ++- example/android/app/build.gradle | 3 ++- example/android/app/src/main/res/values/styles.xml | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 80bbfaa..437c6b4 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,8 @@ android { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { - minSdkVersion 19 + // minSdkVersion is determined by Native View. + minSdkVersion 20 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } lintOptions { diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 18b4d50..a2c7d06 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -38,7 +38,8 @@ android { defaultConfig { applicationId "net.touchcapture.qr.flutterqrexample" - minSdkVersion 19 + // minSdkVersion is determined by Native View. + minSdkVersion 20 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml index cd32859..3257023 100644 --- a/example/android/app/src/main/res/values/styles.xml +++ b/example/android/app/src/main/res/values/styles.xml @@ -1,10 +1,17 @@ + + From 507857a2efa27906c2592d9eb9d90c4a225e4ab6 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Sun, 13 Dec 2020 22:47:53 +0100 Subject: [PATCH 13/20] Implemented activityAware interface. --- .../qr/flutterqr/FlutterQrPlugin.kt | 118 +++++++++++++++--- .../net/touchcapture/qr/flutterqr/QRView.kt | 76 ++--------- .../qr/flutterqr/QRViewFactory.kt | 6 +- .../net/touchcapture/qr/flutterqr/Shared.kt | 10 ++ 4 files changed, 126 insertions(+), 84 deletions(-) create mode 100644 android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt index 4fce11d..035431e 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt @@ -1,42 +1,128 @@ package net.touchcapture.qr.flutterqr +import android.Manifest +import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build import androidx.annotation.NonNull import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result -import io.flutter.plugin.common.PluginRegistry.Registrar +import io.flutter.plugin.common.PluginRegistry -class FlutterQrPlugin : FlutterPlugin, MethodCallHandler { +class FlutterQrPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { - /** Plugin registration embedding v1 */ - companion object { - @JvmStatic - fun registerWith(registrar: Registrar) { - FlutterQrPlugin().onAttachedToEngine(registrar) - } - } + var cameraPermissionContinuation: Runnable? = null + var requestingPermission = false +// private var activity: Activity? = null + +// /** Plugin registration embedding v1 */ +// companion object { +// @JvmStatic +// fun registerWith(registrar: Registrar) { +// FlutterQrPlugin().onAttachedToEngine(registrar) +// } +// } /** Plugin registration embedding v2 */ override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - onAttachedToEngine(flutterPluginBinding) + onAttachedToEngines(flutterPluginBinding) } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { } - private fun onAttachedToEngine(registrar: Registrar) { - registrar - .platformViewRegistry() + // TODO: Fix v1 embedding for Flutter < 1.12 support + /** Plugin start for both embedding v1 & v2 */ + private fun onAttachedToEngines(binding: FlutterPlugin.FlutterPluginBinding) { + binding.platformViewRegistry .registerViewFactory( - "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(registrar)) + "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(binding.binaryMessenger)) } +// private fun onAttachedToEngine(registrar: Registrar) { +// activity = registrar.activity() +// registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) +// checkAndRequestPermission(null) +// registrar +// .platformViewRegistry() +// .registerViewFactory( +// "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(registrar)) +// } + override fun onMethodCall(call: MethodCall, result: Result) { when (call.method) { - "getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}") - else -> result.notImplemented() + "checkAndRequestPermission" -> checkAndRequestPermission(result) + } + } + + override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) { + Shared.activityPluginBinding = activityPluginBinding + Shared.activity = activityPluginBinding.activity + activityPluginBinding.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) + checkAndRequestPermission(null) + } + + override fun onDetachedFromActivityForConfigChanges() { + Shared.activityPluginBinding = null + Shared.activity = null + } + + override fun onReattachedToActivityForConfigChanges(activityPluginBinding: ActivityPluginBinding) { + Shared.activityPluginBinding = activityPluginBinding + Shared.activity = activityPluginBinding.activity + } + + override fun onDetachedFromActivity() { + Shared.activityPluginBinding = null + Shared.activity = null + } + + private inner class CameraRequestPermissionsListener : PluginRegistry.RequestPermissionsResultListener { + override fun onRequestPermissionsResult(id: Int, permissions: Array, grantResults: IntArray): Boolean { + if (id == QRView.CAMERA_REQUEST_ID && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + cameraPermissionContinuation?.run() + return true + } + return false + } + } + + private fun hasCameraPermission(): Boolean { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || + Shared.activity?.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED + } + + private fun checkAndRequestPermission(result: Result?) { + if (cameraPermissionContinuation != null) { + result?.error("cameraPermission", "Camera permission request ongoing", null); + } + + cameraPermissionContinuation = Runnable { + cameraPermissionContinuation = null + if (!hasCameraPermission()) { + result?.error( + "cameraPermission", "MediaRecorderCamera permission not granted", null) + return@Runnable + } + } + + requestingPermission = false + if (hasCameraPermission()) { + cameraPermissionContinuation?.run() + } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestingPermission = true + Shared.activity?.requestPermissions( + arrayOf(Manifest.permission.CAMERA), + QRView.CAMERA_REQUEST_ID) + } } } } 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 ae6260c..ede6fc2 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt @@ -1,12 +1,9 @@ package net.touchcapture.qr.flutterqr -import android.Manifest import android.app.Activity import android.app.Application import android.content.Context import android.content.pm.PackageManager -import android.content.pm.PackageManager.PERMISSION_GRANTED -import android.os.Build import android.os.Bundle import android.view.View import com.google.zxing.ResultPoint @@ -14,39 +11,34 @@ import android.hardware.Camera.CameraInfo import com.journeyapps.barcodescanner.BarcodeCallback import com.journeyapps.barcodescanner.BarcodeResult import com.journeyapps.barcodescanner.BarcodeView +import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.platform.PlatformView - -class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : - PlatformView,MethodChannel.MethodCallHandler { +class QRView(messenger: BinaryMessenger, id: Int, private val context: Context) : + PlatformView, MethodChannel.MethodCallHandler { companion object { const val CAMERA_REQUEST_ID = 513469796 } var barcodeView: BarcodeView? = null - private val activity = registrar.activity() - var cameraPermissionContinuation: Runnable? = null - var requestingPermission = false + private var isTorchOn: Boolean = false val channel: MethodChannel init { - registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) - channel = MethodChannel(registrar.messenger(), "net.touchcapture.qr.flutterqr/qrview_$id") + channel = MethodChannel(messenger, "net.touchcapture.qr.flutterqr/qrview_$id") channel.setMethodCallHandler(this) - checkAndRequestPermission(null) - registrar.activity().application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { + Shared.activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { override fun onActivityPaused(p0: Activity) { - if (p0 == registrar.activity()) { + if (p0 == Shared.activity) { barcodeView?.pause() } } override fun onActivityResumed(p0: Activity) { - if (p0 == registrar.activity()) { + if (p0 == Shared.activity) { barcodeView?.resume() } } @@ -102,7 +94,7 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : } private fun hasFlash(): Boolean { - return registrar.activeContext().packageManager + return context.packageManager .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH) } @@ -120,7 +112,7 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : } private fun createBarCodeView(): BarcodeView? { - val barcode = BarcodeView(registrar.activity()) + val barcode = BarcodeView(Shared.activity) barcode.decodeContinuous( object : BarcodeCallback { override fun barcodeResult(result: BarcodeResult) { @@ -138,27 +130,8 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : barcodeView = null } - private inner class CameraRequestPermissionsListener : PluginRegistry.RequestPermissionsResultListener { - override fun onRequestPermissionsResult(id: Int, permissions: Array, grantResults: IntArray): Boolean { - if (id == CAMERA_REQUEST_ID && grantResults[0] == PERMISSION_GRANTED) { - cameraPermissionContinuation?.run() - return true - } - return false - } - } - - private fun hasCameraPermission(): Boolean { - return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || - activity.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED - } - - override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { - when(call?.method){ - "checkAndRequestPermission" -> { - checkAndRequestPermission(result) - } + when(call.method){ "flipCamera" -> { flipCamera() } @@ -174,33 +147,6 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : } } - private fun checkAndRequestPermission(result: MethodChannel.Result?) { - if (cameraPermissionContinuation != null) { - result?.error("cameraPermission", "Camera permission request ongoing", null); - } - - cameraPermissionContinuation = Runnable { - cameraPermissionContinuation = null - if (!hasCameraPermission()) { - result?.error( - "cameraPermission", "MediaRecorderCamera permission not granted", null) - return@Runnable - } - } - requestingPermission = false - if (hasCameraPermission()) { - cameraPermissionContinuation?.run() - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestingPermission = true - registrar - .activity() - .requestPermissions( - arrayOf(Manifest.permission.CAMERA), - CAMERA_REQUEST_ID) - } - } - } } diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt index f9be661..a797084 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt @@ -1,17 +1,17 @@ package net.touchcapture.qr.flutterqr import android.content.Context -import io.flutter.plugin.common.PluginRegistry +import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory -class QRViewFactory(private val registrar: PluginRegistry.Registrar) : +class QRViewFactory(private val messenger: BinaryMessenger) : PlatformViewFactory(StandardMessageCodec.INSTANCE) { override fun create(context: Context, id: Int, obj: Any?): PlatformView { - return QRView(registrar,id) + return QRView(messenger, id, context) } } \ No newline at end of file diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt new file mode 100644 index 0000000..5957725 --- /dev/null +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt @@ -0,0 +1,10 @@ +package net.touchcapture.qr.flutterqr + +import android.app.Activity +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding + + +object Shared { + var activityPluginBinding: ActivityPluginBinding? = null + var activity: Activity? = null +} \ No newline at end of file From 5d69344dccefe2b2476de2af502e5d4b136a2250 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Mon, 14 Dec 2020 15:56:13 +0100 Subject: [PATCH 14/20] Added support for embedding V1. --- .../qr/flutterqr/FlutterQrPlugin.kt | 52 ++++++++----------- .../net/touchcapture/qr/flutterqr/Shared.kt | 1 - 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt index 035431e..ca59f08 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt @@ -1,61 +1,55 @@ package net.touchcapture.qr.flutterqr import android.Manifest -import android.app.Activity -import android.content.Context import android.content.pm.PackageManager import android.os.Build import androidx.annotation.NonNull import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.PluginRegistry +import io.flutter.plugin.platform.PlatformViewRegistry class FlutterQrPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { var cameraPermissionContinuation: Runnable? = null var requestingPermission = false -// private var activity: Activity? = null -// /** Plugin registration embedding v1 */ -// companion object { -// @JvmStatic -// fun registerWith(registrar: Registrar) { -// FlutterQrPlugin().onAttachedToEngine(registrar) -// } -// } + /** Plugin registration embedding v1 */ + companion object { + @JvmStatic + fun registerWith(registrar: PluginRegistry.Registrar) { + FlutterQrPlugin().onAttachedToV1(registrar) + } + } + + private fun onAttachedToV1(registrar: PluginRegistry.Registrar) { + Shared.activity = registrar.activity() + registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) + checkAndRequestPermission(null) + onAttachedToEngines(registrar.platformViewRegistry(), registrar.messenger()) + } /** Plugin registration embedding v2 */ override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - onAttachedToEngines(flutterPluginBinding) + onAttachedToEngines(flutterPluginBinding.platformViewRegistry, flutterPluginBinding.binaryMessenger) } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { } - // TODO: Fix v1 embedding for Flutter < 1.12 support /** Plugin start for both embedding v1 & v2 */ - private fun onAttachedToEngines(binding: FlutterPlugin.FlutterPluginBinding) { - binding.platformViewRegistry + private fun onAttachedToEngines(platformViewRegistry: PlatformViewRegistry, messenger: BinaryMessenger) { + platformViewRegistry .registerViewFactory( - "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(binding.binaryMessenger)) + "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(messenger)) } -// private fun onAttachedToEngine(registrar: Registrar) { -// activity = registrar.activity() -// registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) -// checkAndRequestPermission(null) -// registrar -// .platformViewRegistry() -// .registerViewFactory( -// "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(registrar)) -// } - override fun onMethodCall(call: MethodCall, result: Result) { when (call.method) { "checkAndRequestPermission" -> checkAndRequestPermission(result) @@ -63,24 +57,20 @@ class FlutterQrPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { } override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) { - Shared.activityPluginBinding = activityPluginBinding Shared.activity = activityPluginBinding.activity activityPluginBinding.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) checkAndRequestPermission(null) } override fun onDetachedFromActivityForConfigChanges() { - Shared.activityPluginBinding = null Shared.activity = null } override fun onReattachedToActivityForConfigChanges(activityPluginBinding: ActivityPluginBinding) { - Shared.activityPluginBinding = activityPluginBinding Shared.activity = activityPluginBinding.activity } override fun onDetachedFromActivity() { - Shared.activityPluginBinding = null Shared.activity = null } @@ -101,7 +91,7 @@ class FlutterQrPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { private fun checkAndRequestPermission(result: Result?) { if (cameraPermissionContinuation != null) { - result?.error("cameraPermission", "Camera permission request ongoing", null); + result?.error("cameraPermission", "Camera permission request ongoing", null) } cameraPermissionContinuation = Runnable { diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt index 5957725..7823e01 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt @@ -5,6 +5,5 @@ import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding object Shared { - var activityPluginBinding: ActivityPluginBinding? = null var activity: Activity? = null } \ No newline at end of file From 352bd1ed9e6a0d77543b97f5f3d3f3c1be783fab Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Tue, 15 Dec 2020 09:43:17 +0100 Subject: [PATCH 15/20] Fixed rotation on iOS. --- example/lib/main.dart | 39 ++++++++++++++++++++++-------------- ios/Classes/QRView.swift | 13 +++++++++--- lib/src/qr_code_scanner.dart | 14 ++++++++----- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index cb5701c..8d957bd 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -29,21 +29,7 @@ class _QRViewExampleState extends State { return Scaffold( body: Column( children: [ - Expanded( - flex: 4, - child: QRView( - key: qrKey, - onQRViewCreated: _onQRViewCreated, - overlay: QrScannerOverlayShape( - borderColor: Colors.red, - borderRadius: 10, - borderLength: 30, - borderWidth: 10, - cutOutSize: 300, - cutOutBottomOffset: 24, - ), - ), - ), + Expanded(flex: 4, child: _buildQrView(context)), Expanded( flex: 1, child: FittedBox( @@ -141,6 +127,29 @@ class _QRViewExampleState extends State { return backCamera == current; } + Widget _buildQrView(BuildContext context) { + // To ensure the Scanner view is properly sizes after rotation + // we need to listen for Flutter SizeChanged notifiation and update controller + return NotificationListener( + onNotification: (notification) { + Future.microtask(() => controller?.updateDimensions(qrKey)); + return false; + }, + child: SizeChangedLayoutNotifier( + key: const Key('qr-size-notifier'), + child: QRView( + key: qrKey, + onQRViewCreated: _onQRViewCreated, + overlay: QrScannerOverlayShape( + borderColor: Colors.red, + borderRadius: 10, + borderLength: 30, + borderWidth: 10, + cutOutSize: 300, + ), + ))); + } + void _onQRViewCreated(QRViewController controller) { this.controller = controller; controller.scannedDataStream.listen((scanData) { diff --git a/ios/Classes/QRView.swift b/ios/Classes/QRView.swift index 376cec1..55426f0 100644 --- a/ios/Classes/QRView.swift +++ b/ios/Classes/QRView.swift @@ -63,9 +63,16 @@ public class QRView:NSObject,FlutterPlatformView { } func setDimensions(width: Double, height: Double) -> Void { - previewView.frame = CGRect(x: 0, y: 0, width: width, height: height) - scanner = MTBBarcodeScanner(previewView: previewView) - MTBBarcodeScanner.requestCameraPermission(success: isCameraAvailable) + previewView.frame = CGRect(x: 0, y: 0, width: width, height: height) + + if let sc: MTBBarcodeScanner = scanner { + if let previewLayer = sc.previewLayer { + previewLayer.frame = previewView.bounds; + } + } else { + scanner = MTBBarcodeScanner(previewView: previewView) + MTBBarcodeScanner.requestCameraPermission(success: isCameraAvailable) + } } func flipCamera(){ diff --git a/lib/src/qr_code_scanner.dart b/lib/src/qr_code_scanner.dart index 8bedf5e..70a96a4 100644 --- a/lib/src/qr_code_scanner.dart +++ b/lib/src/qr_code_scanner.dart @@ -100,11 +100,7 @@ class _CreationParams { class QRViewController { QRViewController._(int id, GlobalKey qrKey) : _channel = MethodChannel('net.touchcapture.qr.flutterqr/qrview_$id') { - if (defaultTargetPlatform == TargetPlatform.iOS) { - final RenderBox renderBox = qrKey.currentContext.findRenderObject(); - _channel.invokeMethod('setDimensions', - {'width': renderBox.size.width, 'height': renderBox.size.height}); - } + updateDimensions(qrKey); _channel.setMethodCallHandler( (call) async { switch (call.method) { @@ -145,4 +141,12 @@ class QRViewController { void dispose() { _scanUpdateController.close(); } + + void updateDimensions(GlobalKey key) { + if (defaultTargetPlatform == TargetPlatform.iOS) { + final RenderBox renderBox = key.currentContext.findRenderObject(); + _channel.invokeMethod('setDimensions', + {'width': renderBox.size.width, 'height': renderBox.size.height}); + } + } } From 6d8b7799f9399e5b78aeb426531fc1300137eaa4 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Tue, 15 Dec 2020 09:54:58 +0100 Subject: [PATCH 16/20] Updated Flutter min sdk of example to match plugin. Updated README.md --- example/README.md | 38 ++++++++++++++++++++++++-------------- example/lib/main.dart | 2 +- example/pubspec.yaml | 2 +- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/example/README.md b/example/README.md index d9a96cd..4fc9d62 100644 --- a/example/README.md +++ b/example/README.md @@ -52,20 +52,7 @@ class _QRViewExampleState extends State { return Scaffold( body: Column( children: [ - Expanded( - flex: 4, - child: QRView( - key: qrKey, - onQRViewCreated: _onQRViewCreated, - overlay: QrScannerOverlayShape( - borderColor: Colors.red, - borderRadius: 10, - borderLength: 30, - borderWidth: 10, - cutOutSize: 300, - ), - ), - ), + Expanded(flex: 4, child: _buildQrView(context)), Expanded( flex: 1, child: FittedBox( @@ -163,6 +150,29 @@ class _QRViewExampleState extends State { return backCamera == current; } + Widget _buildQrView(BuildContext context) { + // To ensure the Scanner view is properly sizes after rotation + // we need to listen for Flutter SizeChanged notification and update controller + return NotificationListener( + onNotification: (notification) { + Future.microtask(() => controller?.updateDimensions(qrKey)); + return false; + }, + child: SizeChangedLayoutNotifier( + key: const Key('qr-size-notifier'), + child: QRView( + key: qrKey, + onQRViewCreated: _onQRViewCreated, + overlay: QrScannerOverlayShape( + borderColor: Colors.red, + borderRadius: 10, + borderLength: 30, + borderWidth: 10, + cutOutSize: 300, + ), + ))); + } + void _onQRViewCreated(QRViewController controller) { this.controller = controller; controller.scannedDataStream.listen((scanData) { diff --git a/example/lib/main.dart b/example/lib/main.dart index 8d957bd..4facbeb 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -129,7 +129,7 @@ class _QRViewExampleState extends State { Widget _buildQrView(BuildContext context) { // To ensure the Scanner view is properly sizes after rotation - // we need to listen for Flutter SizeChanged notifiation and update controller + // we need to listen for Flutter SizeChanged notification and update controller return NotificationListener( onNotification: (notification) { Future.microtask(() => controller?.updateDimensions(qrKey)); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 02dae87..6df5ea4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the flutter_qr plugin. publish_to: 'none' environment: - sdk: ">=2.0.0-dev.68.0 <3.0.0" + sdk: ">=2.3.0 <3.0.0" dependencies: flutter: From a1c7dc6544155d96089da5408fc4448f939321a3 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Tue, 15 Dec 2020 09:58:33 +0100 Subject: [PATCH 17/20] Updated pedantic. --- analysis_options.yaml | 3 ++- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index e2dba57..180afc8 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,5 @@ -include: package:pedantic/analysis_options.1.9.0.yaml +include: package:pedantic/analysis_options.yaml + linter: rules: - always_put_required_named_parameters_first diff --git a/pubspec.yaml b/pubspec.yaml index e0eb626..a9202d6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: sdk: flutter dev_dependencies: - pedantic: ^1.9.0 + pedantic: ^1.9.2 flutter: plugin: From 675be0dceecca180b59ee66c85fe8c1059a378c8 Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Tue, 15 Dec 2020 10:19:57 +0100 Subject: [PATCH 18/20] Update README.md --- README.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ecbe13c..6050aed 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,20 @@ class _QRViewExampleState extends State { children: [ Expanded( flex: 5, - child: QRView( - key: qrKey, - onQRViewCreated: _onQRViewCreated, + // To ensure the Scanner view is properly sizes after rotation + // we need to listen for Flutter SizeChanged notification and update controller + child: NotificationListener( + onNotification: (notification) { + Future.microtask(() => controller?.updateDimensions(qrKey)); + return false; + }, + child: SizeChangedLayoutNotifier( + key: const Key('qr-size-notifier'), + child: QRView( + key: qrKey, + onQRViewCreated: _onQRViewCreated, + ), + ), ), ), Expanded( @@ -129,7 +140,7 @@ controller.resumeCamera(); # SDK -Requires at least SDK 24 (Android 7.0). +Requires at least SDK 21 (Android 5.0). # TODOs * iOS Native embedding is written to match what is supported in the framework as of the date of publication of this package. It needs to be improved as the framework support improves. From ac647cddfb1254f37d3bdc018fb0ffa19f2d028c Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Tue, 15 Dec 2020 10:26:46 +0100 Subject: [PATCH 19/20] Release 0.1.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad7b9bc..1585540 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.1.0 +* Changed Android minSDKversion from 24 to 21 (#170) +* Fix preview size after iPad rotation (#125) +* Implemented Android Embedding V2 (#132) +* Added cutout bottom offset (#115) +* Fix Android ActivityLifecycleCallbacks (#166) +* Fix some other small bugs + ## 0.0.14 * Fix disposing camera on iOS 14 (#113) From 78c9ebf78fdd3a163ea6cd60364e9f82ab3aaf8b Mon Sep 17 00:00:00 2001 From: Julian Steenbakker Date: Tue, 15 Dec 2020 10:29:00 +0100 Subject: [PATCH 20/20] Release 0.1.0 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a9202d6..0cbfd2c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: qr_code_scanner description: QR code scanner that can be embedded inside flutter. It uses zxing in Android and MTBBarcode scanner in iOS. -version: 0.0.14 +version: 0.1.0 author: Julius Canute homepage: https://juliuscanute.com repository: https://github.com/juliuscanute/qr_code_scanner