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

Merge pull request #255 from juliuscanute/252-unknown-exception

252 unknown exception
flutter-beta
Julian Steenbakker 5 лет назад
committed by GitHub
Родитель
Сommit
da000715fa
Не найден GPG ключ соответствующий данной подписи Идентификатор GPG ключа: 4AEE18F83AFDEB23
7 измененных файлов: 255 добавлений и 239 удалений
  1. +1
    -0
      .gitignore
  2. +6
    -10
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/FlutterQrPlugin.kt
  3. +67
    -46
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt
  4. +4
    -0
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/Shared.kt
  5. +118
    -178
      ios/Classes/QRView.swift
  6. +30
    -0
      lib/src/lifecycle_event_handler.dart
  7. +29
    -5
      lib/src/qr_code_scanner.dart

+ 1
- 0
.gitignore Просмотреть файл

@@ -79,6 +79,7 @@ unlinked_spec.ds
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/.symlinks/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata


+ 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) {
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<String>, grantResults: IntArray): Boolean {
if (id == Shared.CAMERA_REQUEST_ID && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
return true
}
return false
}
}

}

+ 67
- 46
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<String, Any>) :
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<St
if (barcodeView == null) {
return barCodeViewNotSet(result)
} else if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
}
checkAndRequestPermission(result)
} else {
barcodeView!!.pause()
val settings = barcodeView!!.cameraSettings

if(settings.requestedCameraId == CameraInfo.CAMERA_FACING_FRONT)
settings.requestedCameraId = CameraInfo.CAMERA_FACING_BACK
else
settings.requestedCameraId = CameraInfo.CAMERA_FACING_FRONT

barcodeView!!.pause()
val settings = barcodeView!!.cameraSettings
barcodeView!!.cameraSettings = settings
barcodeView!!.resume()
result.success(settings.requestedCameraId)
}

if(settings.requestedCameraId == CameraInfo.CAMERA_FACING_FRONT)
settings.requestedCameraId = CameraInfo.CAMERA_FACING_BACK
else
settings.requestedCameraId = CameraInfo.CAMERA_FACING_FRONT

barcodeView!!.cameraSettings = settings
barcodeView!!.resume()
result.success(settings.requestedCameraId)
}

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

if (hasFlash()) {
@@ -137,28 +147,28 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
if (barcodeView == null) {
return barCodeViewNotSet(result)
} else if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
}

if (barcodeView!!.isPreviewActive) {
isPaused = true
barcodeView!!.pause()
checkAndRequestPermission(result)
} else {
if (barcodeView!!.isPreviewActive) {
isPaused = true
barcodeView!!.pause()
}
result.success(true)
}
result.success(true)
}

private fun resumeCamera(result: MethodChannel.Result) {
if (barcodeView == null) {
return barCodeViewNotSet(result)
} else if (!hasCameraPermission()) {
return cameraPermissionNotSet(result)
}

if (!barcodeView!!.isPreviewActive) {
isPaused = false
barcodeView!!.resume()
checkAndRequestPermission(result)
} else {
if (!barcodeView!!.isPreviewActive) {
isPaused = false
barcodeView!!.resume()
}
result.success(true)
}
result.success(true)
}

private fun hasFlash(): Boolean {
@@ -182,10 +192,6 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
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 {
return initBarCodeView().apply {}!!
}
@@ -196,16 +202,17 @@ class QRView(messenger: BinaryMessenger, id: Int, private val params: HashMap<St
if (params["cameraFacing"] as Int == 1) {
barcodeView?.cameraSettings?.requestedCameraId = CameraInfo.CAMERA_FACING_FRONT
}
barcodeView!!.resume()
} else {
if (hasCameraPermission()) {
if (!isPaused) barcodeView!!.resume()
} else {
checkAndRequestPermission(null)
}
}
return barcodeView
}

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

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

private fun checkAndRequestPermission(result: MethodChannel.Result?) {
when {
hasCameraPermission() -> 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<St
}
}
}

override fun onRequestPermissionsResult( requestCode: Int,
permissions: Array<out String>?,
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
}

}


+ 4
- 0
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
}

+ 118
- 178
ios/Classes/QRView.swift Просмотреть файл

@@ -32,6 +32,7 @@ public class QRView:NSObject,FlutterPlatformView {
public init(withFrame frame: CGRect, withRegistrar registrar: FlutterPluginRegistrar, withId id: Int64, params: Dictionary<String, Any>){
self.registrar = registrar
previewView = UIView(frame: frame)
scanner = MTBBarcodeScanner(previewView: previewView)
cameraFacing = MTBCamera.init(rawValue: UInt(Int(params["cameraFacing"] as! Double))) ?? MTBCamera.back
channel = FlutterMethodChannel(name: "net.touchcapture.qr.flutterqr/qrview_\(id)", binaryMessenger: registrar.messenger())
}
@@ -77,226 +78,165 @@ public class QRView:NSObject,FlutterPlatformView {
return previewView
}
func setDimensions(_ result: @escaping FlutterResult, width: Double, height: Double, scanArea: Double, scanAreaOffset: Double) -> Void {
func requestPermissions(_ result: @escaping FlutterResult) {
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
// self?.channel.invokeMethod("onPermissionSet", arguments: true)
// First set the size of the preview area.
self.previewView.frame = CGRect(x: 0, y: 0, width: width, height: height)
// Then set the size of the scan area.
let midX = self.view().bounds.midX
let midY = self.view().bounds.midY
// Check if the scanner is already created.
if let sc: MTBBarcodeScanner = self.scanner {
if let previewLayer = sc.previewLayer {
previewLayer.frame = self.previewView.bounds;
}
if (scanArea != 0) {
sc.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)
// Set offset if provided.
if (scanAreaOffset != 0) {
sc.scanRect = sc.scanRect.offsetBy(dx: 0, dy: CGFloat(scanAreaOffset))
}
}
} else {
// Create a scanner view if it doesn't exist yet.
self.scanner = MTBBarcodeScanner(previewView: self.previewView)
if (scanArea != 0) {
self.scanner?.didStartScanningBlock = {
self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)
// Set offset if provided.
if (scanAreaOffset != 0) {
self.scanner?.scanRect = (self.scanner?.scanRect.offsetBy(dx: 0, dy: CGFloat(scanAreaOffset)))!
}
}
}
}
return result(width)
self.channel.invokeMethod("onPermissionSet", arguments: true)
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
}
})
}
func startScan(_ arguments: Array<Int>, _ result: @escaping FlutterResult) -> Void {
if (scanner == nil) {
scanner = MTBBarcodeScanner(previewView: previewView)
func setDimensions(_ result: @escaping FlutterResult, width: Double, height: Double, scanArea: Double, scanAreaOffset: Double) {
// First ask for permission
requestPermissions(result)
// Then set the size of the preview area.
self.previewView.frame = CGRect(x: 0, y: 0, width: width, height: height)
// Then set the size of the scan area.
let midX = self.view().bounds.midX
let midY = self.view().bounds.midY

// Set the size of the preview.
if let previewLayer = self.scanner?.previewLayer {
previewLayer.frame = self.previewView.bounds
}

// Set scanArea if provided.
if (scanArea != 0) {
self.scanner?.didStartScanningBlock = {
self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)

// Set offset if provided.
if (scanAreaOffset != 0) {
self.scanner?.scanRect = (self.scanner?.scanRect.offsetBy(dx: 0, dy: CGFloat(scanAreaOffset)))!
}
}
}
return result(width)
}
func startScan(_ arguments: Array<Int>, _ result: @escaping FlutterResult) {
// Check for allowed barcodes
var allowedBarcodeTypes: Array<AVMetadataObject.ObjectType> = []
arguments.forEach { arg in
allowedBarcodeTypes.append( QRCodeTypes[arg]!)
}
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
self.channel.invokeMethod("onPermissionSet", arguments: true)
do {
try self.scanner?.startScanning(with: self.cameraFacing, resultBlock: { [weak self] codes in
if let codes = codes {
for code in codes {
var typeString: String;
switch(code.type) {
case AVMetadataObject.ObjectType.aztec:
typeString = "AZTEC"
case AVMetadataObject.ObjectType.code39:
typeString = "CODE_39"
case AVMetadataObject.ObjectType.code93:
typeString = "CODE_93"
case AVMetadataObject.ObjectType.code128:
typeString = "CODE_128"
case AVMetadataObject.ObjectType.dataMatrix:
typeString = "DATA_MATRIX"
case AVMetadataObject.ObjectType.ean8:
typeString = "EAN_8"
case AVMetadataObject.ObjectType.ean13:
typeString = "EAN_13"
case AVMetadataObject.ObjectType.itf14:
typeString = "ITF"
case AVMetadataObject.ObjectType.pdf417:
typeString = "PDF_417"
case AVMetadataObject.ObjectType.qr:
typeString = "QR_CODE"
case AVMetadataObject.ObjectType.upce:
typeString = "UPC_E"
default:
return
}
guard let stringValue = code.stringValue else { continue }
let result = ["code": stringValue, "type": typeString]
if allowedBarcodeTypes.count == 0 || allowedBarcodeTypes.contains(code.type) {
self?.channel.invokeMethod("onRecognizeQR", arguments: result)
}
}
do {
try self.scanner?.startScanning(with: self.cameraFacing, resultBlock: { [weak self] codes in
if let codes = codes {
for code in codes {
var typeString: String;
switch(code.type) {
case AVMetadataObject.ObjectType.aztec:
typeString = "AZTEC"
case AVMetadataObject.ObjectType.code39:
typeString = "CODE_39"
case AVMetadataObject.ObjectType.code93:
typeString = "CODE_93"
case AVMetadataObject.ObjectType.code128:
typeString = "CODE_128"
case AVMetadataObject.ObjectType.dataMatrix:
typeString = "DATA_MATRIX"
case AVMetadataObject.ObjectType.ean8:
typeString = "EAN_8"
case AVMetadataObject.ObjectType.ean13:
typeString = "EAN_13"
case AVMetadataObject.ObjectType.itf14:
typeString = "ITF"
case AVMetadataObject.ObjectType.pdf417:
typeString = "PDF_417"
case AVMetadataObject.ObjectType.qr:
typeString = "QR_CODE"
case AVMetadataObject.ObjectType.upce:
typeString = "UPC_E"
default:
return
}
})
} catch {
let error = FlutterError(code: "unknown-error", message: "Unable to start scanning", details: nil)
return result(error)
guard let stringValue = code.stringValue else { continue }
let result = ["code": stringValue, "type": typeString]
if allowedBarcodeTypes.count == 0 || allowedBarcodeTypes.contains(code.type) {
self?.channel.invokeMethod("onRecognizeQR", arguments: result)
}
}
}
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
}
})
})
} catch {
let error = FlutterError(code: "unknown-error", message: "Unable to start scanning", details: nil)
return result(error)
}
}
func stopCamera(_ result: @escaping FlutterResult){
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
if let sc: MTBBarcodeScanner = self.scanner {
if sc.isScanning() {
sc.stopScanning()
}
}
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
func stopCamera(_ result: @escaping FlutterResult) {
if let sc: MTBBarcodeScanner = self.scanner {
if sc.isScanning() {
sc.stopScanning()
}
})
}
}
func getCameraInfo(_ result: @escaping FlutterResult) -> Void {
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
if let sc: MTBBarcodeScanner = self.scanner {
result(sc.camera.rawValue)
} else {
let error = FlutterError(code: "cameraInformationError", message: "Could not get camera information", details: nil)
result(error)
}
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
}
})
func getCameraInfo(_ result: @escaping FlutterResult) {
result(self.cameraFacing.rawValue)
}
func flipCamera(_ result: @escaping FlutterResult){
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
if let sc: MTBBarcodeScanner = self.scanner {
if sc.hasOppositeCamera() {
sc.flipCamera()
}
return result(sc.camera.rawValue)
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
func flipCamera(_ result: @escaping FlutterResult) {
if let sc: MTBBarcodeScanner = self.scanner {
if sc.hasOppositeCamera() {
sc.flipCamera()
self.cameraFacing = sc.camera
}
})
return result(sc.camera.rawValue)
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
}
func getFlashInfo(_ result: @escaping FlutterResult) -> Void {
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
if let sc: MTBBarcodeScanner = self.scanner {
result(sc.torchMode.rawValue != 0)
} else {
let error = FlutterError(code: "cameraInformationError", message: "Could not get flash information", details: nil)
result(error)
}
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
}
})
func getFlashInfo(_ result: @escaping FlutterResult) {
if let sc: MTBBarcodeScanner = self.scanner {
result(sc.torchMode.rawValue != 0)
} else {
let error = FlutterError(code: "cameraInformationError", message: "Could not get flash information", details: nil)
result(error)
}
}
func toggleFlash(_ result: @escaping FlutterResult){
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
if let sc: MTBBarcodeScanner = self.scanner {
if sc.hasTorch() {
sc.toggleTorch()
return result(sc.torchMode == MTBTorchMode(rawValue: 1))
}
return result(FlutterError(code: "404", message: "This device doesn\'t support flash", details: nil))
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
if let sc: MTBBarcodeScanner = self.scanner {
if sc.hasTorch() {
sc.toggleTorch()
return result(sc.torchMode == MTBTorchMode(rawValue: 1))
}
})
return result(FlutterError(code: "404", message: "This device doesn\'t support flash", details: nil))
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
}
func pauseCamera(_ result: @escaping FlutterResult) {
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
if let sc: MTBBarcodeScanner = self.scanner {
if sc.isScanning() {
sc.freezeCapture()
}
return result(true)
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
if let sc: MTBBarcodeScanner = self.scanner {
if sc.isScanning() {
sc.freezeCapture()
}
})
return result(true)
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
}
func resumeCamera(_ result: @escaping FlutterResult) {
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
if let sc: MTBBarcodeScanner = self.scanner {
if !sc.isScanning() {
sc.unfreezeCapture()
}
return result(true)
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
} else {
return result(FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil))
if let sc: MTBBarcodeScanner = self.scanner {
if !sc.isScanning() {
sc.unfreezeCapture()
}
})
return result(true)
}
return result(FlutterError(code: "404", message: "No barcode scanner found", details: nil))
}

func getSystemFeatures(_ result: @escaping FlutterResult) -> Void {
func getSystemFeatures(_ result: @escaping FlutterResult) {
if let sc: MTBBarcodeScanner = scanner {
var hasBackCameraVar = false
var hasFrontCameraVar = false


+ 30
- 0
lib/src/lifecycle_event_handler.dart Просмотреть файл

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

class LifecycleEventHandler extends WidgetsBindingObserver {
LifecycleEventHandler({
this.resumeCallBack,
this.suspendingCallBack,
});

final AsyncCallback resumeCallBack;
final AsyncCallback suspendingCallBack;

@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
switch (state) {
case AppLifecycleState.resumed:
if (resumeCallBack != null) {
await resumeCallBack();
}
break;
case AppLifecycleState.inactive:
case AppLifecycleState.paused:
case AppLifecycleState.detached:
if (suspendingCallBack != null) {
await suspendingCallBack();
}
break;
}
}
}

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

@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'lifecycle_event_handler.dart';
import 'qr_scanner_overlay_shape.dart';
import 'types/barcode.dart';
import 'types/barcode_format.dart';
@@ -58,6 +59,19 @@ class QRView extends StatefulWidget {
class _QRViewState extends State<QRView> {
var _channel;

@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(LifecycleEventHandler(
resumeCallBack: () async => {
if (_channel != null)
{
QRViewController.updateDimensions(widget.key, _channel,
overlay: widget.overlay)
}
}));
}

@override
Widget build(BuildContext context) {
return NotificationListener(
@@ -75,6 +89,7 @@ class _QRViewState extends State<QRView> {
QRViewController.updateDimensions(widget.key, _channel,
overlay: widget.overlay)
});

return false;
}

@@ -124,9 +139,9 @@ class _QRViewState extends State<QRView> {
_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) {
@@ -151,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':
@@ -189,11 +205,13 @@ class QRViewController {
}

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

Stream<Barcode> get scannedDataStream => _scanUpdateController.stream;

static bool _firstRun = true;
SystemFeatures _features;
bool _hasPermissions;

@@ -216,6 +234,8 @@ class QRViewController {
/// Gets information about which camera is active.
Future<CameraFacing> 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) {
@@ -299,6 +319,10 @@ class QRViewController {
static Future<void> updateDimensions(GlobalKey key, MethodChannel channel,
{QrScannerOverlayShape overlay}) async {
if (defaultTargetPlatform == TargetPlatform.iOS) {
if (_firstRun) {
_firstRun = false;
await Future.delayed(Duration(milliseconds: 300));
}
final RenderBox renderBox = key.currentContext.findRenderObject();
try {
await channel.invokeMethod('setDimensions', {


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