Просмотр исходного кода

Fixed permission callback on Android (#251)

flutter-beta
Julian Steenbakker 5 лет назад
Родитель
Сommit
ff33ea9fc0
Не найден GPG ключ соответствующий данной подписи Идентификатор GPG ключа: 16E437C7A3D94250
4 измененных файлов: 56 добавлений и 38 удалений
  1. +6
    -10
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt
  2. +40
    -25
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt
  3. +4
    -0
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt
  4. +6
    -3
      lib/src/qr_code_scanner.dart

+ 6
- 10
android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt Просмотреть файл

@@ -21,7 +21,7 @@ class FlutterQrPlugin : FlutterPlugin, ActivityAware {
} }


private fun onAttachedToV1(registrar: PluginRegistry.Registrar) { private fun onAttachedToV1(registrar: PluginRegistry.Registrar) {
registrar.addRequestPermissionsResultListener(CameraRequestPermissionsListener())
Shared.registrar = registrar
onAttachedToEngines(registrar.platformViewRegistry(), registrar.messenger(), registrar.activity()) onAttachedToEngines(registrar.platformViewRegistry(), registrar.messenger(), registrar.activity())
} }


@@ -45,27 +45,23 @@ class FlutterQrPlugin : FlutterPlugin, ActivityAware {


override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) { override fun onAttachedToActivity(activityPluginBinding: ActivityPluginBinding) {
Shared.activity = activityPluginBinding.activity Shared.activity = activityPluginBinding.activity
activityPluginBinding.addRequestPermissionsResultListener(CameraRequestPermissionsListener())
Shared.binding = activityPluginBinding
} }


override fun onDetachedFromActivityForConfigChanges() { override fun onDetachedFromActivityForConfigChanges() {
Shared.activity = null Shared.activity = null
Shared.binding = null
} }


override fun onReattachedToActivityForConfigChanges(activityPluginBinding: ActivityPluginBinding) { override fun onReattachedToActivityForConfigChanges(activityPluginBinding: ActivityPluginBinding) {
Shared.activity = activityPluginBinding.activity Shared.activity = activityPluginBinding.activity
Shared.binding = activityPluginBinding
} }


override fun onDetachedFromActivity() { override fun onDetachedFromActivity() {
Shared.activity = null Shared.activity = null
Shared.binding = null
} }
inner class CameraRequestPermissionsListener : PluginRegistry.RequestPermissionsResultListener {
override fun onRequestPermissionsResult(id: Int, permissions: Array<String>, grantResults: IntArray): Boolean {
if (id == Shared.CAMERA_REQUEST_ID && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
return true
}
return false
}
}

} }

+ 40
- 25
android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt Просмотреть файл

@@ -4,30 +4,40 @@ import android.Manifest
import android.app.Activity import android.app.Activity
import android.app.Application import android.app.Application
import android.content.pm.PackageManager 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.hardware.Camera.CameraInfo
import android.os.Build import android.os.Build
import android.os.Bundle
import android.view.View
import com.google.zxing.BarcodeFormat import com.google.zxing.BarcodeFormat
import com.google.zxing.ResultPoint
import com.journeyapps.barcodescanner.BarcodeCallback import com.journeyapps.barcodescanner.BarcodeCallback
import com.journeyapps.barcodescanner.BarcodeResult import com.journeyapps.barcodescanner.BarcodeResult
import com.journeyapps.barcodescanner.BarcodeView import com.journeyapps.barcodescanner.BarcodeView
import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformView


class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<String, Any>) : class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<String, Any>) :
PlatformView, MethodChannel.MethodCallHandler {
PlatformView, MethodChannel.MethodCallHandler, PluginRegistry.RequestPermissionsResultListener {


private var isTorchOn: Boolean = false private var isTorchOn: Boolean = false
private var isPaused: Boolean = false private var isPaused: Boolean = false
private var barcodeView: BarcodeView? = null 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 { 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) channel.setMethodCallHandler(this)
Shared.activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { Shared.activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(p0: Activity) { override fun onActivityPaused(p0: Activity) {
@@ -92,8 +102,6 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
private fun flipCamera(result: MethodChannel.Result) { private fun flipCamera(result: MethodChannel.Result) {
if (barcodeView == null) { if (barcodeView == null) {
return barCodeViewNotSet(result) return barCodeViewNotSet(result)
} else if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
} }


barcodeView!!.pause() barcodeView!!.pause()
@@ -119,8 +127,6 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
private fun toggleFlash(result: MethodChannel.Result) { private fun toggleFlash(result: MethodChannel.Result) {
if (barcodeView == null) { if (barcodeView == null) {
return barCodeViewNotSet(result) return barCodeViewNotSet(result)
} else if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
} }


if (hasFlash()) { if (hasFlash()) {
@@ -136,10 +142,8 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
private fun pauseCamera(result: MethodChannel.Result) { private fun pauseCamera(result: MethodChannel.Result) {
if (barcodeView == null) { if (barcodeView == null) {
return barCodeViewNotSet(result) return barCodeViewNotSet(result)
} else if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
} }
if (barcodeView!!.isPreviewActive) { if (barcodeView!!.isPreviewActive) {
isPaused = true isPaused = true
barcodeView!!.pause() barcodeView!!.pause()
@@ -151,7 +155,7 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
if (barcodeView == null) { if (barcodeView == null) {
return barCodeViewNotSet(result) return barCodeViewNotSet(result)
} else if (!hasCameraPermission()) { } else if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
checkAndRequestPermission(result)
} }


if (!barcodeView!!.isPreviewActive) { if (!barcodeView!!.isPreviewActive) {
@@ -182,10 +186,6 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
result.error("404", "No barcode view found", null) result.error("404", "No barcode view found", null)
} }


private fun cameraPermissionNotSet(result: MethodChannel.Result) {
result.error("cameraPermission", " Permission denied to access the camera", null)
}

override fun getView(): View { override fun getView(): View {
return initBarCodeView().apply {}!! return initBarCodeView().apply {}!!
} }
@@ -196,16 +196,17 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
if (params["cameraFacing"] as Int == 1) { if (params["cameraFacing"] as Int == 1) {
barcodeView?.cameraSettings?.requestedCameraId = CameraInfo.CAMERA_FACING_FRONT barcodeView?.cameraSettings?.requestedCameraId = CameraInfo.CAMERA_FACING_FRONT
} }
barcodeView!!.resume()
} else {
if (hasCameraPermission()) {
barcodeView!!.resume()
} else {
checkAndRequestPermission(null)
}
} }
return barcodeView return barcodeView
} }


private fun startScan(arguments: List<Int>?, result: MethodChannel.Result) { private fun startScan(arguments: List<Int>?, result: MethodChannel.Result) {
if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
}

val allowedBarcodeTypes = mutableListOf<BarcodeFormat>() val allowedBarcodeTypes = mutableListOf<BarcodeFormat>()
try { try {
arguments?.forEach { arguments?.forEach {
@@ -254,7 +255,6 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St


private fun checkAndRequestPermission(result: MethodChannel.Result?) { private fun checkAndRequestPermission(result: MethodChannel.Result?) {
when { when {
hasCameraPermission() -> result?.success(true)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> { Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
Shared.activity?.requestPermissions( Shared.activity?.requestPermissions(
arrayOf(Manifest.permission.CAMERA), arrayOf(Manifest.permission.CAMERA),
@@ -265,5 +265,20 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
} }
} }
} }

override fun onRequestPermissionsResult( requestCode: Int,
permissions: Array<out String>?,
grantResults: IntArray): Boolean {

if (requestCode == Shared.CAMERA_REQUEST_ID && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
permissionGranted = true
channel.invokeMethod("onPermissionSet", true)
return true
}
permissionGranted = false
channel.invokeMethod("onPermissionSet", false)
return false
}

} }



+ 4
- 0
android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt Просмотреть файл

@@ -1,8 +1,12 @@
package net.touchcapture.qr.flutterqr package net.touchcapture.qr.flutterqr


import android.app.Activity import android.app.Activity
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.PluginRegistry


object Shared { object Shared {
const val CAMERA_REQUEST_ID = 513469796 const val CAMERA_REQUEST_ID = 513469796
var activity: Activity? = null var activity: Activity? = null
var binding: ActivityPluginBinding? = null
var registrar: PluginRegistry.Registrar? = null
} }

+ 6
- 3
lib/src/qr_code_scanner.dart Просмотреть файл

@@ -140,7 +140,7 @@ class _QRViewState extends State<QRView> {


// Start scan after creation of the view // Start scan after creation of the view
final controller = final controller =
QRViewController._(_channel, widget.key, widget.onPermissionSet)
QRViewController._(_channel, widget.key, widget.onPermissionSet, widget.cameraFacing)
.._startScan(widget.key, widget.overlay, widget.formatsAllowed); .._startScan(widget.key, widget.overlay, widget.formatsAllowed);


// Initialize the controller for controlling the QRView // Initialize the controller for controlling the QRView
@@ -166,8 +166,8 @@ class _QrCameraSettings {


class QRViewController { class QRViewController {
QRViewController._(MethodChannel channel, GlobalKey qrKey, QRViewController._(MethodChannel channel, GlobalKey qrKey,
PermissionSetCallback onPermissionSet)
: _channel = channel {
PermissionSetCallback onPermissionSet, CameraFacing cameraFacing)
: _channel = channel, _cameraFacing = cameraFacing{
_channel.setMethodCallHandler((call) async { _channel.setMethodCallHandler((call) async {
switch (call.method) { switch (call.method) {
case 'onRecognizeQR': case 'onRecognizeQR':
@@ -204,6 +204,7 @@ class QRViewController {
} }


final MethodChannel _channel; final MethodChannel _channel;
final CameraFacing _cameraFacing;
final StreamController<Barcode> _scanUpdateController = final StreamController<Barcode> _scanUpdateController =
StreamController<Barcode>(); StreamController<Barcode>();


@@ -232,6 +233,8 @@ class QRViewController {
/// Gets information about which camera is active. /// Gets information about which camera is active.
Future<CameraFacing> getCameraInfo() async { Future<CameraFacing> getCameraInfo() async {
try { try {
var cameraFacing = await _channel.invokeMethod('getCameraInfo') as int;
if (cameraFacing == -1) return _cameraFacing;
return CameraFacing return CameraFacing
.values[await _channel.invokeMethod('getCameraInfo') as int]; .values[await _channel.invokeMethod('getCameraInfo') as int];
} on PlatformException catch (e) { } on PlatformException catch (e) {


Загрузка…
Отмена
Сохранить