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 4fce11d..035431e 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt @@ -1,42 +1,128 @@ package net.touchcapture.qr.flutterqr +import android.Manifest +import android.app.Activity +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build 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.MethodCall +import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result -import io.flutter.plugin.common.PluginRegistry.Registrar +import io.flutter.plugin.common.PluginRegistry -class FlutterQrPlugin : FlutterPlugin, MethodCallHandler { +class FlutterQrPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { - /** Plugin registration embedding v1 */ - companion object { - @JvmStatic - fun registerWith(registrar: Registrar) { - FlutterQrPlugin().onAttachedToEngine(registrar) - } - } + var cameraPermissionContinuation: Runnable? = null + var requestingPermission = false +// private var activity: Activity? = null + +// /** Plugin registration embedding v1 */ +// companion object { +// @JvmStatic +// fun registerWith(registrar: Registrar) { +// FlutterQrPlugin().onAttachedToEngine(registrar) +// } +// } /** Plugin registration embedding v2 */ override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - onAttachedToEngine(flutterPluginBinding) + onAttachedToEngines(flutterPluginBinding) } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { } - private fun onAttachedToEngine(registrar: Registrar) { - registrar - .platformViewRegistry() + // TODO: Fix v1 embedding for Flutter < 1.12 support + /** Plugin start for both embedding v1 & v2 */ + private fun onAttachedToEngines(binding: FlutterPlugin.FlutterPluginBinding) { + binding.platformViewRegistry .registerViewFactory( - "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(registrar)) + "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(binding.binaryMessenger)) } +// private fun onAttachedToEngine(registrar: Registrar) { +// activity = registrar.activity() +// registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) +// checkAndRequestPermission(null) +// registrar +// .platformViewRegistry() +// .registerViewFactory( +// "net.touchcapture.qr.flutterqr/qrview", QRViewFactory(registrar)) +// } + override fun onMethodCall(call: MethodCall, result: Result) { when (call.method) { - "getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}") - else -> result.notImplemented() + "checkAndRequestPermission" -> checkAndRequestPermission(result) + } + } + + override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) { + Shared.activityPluginBinding = activityPluginBinding + Shared.activity = activityPluginBinding.activity + activityPluginBinding.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) + checkAndRequestPermission(null) + } + + override fun onDetachedFromActivityForConfigChanges() { + Shared.activityPluginBinding = null + Shared.activity = null + } + + override fun onReattachedToActivityForConfigChanges(activityPluginBinding: ActivityPluginBinding) { + Shared.activityPluginBinding = activityPluginBinding + Shared.activity = activityPluginBinding.activity + } + + override fun onDetachedFromActivity() { + Shared.activityPluginBinding = null + Shared.activity = null + } + + private inner class CameraRequestPermissionsListener : PluginRegistry.RequestPermissionsResultListener { + override fun onRequestPermissionsResult(id: Int, permissions: Array, grantResults: IntArray): Boolean { + if (id == QRView.CAMERA_REQUEST_ID && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + cameraPermissionContinuation?.run() + return true + } + return false + } + } + + private fun hasCameraPermission(): Boolean { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || + Shared.activity?.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED + } + + private fun checkAndRequestPermission(result: Result?) { + if (cameraPermissionContinuation != null) { + result?.error("cameraPermission", "Camera permission request ongoing", null); + } + + cameraPermissionContinuation = Runnable { + cameraPermissionContinuation = null + if (!hasCameraPermission()) { + result?.error( + "cameraPermission", "MediaRecorderCamera permission not granted", null) + return@Runnable + } + } + + requestingPermission = false + if (hasCameraPermission()) { + cameraPermissionContinuation?.run() + } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestingPermission = true + Shared.activity?.requestPermissions( + arrayOf(Manifest.permission.CAMERA), + QRView.CAMERA_REQUEST_ID) + } } } } 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 ae6260c..ede6fc2 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt @@ -1,12 +1,9 @@ package net.touchcapture.qr.flutterqr -import android.Manifest import android.app.Activity import android.app.Application import android.content.Context import android.content.pm.PackageManager -import android.content.pm.PackageManager.PERMISSION_GRANTED -import android.os.Build import android.os.Bundle import android.view.View import com.google.zxing.ResultPoint @@ -14,39 +11,34 @@ import android.hardware.Camera.CameraInfo 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(private val registrar: PluginRegistry.Registrar, id: Int) : - PlatformView,MethodChannel.MethodCallHandler { +class QRView(messenger: BinaryMessenger, id: Int, private val context: Context) : + PlatformView, MethodChannel.MethodCallHandler { companion object { const val CAMERA_REQUEST_ID = 513469796 } var barcodeView: BarcodeView? = null - private val activity = registrar.activity() - var cameraPermissionContinuation: Runnable? = null - var requestingPermission = false + private var isTorchOn: Boolean = false val channel: MethodChannel init { - registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener()) - channel = MethodChannel(registrar.messenger(), "net.touchcapture.qr.flutterqr/qrview_$id") + channel = MethodChannel(messenger, "net.touchcapture.qr.flutterqr/qrview_$id") channel.setMethodCallHandler(this) - checkAndRequestPermission(null) - registrar.activity().application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { + Shared.activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { override fun onActivityPaused(p0: Activity) { - if (p0 == registrar.activity()) { + if (p0 == Shared.activity) { barcodeView?.pause() } } override fun onActivityResumed(p0: Activity) { - if (p0 == registrar.activity()) { + if (p0 == Shared.activity) { barcodeView?.resume() } } @@ -102,7 +94,7 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : } private fun hasFlash(): Boolean { - return registrar.activeContext().packageManager + return context.packageManager .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH) } @@ -120,7 +112,7 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : } private fun createBarCodeView(): BarcodeView? { - val barcode = BarcodeView(registrar.activity()) + val barcode = BarcodeView(Shared.activity) barcode.decodeContinuous( object : BarcodeCallback { override fun barcodeResult(result: BarcodeResult) { @@ -138,27 +130,8 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : barcodeView = null } - private inner class CameraRequestPermissionsListener : PluginRegistry.RequestPermissionsResultListener { - override fun onRequestPermissionsResult(id: Int, permissions: Array, grantResults: IntArray): Boolean { - if (id == CAMERA_REQUEST_ID && grantResults[0] == PERMISSION_GRANTED) { - cameraPermissionContinuation?.run() - return true - } - return false - } - } - - private fun hasCameraPermission(): Boolean { - return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || - activity.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED - } - - override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { - when(call?.method){ - "checkAndRequestPermission" -> { - checkAndRequestPermission(result) - } + when(call.method){ "flipCamera" -> { flipCamera() } @@ -174,33 +147,6 @@ class QRView(private val registrar: PluginRegistry.Registrar, id: Int) : } } - private fun checkAndRequestPermission(result: MethodChannel.Result?) { - if (cameraPermissionContinuation != null) { - result?.error("cameraPermission", "Camera permission request ongoing", null); - } - - cameraPermissionContinuation = Runnable { - cameraPermissionContinuation = null - if (!hasCameraPermission()) { - result?.error( - "cameraPermission", "MediaRecorderCamera permission not granted", null) - return@Runnable - } - } - requestingPermission = false - if (hasCameraPermission()) { - cameraPermissionContinuation?.run() - } else { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestingPermission = true - registrar - .activity() - .requestPermissions( - arrayOf(Manifest.permission.CAMERA), - CAMERA_REQUEST_ID) - } - } - } } diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt index f9be661..a797084 100644 --- a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt @@ -1,17 +1,17 @@ package net.touchcapture.qr.flutterqr import android.content.Context -import io.flutter.plugin.common.PluginRegistry +import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.StandardMessageCodec import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformViewFactory -class QRViewFactory(private val registrar: PluginRegistry.Registrar) : +class QRViewFactory(private val messenger: BinaryMessenger) : PlatformViewFactory(StandardMessageCodec.INSTANCE) { override fun create(context: Context, id: Int, obj: Any?): PlatformView { - return QRView(registrar,id) + return QRView(messenger, id, context) } } \ No newline at end of file diff --git a/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt new file mode 100644 index 0000000..5957725 --- /dev/null +++ b/android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt @@ -0,0 +1,10 @@ +package net.touchcapture.qr.flutterqr + +import android.app.Activity +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding + + +object Shared { + var activityPluginBinding: ActivityPluginBinding? = null + var activity: Activity? = null +} \ No newline at end of file