Julian Steenbakker
Committed by GitHub

Merge branch 'master' into dependabot/github_actions/actions/setup-java-3.5.1

@@ -16,7 +16,7 @@ jobs: @@ -16,7 +16,7 @@ jobs:
16 with: 16 with:
17 java-version: 11 17 java-version: 11
18 distribution: temurin 18 distribution: temurin
19 - - uses: subosito/flutter-action@v2.6.1 19 + - uses: subosito/flutter-action@v2.7.1
20 with: 20 with:
21 cache: true 21 cache: true
22 - name: Version 22 - name: Version
@@ -33,7 +33,7 @@ jobs: @@ -33,7 +33,7 @@ jobs:
33 with: 33 with:
34 java-version: 11 34 java-version: 11
35 distribution: temurin 35 distribution: temurin
36 - - uses: subosito/flutter-action@v2.6.1 36 + - uses: subosito/flutter-action@v2.7.1
37 with: 37 with:
38 cache: true 38 cache: true
39 - name: Format 39 - name: Format
@@ -9,7 +9,7 @@ buildscript { @@ -9,7 +9,7 @@ buildscript {
9 } 9 }
10 10
11 dependencies { 11 dependencies {
12 - classpath 'com.android.tools.build:gradle:7.2.2' 12 + classpath 'com.android.tools.build:gradle:7.3.0'
13 } 13 }
14 } 14 }
15 15
@@ -29,7 +29,11 @@ import java.io.File @@ -29,7 +29,11 @@ import java.io.File
29 class MobileScanner(private val activity: Activity, private val textureRegistry: TextureRegistry) 29 class MobileScanner(private val activity: Activity, private val textureRegistry: TextureRegistry)
30 : MethodChannel.MethodCallHandler, EventChannel.StreamHandler, PluginRegistry.RequestPermissionsResultListener { 30 : MethodChannel.MethodCallHandler, EventChannel.StreamHandler, PluginRegistry.RequestPermissionsResultListener {
31 companion object { 31 companion object {
32 - private const val REQUEST_CODE = 22022022 32 + /**
  33 + * When the application's activity is [androidx.fragment.app.FragmentActivity], requestCode can only use the lower 16 bits.
  34 + * @see androidx.fragment.app.FragmentActivity.validateRequestPermissionsRequestCode
  35 + */
  36 + private const val REQUEST_CODE = 0x0786
33 private val TAG = MobileScanner::class.java.simpleName 37 private val TAG = MobileScanner::class.java.simpleName
34 } 38 }
35 39
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 android:label="mobile_scanner_example" 5 android:label="mobile_scanner_example"
6 android:icon="@mipmap/ic_launcher"> 6 android:icon="@mipmap/ic_launcher">
7 <activity 7 <activity
8 - android:name="io.flutter.embedding.android.FlutterActivity" 8 + android:name=".MainActivity"
9 android:exported="true" 9 android:exported="true"
10 android:launchMode="singleTop" 10 android:launchMode="singleTop"
11 android:theme="@style/LaunchTheme" 11 android:theme="@style/LaunchTheme"
1 package dev.steenbakker.mobile_scanner_example 1 package dev.steenbakker.mobile_scanner_example
2 2
3 -import io.flutter.embedding.android.FlutterActivity 3 +import io.flutter.embedding.android.FlutterFragmentActivity
4 4
5 -class MainActivity: FlutterActivity() { 5 +class MainActivity : FlutterFragmentActivity() {
6 } 6 }
@@ -6,7 +6,7 @@ buildscript { @@ -6,7 +6,7 @@ buildscript {
6 } 6 }
7 7
8 dependencies { 8 dependencies {
9 - classpath 'com.android.tools.build:gradle:7.2.2' 9 + classpath 'com.android.tools.build:gradle:7.3.0'
10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 } 11 }
12 } 12 }
@@ -195,13 +195,13 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan @@ -195,13 +195,13 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHan
195 let facing: Int = argReader.int(key: "facing") ?? 1 195 let facing: Int = argReader.int(key: "facing") ?? 1
196 let formats: Array = argReader.intArray(key: "formats") ?? [] 196 let formats: Array = argReader.intArray(key: "formats") ?? []
197 197
198 - let formatList: NSMutableArray = [] 198 + if (formats.count != 0) {
  199 + var barcodeFormats: BarcodeFormat = []
199 for index in formats { 200 for index in formats {
200 - formatList.add(BarcodeFormat(rawValue: index)) 201 + barcodeFormats.insert(BarcodeFormat(rawValue: index))
201 } 202 }
202 203
203 - if (formatList.count != 0) {  
204 - let barcodeOptions = BarcodeScannerOptions(formats: formatList.firstObject as! BarcodeFormat) 204 + let barcodeOptions = BarcodeScannerOptions(formats: barcodeFormats)
205 scanner = BarcodeScanner.barcodeScanner(options: barcodeOptions) 205 scanner = BarcodeScanner.barcodeScanner(options: barcodeOptions)
206 } 206 }
207 207
@@ -24,7 +24,6 @@ class MobileScannerWebPlugin { @@ -24,7 +24,6 @@ class MobileScannerWebPlugin {
24 registrar, 24 registrar,
25 ); 25 );
26 final MobileScannerWebPlugin instance = MobileScannerWebPlugin(); 26 final MobileScannerWebPlugin instance = MobileScannerWebPlugin();
27 - WidgetsFlutterBinding.ensureInitialized();  
28 27
29 channel.setMethodCallHandler(instance.handleMethodCall); 28 channel.setMethodCallHandler(instance.handleMethodCall);
30 event.setController(instance.controller); 29 event.setController(instance.controller);
@@ -9,6 +9,9 @@ class MobileScanner extends StatefulWidget { @@ -9,6 +9,9 @@ class MobileScanner extends StatefulWidget {
9 /// The controller of the camera. 9 /// The controller of the camera.
10 final MobileScannerController? controller; 10 final MobileScannerController? controller;
11 11
  12 + /// Calls the provided [onPermissionSet] callback when the permission is set.
  13 + final Function(bool permissionGranted)? onPermissionSet;
  14 +
12 /// Function that gets called when a Barcode is detected. 15 /// Function that gets called when a Barcode is detected.
13 /// 16 ///
14 /// [barcode] The barcode object with all information about the scanned code. 17 /// [barcode] The barcode object with all information about the scanned code.
@@ -34,6 +37,7 @@ class MobileScanner extends StatefulWidget { @@ -34,6 +37,7 @@ class MobileScanner extends StatefulWidget {
34 this.controller, 37 this.controller,
35 this.fit = BoxFit.cover, 38 this.fit = BoxFit.cover,
36 this.allowDuplicates = false, 39 this.allowDuplicates = false,
  40 + this.onPermissionSet,
37 }); 41 });
38 42
39 @override 43 @override
@@ -48,7 +52,8 @@ class _MobileScannerState extends State<MobileScanner> @@ -48,7 +52,8 @@ class _MobileScannerState extends State<MobileScanner>
48 void initState() { 52 void initState() {
49 super.initState(); 53 super.initState();
50 WidgetsBinding.instance.addObserver(this); 54 WidgetsBinding.instance.addObserver(this);
51 - controller = widget.controller ?? MobileScannerController(); 55 + controller = widget.controller ??
  56 + MobileScannerController(onPermissionSet: widget.onPermissionSet);
52 if (!controller.isStarting) controller.start(); 57 if (!controller.isStarting) controller.start();
53 } 58 }
54 59
@@ -118,7 +123,8 @@ class _MobileScannerState extends State<MobileScanner> @@ -118,7 +123,8 @@ class _MobileScannerState extends State<MobileScanner>
118 } 123 }
119 } else { 124 } else {
120 if (widget.controller == null) { 125 if (widget.controller == null) {
121 - controller = MobileScannerController(); 126 + controller =
  127 + MobileScannerController(onPermissionSet: widget.onPermissionSet);
122 } else if (oldWidget.controller != widget.controller) { 128 } else if (oldWidget.controller != widget.controller) {
123 controller = widget.controller!; 129 controller = widget.controller!;
124 } 130 }
@@ -39,6 +39,7 @@ class MobileScannerController { @@ -39,6 +39,7 @@ class MobileScannerController {
39 static int? _controllerHashcode; 39 static int? _controllerHashcode;
40 StreamSubscription? events; 40 StreamSubscription? events;
41 41
  42 + Function(bool permissionGranted)? onPermissionSet;
42 final ValueNotifier<MobileScannerArguments?> args = ValueNotifier(null); 43 final ValueNotifier<MobileScannerArguments?> args = ValueNotifier(null);
43 final ValueNotifier<TorchState> torchState = ValueNotifier(TorchState.off); 44 final ValueNotifier<TorchState> torchState = ValueNotifier(TorchState.off);
44 late final ValueNotifier<CameraFacing> cameraFacingState; 45 late final ValueNotifier<CameraFacing> cameraFacingState;
@@ -48,8 +49,6 @@ class MobileScannerController { @@ -48,8 +49,6 @@ class MobileScannerController {
48 final bool returnImage; 49 final bool returnImage;
49 50
50 /// If provided, the scanner will only detect those specific formats. 51 /// If provided, the scanner will only detect those specific formats.
51 - ///  
52 - /// WARNING: On iOS, only 1 format is supported.  
53 final List<BarcodeFormat>? formats; 52 final List<BarcodeFormat>? formats;
54 53
55 CameraFacing facing; 54 CameraFacing facing;
@@ -66,6 +65,7 @@ class MobileScannerController { @@ -66,6 +65,7 @@ class MobileScannerController {
66 this.ratio, 65 this.ratio,
67 this.torchEnabled, 66 this.torchEnabled,
68 this.formats, 67 this.formats,
  68 + this.onPermissionSet,
69 this.autoResume = true, 69 this.autoResume = true,
70 this.returnImage = false, 70 this.returnImage = false,
71 }) { 71 }) {
@@ -156,11 +156,14 @@ class MobileScannerController { @@ -156,11 +156,14 @@ class MobileScannerController {
156 state = result 156 state = result
157 ? MobileScannerState.authorized 157 ? MobileScannerState.authorized
158 : MobileScannerState.denied; 158 : MobileScannerState.denied;
  159 + onPermissionSet?.call(result);
159 break; 160 break;
160 case MobileScannerState.denied: 161 case MobileScannerState.denied:
161 isStarting = false; 162 isStarting = false;
  163 + onPermissionSet?.call(false);
162 throw PlatformException(code: 'NO ACCESS'); 164 throw PlatformException(code: 'NO ACCESS');
163 case MobileScannerState.authorized: 165 case MobileScannerState.authorized:
  166 + onPermissionSet?.call(true);
164 break; 167 break;
165 } 168 }
166 } 169 }
@@ -192,6 +195,9 @@ class MobileScannerController { @@ -192,6 +195,9 @@ class MobileScannerController {
192 } on PlatformException catch (error) { 195 } on PlatformException catch (error) {
193 debugPrint('${error.code}: ${error.message}'); 196 debugPrint('${error.code}: ${error.message}');
194 isStarting = false; 197 isStarting = false;
  198 + if (error.code == "MobileScannerWeb") {
  199 + onPermissionSet?.call(false);
  200 + }
195 // setAnalyzeMode(AnalyzeMode.none.index); 201 // setAnalyzeMode(AnalyzeMode.none.index);
196 return; 202 return;
197 } 203 }
@@ -204,6 +210,10 @@ class MobileScannerController { @@ -204,6 +210,10 @@ class MobileScannerController {
204 hasTorch = startResult['torchable'] as bool? ?? false; 210 hasTorch = startResult['torchable'] as bool? ?? false;
205 211
206 if (kIsWeb) { 212 if (kIsWeb) {
  213 + onPermissionSet?.call(
  214 + true,
  215 + ); // If we reach this line, it means camera permission has been granted
  216 +
207 args.value = MobileScannerArguments( 217 args.value = MobileScannerArguments(
208 webId: startResult['ViewID'] as String?, 218 webId: startResult['ViewID'] as String?,
209 size: Size( 219 size: Size(
@@ -287,6 +297,7 @@ class MobileScannerController { @@ -287,6 +297,7 @@ class MobileScannerController {
287 events?.cancel(); 297 events?.cancel();
288 events = null; 298 events = null;
289 _controllerHashcode = null; 299 _controllerHashcode = null;
  300 + onPermissionSet = null;
290 } 301 }
291 barcodesController.close(); 302 barcodesController.close();
292 } 303 }