From 5e93c2ecc920f2c7d262de3a6f7798ae67256182 Mon Sep 17 00:00:00 2001 From: MatveevYasha Date: Thu, 1 Aug 2024 16:43:36 +0200 Subject: [PATCH 1/2] Add format to code --- CHANGELOG.md | 4 -- android/build.gradle | 3 +- .../qr_mobile_vision/BarcodeFormats.java | 7 +- .../qr_mobile_vision/Heartbeat.java | 3 +- .../qr_mobile_vision/QrDetector.java | 2 +- .../QrMobileVisionPlugin.java | 27 ++++--- .../qr_mobile_vision/QrReaderCallbacks.java | 2 +- example/ios/Podfile.lock | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 15 ++-- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- example/ios/Runner/Info.plist | 12 ++-- example/lib/main.dart | 5 +- example/pubspec.lock | 70 ++++++++++++------- ios/Classes/QrMobileVisionPlugin.swift | 4 +- ios/Classes/QrReader.swift | 42 +++++++++-- lib/qr_mobile_vision.dart | 3 +- lib/src/barcode_formats.dart | 10 +++ lib/src/qr_camera.dart | 2 +- lib/src/qr_channel_reader.dart | 12 ++-- lib/src/qr_mobile_vision_method_channel.dart | 2 +- .../qr_mobile_vision_platform_interface.dart | 3 +- pubspec.yaml | 2 +- test/qr_mobile_vision_test.dart | 5 +- 23 files changed, 149 insertions(+), 90 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8324f4c..0797669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,3 @@ -## [5.0.1] - Feb 14, 2024 -* Fix null pointer exception on disconnect for android -* Fix deprecated Handler - ## [5.0.0] - January 26, 2024 * Bump version to match what is supported by MLKit library. No more Camera1 API needed! diff --git a/android/build.gradle b/android/build.gradle index 703e4b7..9f38da0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -26,8 +26,7 @@ android { namespace 'com.github.rmtmckenzie.qr_mobile_vision' } - // update this when flutter default changes - compileSdk 33 + compileSdk 34 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/BarcodeFormats.java b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/BarcodeFormats.java index 56c7bc4..11ee5e1 100644 --- a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/BarcodeFormats.java +++ b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/BarcodeFormats.java @@ -96,5 +96,10 @@ static BarcodeScannerOptions optionsFromStringList(List strings) { .setBarcodeFormats(first, rest).build(); } - + public static String getEnumByString(int code){ + for(BarcodeFormats e : BarcodeFormats.values()){ + if(e.intValue==(code)) return e.name(); + } + return ""; + } } diff --git a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java index e0360b7..4e0b190 100644 --- a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java +++ b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java @@ -1,11 +1,10 @@ package com.github.rmtmckenzie.qr_mobile_vision; import android.os.Handler; -import android.os.Looper; public class Heartbeat { - private final Handler handler = new Handler(Looper.getMainLooper()); + private final Handler handler = new Handler(); private final Runnable runner; private final int timeout; diff --git a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrDetector.java b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrDetector.java index 7d085f5..044c5cd 100644 --- a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrDetector.java +++ b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrDetector.java @@ -86,7 +86,7 @@ private void processFrame(Frame frame) { @Override public void onSuccess(List firebaseVisionBarcodes) { for (Barcode barcode : firebaseVisionBarcodes) { - communicator.qrRead(barcode.getRawValue()); + communicator.qrRead(barcode.getRawValue(),BarcodeFormats.getEnumByString(barcode.getFormat())); } } diff --git a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java index 220e635..053023f 100644 --- a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java +++ b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,8 +35,7 @@ public class QrMobileVisionPlugin implements FlutterPlugin, MethodCallHandler, A private static final String TAG = "cgr.qrmv.QrMobVisPlugin"; private static final int REQUEST_PERMISSION = 1; private MethodChannel channel; - private ActivityPluginBinding activityBinding; - + private Activity activity; private TextureRegistry textures; private Integer lastHeartbeatTimeout; private boolean waitingForPermissionResult; @@ -47,6 +47,8 @@ public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { textures = binding.getTextureRegistry(); channel = new MethodChannel(binding.getBinaryMessenger(), "qr_mobile_vision"); channel.setMethodCallHandler(this); + Application app = (Application) binding.getApplicationContext(); + } @Override @@ -57,7 +59,7 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { binding.addRequestPermissionsResultListener(this); - activityBinding = binding; + activity = binding.getActivity(); } @Override @@ -72,7 +74,9 @@ public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBindin @Override public void onDetachedFromActivity() { - activityBinding = null; + activity = null; + channel.setMethodCallHandler(null); + channel = null; } @Override @@ -115,8 +119,6 @@ public void onMethodCall(MethodCall methodCall, @NonNull Result result) { result.error("QRREADER_ERROR", "noPermission", null); } else if (readingInstance != null) { result.error("ALREADY_RUNNING", "Start cannot be called when already running", ""); - } else if (activityBinding == null) { - result.error("DETACHED", "Cannot start when not attached to activity", null); } else { lastHeartbeatTimeout = methodCall.argument("heartbeatTimeout"); Integer targetWidth = methodCall.argument("targetWidth"); @@ -132,7 +134,7 @@ public void onMethodCall(MethodCall methodCall, @NonNull Result result) { BarcodeScannerOptions options = BarcodeFormats.optionsFromStringList(formatStrings); TextureRegistry.SurfaceTextureEntry textureEntry = textures.createSurfaceTexture(); - QrReader reader = new QrReader(targetWidth, targetHeight, activityBinding.getActivity(), options, + QrReader reader = new QrReader(targetWidth, targetHeight, activity, options, this, this, textureEntry.surfaceTexture()); readingInstance = new ReadingInstance(reader, textureEntry, result); @@ -149,11 +151,8 @@ public void onMethodCall(MethodCall methodCall, @NonNull Result result) { result.error(e.reason().name(), "Error starting camera for reason: " + e.reason().name(), null); } catch (NoPermissionException e) { waitingForPermissionResult = true; - ActivityCompat.requestPermissions( - activityBinding.getActivity(), - new String[]{Manifest.permission.CAMERA}, - REQUEST_PERMISSION - ); + ActivityCompat.requestPermissions(activity, + new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION); } } break; @@ -185,8 +184,8 @@ public void onMethodCall(MethodCall methodCall, @NonNull Result result) { } @Override - public void qrRead(String data) { - channel.invokeMethod("qrRead", data); + public void qrRead(String data, String format) { + channel.invokeMethod("qrRead", new ArrayList(Arrays.asList(data, format))); } @Override diff --git a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrReaderCallbacks.java b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrReaderCallbacks.java index 1396822..1c112c1 100644 --- a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrReaderCallbacks.java +++ b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrReaderCallbacks.java @@ -1,5 +1,5 @@ package com.github.rmtmckenzie.qr_mobile_vision; public interface QrReaderCallbacks { - void qrRead(String data); + void qrRead(String data, String format); } diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 86063bb..ffaf7bd 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -117,6 +117,6 @@ SPEC CHECKSUMS: PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 qr_mobile_vision: de2dbc8122cf2e0d15af3d777f6969e2d65876f6 -PODFILE CHECKSUM: 7be2f5f74864d463a8ad433546ed1de7e0f29aef +PODFILE CHECKSUM: 28dee045aca6364a379bd7a0225d71bcda155772 COCOAPODS: 1.14.3 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 2d0fae4..e4b5396 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -161,7 +161,6 @@ 227482435EAD2F248AC1F228 /* Pods-RunnerTests.release.xcconfig */, 1615697041F5FFD155A18799 /* Pods-RunnerTests.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -216,7 +215,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1510; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { 331C8080294A63A400263BE5 = { @@ -471,14 +470,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 38675L3NKC; + DEVELOPMENT_TEAM = 3D72B5DZPX; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.rmtmckenzie.qrMobileVisionExample; + PRODUCT_BUNDLE_IDENTIFIER = com.example.qrMobileVisionExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -654,14 +653,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 38675L3NKC; + DEVELOPMENT_TEAM = 3D72B5DZPX; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.rmtmckenzie.qrMobileVisionExample; + PRODUCT_BUNDLE_IDENTIFIER = com.example.qrMobileVisionExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -677,14 +676,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 38675L3NKC; + DEVELOPMENT_TEAM = 3D72B5DZPX; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.github.rmtmckenzie.qrMobileVisionExample; + PRODUCT_BUNDLE_IDENTIFIER = com.example.qrMobileVisionExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8e3ca5d..87131a0 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -24,12 +26,14 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + NSCameraUsageDescription + Used to scan QR codes + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main - NSCameraUsageDescription - Used to scan QR codes UISupportedInterfaceOrientations UIInterfaceOrientationPortrait @@ -43,9 +47,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/example/lib/main.dart b/example/lib/main.dart index e6b5516..1c37cf7 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -30,6 +30,7 @@ class MyApp extends StatefulWidget { class MyAppState extends State { String? qr; + String? format; bool camState = false; bool dirState = false; @@ -72,9 +73,10 @@ class MyAppState extends State { style: const TextStyle(color: Colors.red), ), cameraDirection: dirState ? CameraDirection.FRONT : CameraDirection.BACK, - qrCodeCallback: (code) { + qrCodeCallback: (code, format) { setState(() { qr = code; + this.format = format.toString(); }); }, child: Container( @@ -92,6 +94,7 @@ class MyAppState extends State { ) : const Center(child: Text("Camera inactive"))), Text("QRCODE: $qr"), + Text("FORMAT: $format"), ], ), ), diff --git a/example/pubspec.lock b/example/pubspec.lock index 171f569..f689217 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" flutter: dependency: "direct main" description: flutter @@ -119,6 +119,30 @@ packages: description: flutter source: sdk version: "0.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -131,26 +155,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" native_device_orientation: dependency: transitive description: @@ -163,18 +187,18 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" platform: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: @@ -187,17 +211,17 @@ packages: dependency: transitive description: name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "5.0.2" qr_mobile_vision: dependency: "direct main" description: path: ".." relative: true source: path - version: "5.0.1" + version: "5.0.0" sky_engine: dependency: transitive description: flutter @@ -271,26 +295,18 @@ packages: dependency: transitive description: name: vm_service - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 - url: "https://pub.dev" - source: hosted - version: "11.10.0" - web: - dependency: transitive - description: - name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "13.0.0" webdriver: dependency: transitive description: name: webdriver - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" win32: dependency: transitive description: diff --git a/ios/Classes/QrMobileVisionPlugin.swift b/ios/Classes/QrMobileVisionPlugin.swift index d512ea7..9002e9a 100644 --- a/ios/Classes/QrMobileVisionPlugin.swift +++ b/ios/Classes/QrMobileVisionPlugin.swift @@ -52,8 +52,8 @@ public class QrMobileVisionPlugin: NSObject, FlutterPlugin { targetHeight: targetHeight, direction: cameraDirection, textureRegistry: textureRegistry, - options: options) { [unowned self] qr in - self.channel.invokeMethod("qrRead", arguments: qr) + options: options) { [unowned self] qr,format in + self.channel.invokeMethod("qrRead", arguments: [qr,format]) } reader!.start(); diff --git a/ios/Classes/QrReader.swift b/ios/Classes/QrReader.swift index dcf2389..a57b454 100644 --- a/ios/Classes/QrReader.swift +++ b/ios/Classes/QrReader.swift @@ -132,11 +132,11 @@ class QrReader: NSObject { var textureId: Int64! var pixelBuffer : CVPixelBuffer? let barcodeDetector: BarcodeScanner - let qrCallback: (_:String) -> Void + let qrCallback: (_:String, _:String) -> Void - init(targetWidth: Int, targetHeight: Int, direction: QrCameraDirection, textureRegistry: FlutterTextureRegistry, options: BarcodeScannerOptions, qrCallback: @escaping (_:String) -> Void) throws { + init(targetWidth: Int, targetHeight: Int, direction: QrCameraDirection, textureRegistry: FlutterTextureRegistry, options: BarcodeScannerOptions, qrCallback: @escaping (_:String,_:String) -> Void) throws { self.targetWidth = targetWidth self.targetHeight = targetHeight self.textureRegistry = textureRegistry @@ -263,7 +263,7 @@ extension QrReader: AVCaptureVideoDataOutputSampleBufferDelegate { for feature in features { if let value = feature.rawValue { - self.qrCallback(value) + self.qrCallback(value,self.getFormatName(format: feature.format)) } } } @@ -291,5 +291,39 @@ extension QrReader: AVCaptureVideoDataOutputSampleBufferDelegate { return imageOrientation(deviceOrientation: defaultOrientation, defaultOrientation: .portrait) } } - + + func getFormatName (format: BarcodeFormat) -> String { + switch format { + case .all: + return "ALL_FORMATS" + case .aztec: + return "AZTEC" + case .code128: + return "CODE_128" + case .code39: + return "CODE_39" + case .code93: + return "CODE_93" + case .codaBar: + return "CODABAR" + case .dataMatrix: + return "DATA_MATRIX" + case .EAN13: + return "EAN_13" + case .EAN8: + return "EAN_8" + case .ITF: + return "ITF" + case .PDF417: + return "PDF417" + case .qrCode: + return "QR_CODE" + case .UPCA: + return "UPC_A" + case .UPCE: + return "UPC_E" + default: + return "ALL_FORMATS" + } + } } diff --git a/lib/qr_mobile_vision.dart b/lib/qr_mobile_vision.dart index 729739e..40eabf7 100644 --- a/lib/qr_mobile_vision.dart +++ b/lib/qr_mobile_vision.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:qr_mobile_vision/src/barcode_formats.dart'; import 'package:qr_mobile_vision/src/camera_direction.dart'; import 'package:qr_mobile_vision/src/preview_details.dart'; @@ -15,7 +14,7 @@ class QrMobileVision { static Future start({ required int width, required int height, - required ValueChanged qrCodeHandler, + required void Function(String?, BarcodeFormats?) qrCodeHandler, CameraDirection cameraDirection = CameraDirection.BACK, List? formats = defaultBarcodeFormats, }) async { diff --git a/lib/src/barcode_formats.dart b/lib/src/barcode_formats.dart index 0debb78..4cd6712 100644 --- a/lib/src/barcode_formats.dart +++ b/lib/src/barcode_formats.dart @@ -17,6 +17,16 @@ enum BarcodeFormats { UPC_E, } +extension BarcodeFormat on BarcodeFormats { + static BarcodeFormats fromString(String? value) { + return BarcodeFormats.values.firstWhere( + (e) => + e.toString().toUpperCase() == 'BarcodeFormats.$value'.toUpperCase(), + orElse: () => BarcodeFormats.ALL_FORMATS, + ); + } +} + const defaultBarcodeFormats = [ BarcodeFormats.ALL_FORMATS, ]; diff --git a/lib/src/qr_camera.dart b/lib/src/qr_camera.dart index c46eba1..7482bf6 100644 --- a/lib/src/qr_camera.dart +++ b/lib/src/qr_camera.dart @@ -30,7 +30,7 @@ class QrCamera extends StatefulWidget { onError = onError ?? _defaultOnError; final BoxFit fit; - final ValueChanged qrCodeCallback; + final void Function(String?, BarcodeFormats?) qrCodeCallback; final Widget? child; final WidgetBuilder notStartedBuilder; final WidgetBuilder offscreenBuilder; diff --git a/lib/src/qr_channel_reader.dart b/lib/src/qr_channel_reader.dart index 403388a..29d497b 100644 --- a/lib/src/qr_channel_reader.dart +++ b/lib/src/qr_channel_reader.dart @@ -1,5 +1,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:qr_mobile_vision/qr_camera.dart'; class QrChannelReader { QrChannelReader(this.channel) { @@ -7,8 +8,9 @@ class QrChannelReader { switch (call.method) { case 'qrRead': if (qrCodeHandler != null) { - assert(call.arguments is String); - qrCodeHandler!(call.arguments); + assert(call.arguments is List); + assert((call.arguments as List).length ==2); + qrCodeHandler!(call.arguments[0],BarcodeFormat.fromString(call.arguments[1]) ); } break; default: @@ -18,10 +20,10 @@ class QrChannelReader { }); } - void setQrCodeHandler(ValueChanged? qrch) { - qrCodeHandler = qrch; + void setQrCodeHandler(void Function(String?, BarcodeFormats?)? handler) { + qrCodeHandler = handler; } MethodChannel channel; - ValueChanged? qrCodeHandler; + void Function(String?, BarcodeFormats?)? qrCodeHandler; } diff --git a/lib/src/qr_mobile_vision_method_channel.dart b/lib/src/qr_mobile_vision_method_channel.dart index 0a6ecd4..a608067 100644 --- a/lib/src/qr_mobile_vision_method_channel.dart +++ b/lib/src/qr_mobile_vision_method_channel.dart @@ -22,7 +22,7 @@ class MethodChannelQrMobileVision extends QrMobileVisionPlatform { Future start({ required int width, required int height, - required ValueChanged qrCodeHandler, + required void Function(String?, BarcodeFormats?) qrCodeHandler, CameraDirection cameraDirection = CameraDirection.BACK, List? formats = defaultBarcodeFormats, }) async { diff --git a/lib/src/qr_mobile_vision_platform_interface.dart b/lib/src/qr_mobile_vision_platform_interface.dart index edbf3c3..0c01122 100644 --- a/lib/src/qr_mobile_vision_platform_interface.dart +++ b/lib/src/qr_mobile_vision_platform_interface.dart @@ -1,4 +1,3 @@ -import 'package:flutter/widgets.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:qr_mobile_vision/src/barcode_formats.dart'; import 'package:qr_mobile_vision/src/camera_direction.dart'; @@ -29,7 +28,7 @@ abstract class QrMobileVisionPlatform extends PlatformInterface { Future start({ required int width, required int height, - required ValueChanged qrCodeHandler, + required void Function(String?, BarcodeFormats?) qrCodeHandler, CameraDirection cameraDirection = CameraDirection.BACK, List? formats = defaultBarcodeFormats, }); diff --git a/pubspec.yaml b/pubspec.yaml index 7e941bf..0cac97b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: qr_mobile_vision description: "Plugin for reading QR codes using Firebase's Mobile Vision API." -version: 5.0.1 +version: 5.0.0 homepage: https://github.com/rmtmckenzie/flutter_qr_mobile_vision environment: diff --git a/test/qr_mobile_vision_test.dart b/test/qr_mobile_vision_test.dart index 395b246..a017595 100644 --- a/test/qr_mobile_vision_test.dart +++ b/test/qr_mobile_vision_test.dart @@ -1,4 +1,3 @@ -import 'package:flutter/src/foundation/basic_types.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:qr_mobile_vision/qr_mobile_vision.dart'; @@ -18,7 +17,7 @@ class MockQrMobileVisionPlatform with MockPlatformInterfaceMixin implements QrMo Future start({ required int width, required int height, - required ValueChanged qrCodeHandler, + required void Function(String?, BarcodeFormats?) qrCodeHandler, CameraDirection cameraDirection = CameraDirection.BACK, List? formats = defaultBarcodeFormats, }) async { @@ -62,7 +61,7 @@ void main() { }); test('start', () async { - handler(String? code) => print(code); + handler(String? code, BarcodeFormats? format) => print(code); final details = await QrMobileVision.start( width: 100, height: 100, From 0f7079961be451c7ce4e4848b18648a0583363d7 Mon Sep 17 00:00:00 2001 From: MatveevYasha Date: Thu, 1 Aug 2024 17:01:04 +0200 Subject: [PATCH 2/2] Revert 5.0.1 ver changes --- CHANGELOG.md | 4 ++++ android/build.gradle | 3 ++- .../qr_mobile_vision/Heartbeat.java | 3 ++- .../QrMobileVisionPlugin.java | 21 ++++++++++--------- pubspec.yaml | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0797669..8324f4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.0.1] - Feb 14, 2024 +* Fix null pointer exception on disconnect for android +* Fix deprecated Handler + ## [5.0.0] - January 26, 2024 * Bump version to match what is supported by MLKit library. No more Camera1 API needed! diff --git a/android/build.gradle b/android/build.gradle index 9f38da0..703e4b7 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -26,7 +26,8 @@ android { namespace 'com.github.rmtmckenzie.qr_mobile_vision' } - compileSdk 34 + // update this when flutter default changes + compileSdk 33 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 diff --git a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java index 4e0b190..e0360b7 100644 --- a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java +++ b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/Heartbeat.java @@ -1,10 +1,11 @@ package com.github.rmtmckenzie.qr_mobile_vision; import android.os.Handler; +import android.os.Looper; public class Heartbeat { - private final Handler handler = new Handler(); + private final Handler handler = new Handler(Looper.getMainLooper()); private final Runnable runner; private final int timeout; diff --git a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java index 053023f..dff9e56 100644 --- a/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java +++ b/android/src/main/java/com/github/rmtmckenzie/qr_mobile_vision/QrMobileVisionPlugin.java @@ -35,7 +35,7 @@ public class QrMobileVisionPlugin implements FlutterPlugin, MethodCallHandler, A private static final String TAG = "cgr.qrmv.QrMobVisPlugin"; private static final int REQUEST_PERMISSION = 1; private MethodChannel channel; - private Activity activity; + private ActivityPluginBinding activityBinding; private TextureRegistry textures; private Integer lastHeartbeatTimeout; private boolean waitingForPermissionResult; @@ -47,8 +47,6 @@ public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { textures = binding.getTextureRegistry(); channel = new MethodChannel(binding.getBinaryMessenger(), "qr_mobile_vision"); channel.setMethodCallHandler(this); - Application app = (Application) binding.getApplicationContext(); - } @Override @@ -59,7 +57,7 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { binding.addRequestPermissionsResultListener(this); - activity = binding.getActivity(); + activityBinding = binding; } @Override @@ -74,9 +72,7 @@ public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBindin @Override public void onDetachedFromActivity() { - activity = null; - channel.setMethodCallHandler(null); - channel = null; + activityBinding = null; } @Override @@ -119,6 +115,8 @@ public void onMethodCall(MethodCall methodCall, @NonNull Result result) { result.error("QRREADER_ERROR", "noPermission", null); } else if (readingInstance != null) { result.error("ALREADY_RUNNING", "Start cannot be called when already running", ""); + } else if (activityBinding == null) { + result.error("DETACHED", "Cannot start when not attached to activity", null); } else { lastHeartbeatTimeout = methodCall.argument("heartbeatTimeout"); Integer targetWidth = methodCall.argument("targetWidth"); @@ -134,7 +132,7 @@ public void onMethodCall(MethodCall methodCall, @NonNull Result result) { BarcodeScannerOptions options = BarcodeFormats.optionsFromStringList(formatStrings); TextureRegistry.SurfaceTextureEntry textureEntry = textures.createSurfaceTexture(); - QrReader reader = new QrReader(targetWidth, targetHeight, activity, options, + QrReader reader = new QrReader(targetWidth, targetHeight, activityBinding.getActivity(), options, this, this, textureEntry.surfaceTexture()); readingInstance = new ReadingInstance(reader, textureEntry, result); @@ -151,8 +149,11 @@ public void onMethodCall(MethodCall methodCall, @NonNull Result result) { result.error(e.reason().name(), "Error starting camera for reason: " + e.reason().name(), null); } catch (NoPermissionException e) { waitingForPermissionResult = true; - ActivityCompat.requestPermissions(activity, - new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION); + ActivityCompat.requestPermissions( + activityBinding.getActivity(), + new String[]{Manifest.permission.CAMERA}, + REQUEST_PERMISSION + ); } } break; diff --git a/pubspec.yaml b/pubspec.yaml index 0cac97b..7e941bf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: qr_mobile_vision description: "Plugin for reading QR codes using Firebase's Mobile Vision API." -version: 5.0.0 +version: 5.0.1 homepage: https://github.com/rmtmckenzie/flutter_qr_mobile_vision environment: