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 958a8da..f096d27 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt @@ -21,7 +21,7 @@ class FlutterQrPlugin : FlutterPlugin, ActivityAware { } private fun onAttachedToV1(registrar: PluginRegistry.Registrar) { - registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) + Shared.registrar = registrar onAttachedToEngines(registrar.platformViewRegistry(), registrar.messenger(), registrar.activity()) } @@ -45,27 +45,23 @@ class FlutterQrPlugin : FlutterPlugin, ActivityAware { override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) { Shared.activity = activityPluginBinding.activity - activityPluginBinding.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) + Shared.binding = activityPluginBinding } override fun onDetachedFromActivityForConfigChanges() { Shared.activity = null + Shared.binding = null } override fun onReattachedToActivityForConfigChanges(activityPluginBinding: ActivityPluginBinding) { Shared.activity = activityPluginBinding.activity + Shared.binding = activityPluginBinding } override fun onDetachedFromActivity() { Shared.activity = null + Shared.binding = null } - inner class CameraRequestPermissionsListener : PluginRegistry.RequestPermissionsResultListener { - override fun onRequestPermissionsResult(id: Int, permissions: Array, grantResults: IntArray): Boolean { - if (id == Shared.CAMERA_REQUEST_ID && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - return true - } - return false - } - } + } 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 e914f40..c7355b3 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt @@ -4,40 +4,50 @@ import android.Manifest import android.app.Activity import android.app.Application import android.content.pm.PackageManager -import android.os.Bundle -import android.view.View -import com.google.zxing.ResultPoint import android.hardware.Camera.CameraInfo import android.os.Build +import android.os.Bundle +import android.view.View import com.google.zxing.BarcodeFormat +import com.google.zxing.ResultPoint 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(messenger: BinaryMessenger, id: Int, private val params: HashMap) : - PlatformView, MethodChannel.MethodCallHandler { + PlatformView, MethodChannel.MethodCallHandler, PluginRegistry.RequestPermissionsResultListener { private var isTorchOn: Boolean = false private var isPaused: Boolean = false private var barcodeView: BarcodeView? = null - private val channel: MethodChannel + private val channel: MethodChannel = MethodChannel(messenger, "net.touchcapture.qr.flutterqr/qrview_$id") + private var permissionGranted: Boolean = false init { - checkAndRequestPermission(null) - channel = MethodChannel(messenger, "net.touchcapture.qr.flutterqr/qrview_$id") + if (Shared.binding != null) { + 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) { - if (p0 == Shared.activity && !isPaused) { + if (p0 == Shared.activity && !isPaused && hasCameraPermission()) { barcodeView?.pause() } } override fun onActivityResumed(p0: Activity) { - if (p0 == Shared.activity && !isPaused) { + if (p0 == Shared.activity && !isPaused && hasCameraPermission()) { barcodeView?.resume() } } @@ -93,20 +103,22 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap?, result: MethodChannel.Result) { - if (!hasCameraPermission()) { - return cameraPermissionNotSet(result) - } - val allowedBarcodeTypes = mutableListOf() try { arguments?.forEach { @@ -254,7 +261,6 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap result?.success(true) Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> { Shared.activity?.requestPermissions( arrayOf(Manifest.permission.CAMERA), @@ -265,5 +271,20 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap?, + grantResults: IntArray): Boolean { + + if (requestCode == Shared.CAMERA_REQUEST_ID && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + permissionGranted = true + channel.invokeMethod("onPermissionSet", true) + return true + } + permissionGranted = false + channel.invokeMethod("onPermissionSet", 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 a5a663d..996df87 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt @@ -1,8 +1,12 @@ package net.touchcapture.qr.flutterqr import android.app.Activity +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.PluginRegistry 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/lib/src/qr_code_scanner.dart b/lib/src/qr_code_scanner.dart index 911242d..0e4fb8d 100644 --- a/lib/src/qr_code_scanner.dart +++ b/lib/src/qr_code_scanner.dart @@ -64,12 +64,12 @@ class _QRViewState extends State { super.initState(); WidgetsBinding.instance.addObserver(LifecycleEventHandler( resumeCallBack: () async => { - if (_channel != null) { - QRViewController.updateDimensions( - widget.key, _channel, - overlay: widget.overlay) - } - })); + if (_channel != null) + { + QRViewController.updateDimensions(widget.key, _channel, + overlay: widget.overlay) + } + })); } @override @@ -86,9 +86,9 @@ class _QRViewState extends State { bool onNotification(notification) { Future.microtask(() => { - QRViewController.updateDimensions(widget.key, _channel, - overlay: widget.overlay) - }); + QRViewController.updateDimensions(widget.key, _channel, + overlay: widget.overlay) + }); return false; } @@ -139,9 +139,9 @@ class _QRViewState extends State { _channel = MethodChannel('net.touchcapture.qr.flutterqr/qrview_$id'); // Start scan after creation of the view - final controller = - QRViewController._(_channel, widget.key, widget.onPermissionSet) - .._startScan(widget.key, widget.overlay, widget.formatsAllowed); + final controller = QRViewController._( + _channel, widget.key, widget.onPermissionSet, widget.cameraFacing) + .._startScan(widget.key, widget.overlay, widget.formatsAllowed); // Initialize the controller for controlling the QRView if (widget.onQRViewCreated != null) { @@ -166,8 +166,9 @@ class _QrCameraSettings { class QRViewController { QRViewController._(MethodChannel channel, GlobalKey qrKey, - PermissionSetCallback onPermissionSet) - : _channel = channel { + PermissionSetCallback onPermissionSet, CameraFacing cameraFacing) + : _channel = channel, + _cameraFacing = cameraFacing { _channel.setMethodCallHandler((call) async { switch (call.method) { case 'onRecognizeQR': @@ -204,6 +205,7 @@ class QRViewController { } final MethodChannel _channel; + final CameraFacing _cameraFacing; final StreamController _scanUpdateController = StreamController(); @@ -232,6 +234,8 @@ class QRViewController { /// Gets information about which camera is active. Future getCameraInfo() async { try { + var cameraFacing = await _channel.invokeMethod('getCameraInfo') as int; + if (cameraFacing == -1) return _cameraFacing; return CameraFacing .values[await _channel.invokeMethod('getCameraInfo') as int]; } on PlatformException catch (e) { @@ -320,7 +324,7 @@ class QRViewController { await Future.delayed(Duration(milliseconds: 300)); } final RenderBox renderBox = key.currentContext.findRenderObject(); - try { + try { await channel.invokeMethod('setDimensions', { 'width': renderBox.size.width, 'height': renderBox.size.height,