diff --git a/analysis_options.yaml b/analysis_options.yaml index d4fcc1ad..a3be6b82 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1 +1 @@ -include: package:pedantic/analysis_options.yaml \ No newline at end of file +include: package:flutter_lints/flutter.yaml \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index bb37cf7d..cd4c6f94 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.5.10' + ext.kotlin_version = '1.5.31' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.1' + classpath 'com.android.tools.build:gradle:7.0.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -36,9 +36,7 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true } - buildFeatures { - viewBinding = true - } + compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index ae4f48ec..28f2e86f 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ - + diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/CustomFramingRectBarcodeView.java b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/CustomFramingRectBarcodeView.java deleted file mode 100644 index 5203968e..00000000 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/CustomFramingRectBarcodeView.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.touchcapture.qr.flutterqr; - -import android.content.Context; -import android.graphics.Rect; -import android.util.AttributeSet; - -import com.journeyapps.barcodescanner.BarcodeView; -import com.journeyapps.barcodescanner.Size; - -public class CustomFramingRectBarcodeView extends BarcodeView { - - private static final int BOTTOM_OFFSET_NOT_SET_VALUE = -1; - - private int bottomOffset = BOTTOM_OFFSET_NOT_SET_VALUE; - - public CustomFramingRectBarcodeView(Context context) { - super(context); - } - - public CustomFramingRectBarcodeView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public CustomFramingRectBarcodeView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @Override - protected Rect calculateFramingRect(Rect container, Rect surface) { - Rect containerArea = new Rect(container); - boolean intersects = containerArea.intersect(surface);//adjusts the containerArea (code from super.calculateFramingRect) - Rect scanAreaRect = super.calculateFramingRect(container, surface); - if (bottomOffset != BOTTOM_OFFSET_NOT_SET_VALUE) {//if the setFramingRect function was called, then we shift the scan area by Y - Rect scanAreaRectWithOffset = new Rect(scanAreaRect); - scanAreaRectWithOffset.bottom -= bottomOffset; - scanAreaRectWithOffset.top -= bottomOffset; - - boolean belongsToContainer = scanAreaRectWithOffset.intersect(containerArea); - if(belongsToContainer){ - return scanAreaRectWithOffset; - } - } - return scanAreaRect; - } - - public void setFramingRect(int rectWidth, int rectHeight, int bottomOffset) { - this.bottomOffset = bottomOffset; - this.setFramingRectSize(new Size(rectWidth, rectHeight)); - } -} diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/CustomFramingRectBarcodeView.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/CustomFramingRectBarcodeView.kt new file mode 100644 index 00000000..8a6908dd --- /dev/null +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/CustomFramingRectBarcodeView.kt @@ -0,0 +1,45 @@ +package net.touchcapture.qr.flutterqr + +import android.content.Context +import android.graphics.Rect +import android.util.AttributeSet +import com.journeyapps.barcodescanner.BarcodeView +import com.journeyapps.barcodescanner.Size + +class CustomFramingRectBarcodeView : BarcodeView { + private var bottomOffset = BOTTOM_OFFSET_NOT_SET_VALUE + + constructor(context: Context?) : super(context) {} + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {} + constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( + context, + attrs, + defStyleAttr + ) + + override fun calculateFramingRect(container: Rect, surface: Rect): Rect { + val containerArea = Rect(container) + val intersects = + containerArea.intersect(surface) //adjusts the containerArea (code from super.calculateFramingRect) + val scanAreaRect = super.calculateFramingRect(container, surface) + if (bottomOffset != BOTTOM_OFFSET_NOT_SET_VALUE) { //if the setFramingRect function was called, then we shift the scan area by Y + val scanAreaRectWithOffset = Rect(scanAreaRect) + scanAreaRectWithOffset.bottom -= bottomOffset + scanAreaRectWithOffset.top -= bottomOffset + val belongsToContainer = scanAreaRectWithOffset.intersect(containerArea) + if (belongsToContainer) { + return scanAreaRectWithOffset + } + } + return scanAreaRect + } + + fun setFramingRect(rectWidth: Int, rectHeight: Int, bottomOffset: Int) { + this.bottomOffset = bottomOffset + framingRectSize = Size(rectWidth, rectHeight) + } + + companion object { + private const val BOTTOM_OFFSET_NOT_SET_VALUE = -1 + } +} \ No newline at end of file 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 f096d271..ef37c405 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt @@ -1,65 +1,43 @@ package net.touchcapture.qr.flutterqr -import android.app.Activity -import android.content.pm.PackageManager 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.PluginRegistry -import io.flutter.plugin.platform.PlatformViewRegistry +import net.touchcapture.qr.flutterqr.Shared.activity class FlutterQrPlugin : FlutterPlugin, ActivityAware { - /** Plugin registration embedding v1 */ - companion object { - @JvmStatic - fun registerWith(registrar: PluginRegistry.Registrar) { - FlutterQrPlugin().onAttachedToV1(registrar) - } - } - - private fun onAttachedToV1(registrar: PluginRegistry.Registrar) { - Shared.registrar = registrar - onAttachedToEngines(registrar.platformViewRegistry(), registrar.messenger(), registrar.activity()) - } - /** Plugin registration embedding v2 */ override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - onAttachedToEngines(flutterPluginBinding.platformViewRegistry, flutterPluginBinding.binaryMessenger, Shared.activity) + if (activity != null) { + activity = activity + } + flutterPluginBinding.platformViewRegistry + .registerViewFactory( + "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(flutterPluginBinding.binaryMessenger)) } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { } - /** Plugin start for both embedding v1 & v2 */ - private fun onAttachedToEngines(platformViewRegistry: PlatformViewRegistry, messenger: BinaryMessenger, activity: Activity?) { - if (activity != null) { - Shared.activity = activity - } - platformViewRegistry - .registerViewFactory( - "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(messenger)) - } - override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) { - Shared.activity = activityPluginBinding.activity + activity = activityPluginBinding.activity Shared.binding = activityPluginBinding } override fun onDetachedFromActivityForConfigChanges() { - Shared.activity = null + activity = null Shared.binding = null } override fun onReattachedToActivityForConfigChanges(activityPluginBinding: ActivityPluginBinding) { - Shared.activity = activityPluginBinding.activity + activity = activityPluginBinding.activity Shared.binding = activityPluginBinding } override fun onDetachedFromActivity() { - Shared.activity = null + activity = null Shared.binding = null } 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 0369775e..3578f444 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt @@ -34,10 +34,6 @@ class QRView(private val context: Context, messenger: BinaryMessenger, private v Shared.binding!!.addRequestPermissionsResultListener(this) } - if (Shared.registrar != null) { - Shared.registrar!!.addRequestPermissionsResultListener(this) - } - channel.setMethodCallHandler(this) Shared.activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { override fun onActivityPaused(p0: Activity) { @@ -306,14 +302,14 @@ class QRView(private val context: Context, messenger: BinaryMessenger, private v permissions: Array?, grantResults: IntArray): Boolean { if(requestCode == Shared.CAMERA_REQUEST_ID + this.id) { - if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + return if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { permissionGranted = true channel.invokeMethod("onPermissionSet", true) - return true + true } else { permissionGranted = false channel.invokeMethod("onPermissionSet", false) - return false + false } } return false 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 996df875..df8ed9ed 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt @@ -8,5 +8,4 @@ object Shared { const val CAMERA_REQUEST_ID = 513469796 var activity: Activity? = null var binding: ActivityPluginBinding? = null - var registrar: PluginRegistry.Registrar? = null } \ No newline at end of file diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml new file mode 100644 index 00000000..a3be6b82 --- /dev/null +++ b/example/analysis_options.yaml @@ -0,0 +1 @@ +include: package:flutter_lints/flutter.yaml \ No newline at end of file diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index adb99255..39cfa1f5 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 30 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -36,7 +36,7 @@ android { applicationId "net.touchcapture.qr.flutterqrexample" // minSdkVersion is determined by Native View. minSdkVersion 20 - targetSdkVersion 30 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -56,7 +56,7 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - testImplementation 'junit:junit:4.13.1' + testImplementation 'junit:junit:4.13.2' 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/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 3407805c..d5fb6aa3 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -16,17 +16,13 @@ android:label="flutter_qr_example" android:icon="@mipmap/ic_launcher"> - - - runApp(MaterialApp(home: MyHome())); +void main() => runApp(const MaterialApp(home: MyHome())); class MyHome extends StatelessWidget { const MyHome({Key? key}) : super(key: key); @@ -13,15 +13,15 @@ class MyHome extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: Text('Flutter Demo Home Page')), + appBar: AppBar(title: const Text('Flutter Demo Home Page')), body: Center( child: ElevatedButton( onPressed: () { Navigator.of(context).push(MaterialPageRoute( - builder: (context) => QRViewExample(), + builder: (context) => const QRViewExample(), )); }, - child: Text('qrView'), + child: const Text('qrView'), ), ), ); @@ -29,6 +29,8 @@ class MyHome extends StatelessWidget { } class QRViewExample extends StatefulWidget { + const QRViewExample({Key? key}) : super(key: key); + @override State createState() => _QRViewExampleState(); } @@ -66,13 +68,13 @@ class _QRViewExampleState extends State { Text( 'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}') else - Text('Scan a code'), + const Text('Scan a code'), Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( - margin: EdgeInsets.all(8), + margin: const EdgeInsets.all(8), child: ElevatedButton( onPressed: () async { await controller?.toggleFlash(); @@ -86,7 +88,7 @@ class _QRViewExampleState extends State { )), ), Container( - margin: EdgeInsets.all(8), + margin: const EdgeInsets.all(8), child: ElevatedButton( onPressed: () async { await controller?.flipCamera(); @@ -99,7 +101,7 @@ class _QRViewExampleState extends State { return Text( 'Camera facing ${describeEnum(snapshot.data!)}'); } else { - return Text('loading'); + return const Text('loading'); } }, )), @@ -111,21 +113,23 @@ class _QRViewExampleState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( - margin: EdgeInsets.all(8), + margin: const EdgeInsets.all(8), child: ElevatedButton( onPressed: () async { await controller?.pauseCamera(); }, - child: Text('pause', style: TextStyle(fontSize: 20)), + child: const Text('pause', + style: TextStyle(fontSize: 20)), ), ), Container( - margin: EdgeInsets.all(8), + margin: const EdgeInsets.all(8), child: ElevatedButton( onPressed: () async { await controller?.resumeCamera(); }, - child: Text('resume', style: TextStyle(fontSize: 20)), + child: const Text('resume', + style: TextStyle(fontSize: 20)), ), ) ], @@ -175,7 +179,7 @@ class _QRViewExampleState extends State { log('${DateTime.now().toIso8601String()}_onPermissionSet $p'); if (!p) { ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('no Permission')), + const SnackBar(content: Text('no Permission')), ); } } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b93026c1..30a6d725 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: sdk: flutter dev_dependencies: - pedantic: ^1.11.0 + flutter_lints: ^1.0.4 flutter_test: sdk: flutter diff --git a/lib/src/qr_code_scanner.dart b/lib/src/qr_code_scanner.dart index 238529c9..776d83ab 100644 --- a/lib/src/qr_code_scanner.dart +++ b/lib/src/qr_code_scanner.dart @@ -126,7 +126,7 @@ class _QRViewState extends State { onPlatformViewCreated: _onPlatformViewCreated, creationParams: _QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(), - creationParamsCodec: StandardMessageCodec(), + creationParamsCodec: const StandardMessageCodec(), ); break; case TargetPlatform.iOS: @@ -135,7 +135,7 @@ class _QRViewState extends State { onPlatformViewCreated: _onPlatformViewCreated, creationParams: _QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(), - creationParamsCodec: StandardMessageCodec(), + creationParamsCodec: const StandardMessageCodec(), ); break; default: @@ -327,7 +327,7 @@ class QRViewController { {QrScannerOverlayShape? overlay}) async { if (defaultTargetPlatform == TargetPlatform.iOS) { // Add small delay to ensure the render box is loaded - await Future.delayed(Duration(milliseconds: 300)); + await Future.delayed(const Duration(milliseconds: 300)); if (key.currentContext == null) return false; final renderBox = key.currentContext!.findRenderObject() as RenderBox; try { diff --git a/lib/src/web/flutter_qr_web.dart b/lib/src/web/flutter_qr_web.dart index f0622488..1da34070 100644 --- a/lib/src/web/flutter_qr_web.dart +++ b/lib/src/web/flutter_qr_web.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_web_libraries_in_flutter + import 'dart:async'; import 'dart:core'; import 'dart:html' as html; @@ -59,11 +61,11 @@ class _WebQrViewState extends State { QRViewControllerWeb? _controller; - late Size _size = Size(0, 0); + late Size _size = const Size(0, 0); Timer? timer; String? code; String? _errorMsg; - var video; + html.VideoElement video = html.VideoElement(); String viewID = 'QRVIEW-' + DateTime.now().millisecondsSinceEpoch.toString(); final StreamController _scanUpdateController = @@ -78,13 +80,13 @@ class _WebQrViewState extends State { facing = widget.cameraFacing ?? CameraFacing.front; - video = html.VideoElement(); + // video = html.VideoElement(); WebQrView.vidDiv.children = [video]; // ignore: UNDEFINED_PREFIXED_NAME ui.platformViewRegistry .registerViewFactory(viewID, (int id) => WebQrView.vidDiv); // giving JavaScipt some time to process the DOM changes - Timer(Duration(milliseconds: 500), () { + Timer(const Duration(milliseconds: 500), () { start(); }); } @@ -92,7 +94,8 @@ class _WebQrViewState extends State { Future start() async { await _makeCall(); _frameIntervall?.cancel(); - _frameIntervall = Timer.periodic(Duration(milliseconds: 200), (timer) { + _frameIntervall = + Timer.periodic(const Duration(milliseconds: 200), (timer) { _captureFrame2(); }); } @@ -202,7 +205,7 @@ class _WebQrViewState extends State { return Center(child: Text(_errorMsg!)); } if (_localStream == null) { - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); } return LayoutBuilder( builder: (context, constraints) { diff --git a/pubspec.yaml b/pubspec.yaml index a050b960..8064790d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ repository: https://github.com/juliuscanute/qr_code_scanner environment: sdk: '>=2.12.0 <3.0.0' - flutter: ">=1.10.0" + flutter: ">=1.12.0" dependencies: js: ^0.6.3 @@ -16,7 +16,7 @@ dependencies: sdk: flutter dev_dependencies: - pedantic: ^1.11.0 + flutter_lints: ^1.0.4 flutter: plugin: