Julian Steenbakker

Merge branch 'master' into feature/scan-window

# Conflicts:
#	lib/src/mobile_scanner.dart
name: code analysis & formatting
on: [push, pull_request]
on:
push:
branches:
- master
pull_request:
types: [ opened, labeled, unlabeled, synchronize ]
jobs:
analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
- uses: actions/checkout@v3.0.2
- uses: actions/setup-java@v3.4.1
with:
distribution: 'temurin'
java-version: '11'
- uses: subosito/flutter-action@v2.4.0
java-version: 11
distribution: temurin
- uses: subosito/flutter-action@v2.6.1
with:
cache: true
- name: Version
run: flutter doctor -v
- name: Install dependencies
... ... @@ -21,11 +28,13 @@ jobs:
formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
- uses: actions/checkout@v3.0.2
- uses: actions/setup-java@v3.4.1
with:
java-version: 11
distribution: temurin
- uses: subosito/flutter-action@v2.6.1
with:
distribution: 'temurin'
java-version: '11'
- uses: subosito/flutter-action@v2.4.0
cache: true
- name: Format
run: flutter format -n --set-exit-if-changed .
\ No newline at end of file
run: flutter format -n --set-exit-if-changed .
... ...
... ... @@ -2,7 +2,7 @@ group 'dev.steenbakker.mobile_scanner'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.6.21'
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
... ... @@ -52,8 +52,8 @@ dependencies {
// Use this dependency to use the dynamically downloaded model in Google Play Services
// implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:18.0.0'
implementation "androidx.camera:camera-camera2:1.2.0-alpha01"
implementation 'androidx.camera:camera-lifecycle:1.2.0-alpha01'
implementation "androidx.camera:camera-camera2:1.2.0-alpha04"
implementation 'androidx.camera:camera-lifecycle:1.2.0-alpha04'
// // The following line is optional, as the core library is included indirectly by camera-camera2
// implementation "androidx.camera:camera-core:1.1.0-alpha11"
... ...
buildscript {
ext.kotlin_version = '1.6.21'
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
... ...
... ... @@ -133,9 +133,9 @@ class _BarcodeScannerWithControllerState
icon: const Icon(Icons.image),
iconSize: 32.0,
onPressed: () async {
final ImagePicker _picker = ImagePicker();
final ImagePicker picker = ImagePicker();
// Pick an image
final XFile? image = await _picker.pickImage(
final XFile? image = await picker.pickImage(
source: ImageSource.gallery,
);
if (image != null) {
... ...
... ... @@ -16,7 +16,7 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
lint: ^1.8.2
lint: ^1.10.0
flutter:
uses-material-design: true
... ...
... ... @@ -37,13 +37,12 @@ class MobileScanner extends StatefulWidget {
/// Create a [MobileScanner] with a [controller], the [controller] must has been initialized.
const MobileScanner({
Key? key,
super.key,
required this.onDetect,
this.controller,
this.fit = BoxFit.cover,
this.allowDuplicates = false,
this.scanWindow,
}) : super(key: key);
});
@override
State<MobileScanner> createState() => _MobileScannerState();
... ... @@ -58,13 +57,14 @@ class _MobileScannerState extends State<MobileScanner>
super.initState();
WidgetsBinding.instance.addObserver(this);
controller = widget.controller ?? MobileScannerController();
if (!controller.isStarting) controller.start();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
if (!controller.isStarting) controller.start();
if (!controller.isStarting && controller.autoResume) controller.start();
break;
case AppLifecycleState.inactive:
case AppLifecycleState.paused:
... ... @@ -134,7 +134,7 @@ class _MobileScannerState extends State<MobileScanner>
builder: (context, value, child) {
value = value as MobileScannerArguments?;
if (value == null) {
return Container(color: Colors.black);
return const ColoredBox(color: Colors.black);
} else {
if (widget.scanWindow != null) {
final window = calculateScanWindowRelativeToTextureInPercentage(
... ...
... ... @@ -35,7 +35,8 @@ class MobileScannerController {
EventChannel eventChannel =
const EventChannel('dev.steenbakker.mobile_scanner/scanner/event');
int? _controllerHashcode;
//Must be static to keep the same value on new instances
static int? _controllerHashcode;
StreamSubscription? events;
final ValueNotifier<MobileScannerArguments?> args = ValueNotifier(null);
... ... @@ -53,6 +54,9 @@ class MobileScannerController {
bool hasTorch = false;
late StreamController<Barcode> barcodesController;
/// Whether to automatically resume the camera when the application is resumed
bool autoResume;
Stream<Barcode> get barcodes => barcodesController.stream;
MobileScannerController({
... ... @@ -60,6 +64,7 @@ class MobileScannerController {
this.ratio,
this.torchEnabled,
this.formats,
this.autoResume = true,
}) {
// In case a new instance is created before calling dispose()
if (_controllerHashcode != null) {
... ... @@ -75,8 +80,6 @@ class MobileScannerController {
// onCancel: () => setAnalyzeMode(AnalyzeMode.none.index),
);
start();
// Listen to events from the platform specific code
events = eventChannel
.receiveBroadcastStream()
... ... @@ -88,22 +91,22 @@ class MobileScannerController {
final data = event['data'];
switch (name) {
case 'torchState':
final state = TorchState.values[data as int];
final state = TorchState.values[data as int? ?? 0];
torchState.value = state;
break;
case 'barcode':
final barcode = Barcode.fromNative(data as Map);
final barcode = Barcode.fromNative(data as Map? ?? {});
barcodesController.add(barcode);
break;
case 'barcodeMac':
barcodesController.add(
Barcode(
rawValue: (data as Map)['payload'] as String,
rawValue: (data as Map)['payload'] as String?,
),
);
break;
case 'barcodeWeb':
barcodesController.add(Barcode(rawValue: data as String));
barcodesController.add(Barcode(rawValue: data as String?));
break;
default:
throw UnimplementedError();
... ... @@ -134,11 +137,11 @@ class MobileScannerController {
// Check authorization status
if (!kIsWeb) {
MobileScannerState state = MobileScannerState
.values[await methodChannel.invokeMethod('state') as int];
.values[await methodChannel.invokeMethod('state') as int? ?? 0];
switch (state) {
case MobileScannerState.undetermined:
final bool result =
await methodChannel.invokeMethod('request') as bool;
await methodChannel.invokeMethod('request') as bool? ?? false;
state = result
? MobileScannerState.authorized
: MobileScannerState.denied;
... ... @@ -194,21 +197,21 @@ class MobileScannerController {
throw PlatformException(code: 'INITIALIZATION ERROR');
}
hasTorch = startResult['torchable'] as bool;
hasTorch = startResult['torchable'] as bool? ?? false;
if (kIsWeb) {
args.value = MobileScannerArguments(
webId: startResult['ViewID'] as String?,
size: Size(
startResult['videoWidth'] as double,
startResult['videoHeight'] as double,
startResult['videoWidth'] as double? ?? 0,
startResult['videoHeight'] as double? ?? 0,
),
hasTorch: hasTorch,
);
} else {
args.value = MobileScannerArguments(
textureId: startResult['textureId'] as int,
size: toSize(startResult['size'] as Map),
textureId: startResult['textureId'] as int?,
size: toSize(startResult['size'] as Map? ?? {}),
hasTorch: hasTorch,
);
}
... ...
... ... @@ -17,7 +17,7 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
lint: ^1.8.2
lint: ^1.10.0
flutter:
plugin:
... ...