Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package biz.cunning.cunning_document_scanner

import android.Manifest
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.IntentSender
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import biz.cunning.cunning_document_scanner.fallback.DocumentScannerActivity
import biz.cunning.cunning_document_scanner.fallback.constants.DocumentScannerExtra
import com.google.mlkit.common.MlKitException
Expand All @@ -24,13 +27,16 @@ import io.flutter.plugin.common.PluginRegistry


/** CunningDocumentScannerPlugin */
class CunningDocumentScannerPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
class CunningDocumentScannerPlugin : FlutterPlugin, MethodCallHandler, ActivityAware,
PluginRegistry.RequestPermissionsResultListener {
private var delegate: PluginRegistry.ActivityResultListener? = null
private var binding: ActivityPluginBinding? = null
private var pendingResult: Result? = null
private lateinit var activity: Activity
private val START_DOCUMENT_ACTIVITY: Int = 0x362738
private val START_DOCUMENT_FB_ACTIVITY: Int = 0x362737
private val REQUEST_CAMERA_PERMISSION: Int = 0x362739
private var noOfPages: Int = 0


/// The MethodChannel that will the communication between Flutter and native Android
Expand All @@ -46,7 +52,7 @@ class CunningDocumentScannerPlugin : FlutterPlugin, MethodCallHandler, ActivityA

override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPictures") {
val noOfPages = call.argument<Int>("noOfPages") ?: 50;
noOfPages = call.argument<Int>("noOfPages") ?: 50;
val isGalleryImportAllowed = call.argument<Boolean>("isGalleryImportAllowed") ?: false;
this.pendingResult = result
startScan(noOfPages, isGalleryImportAllowed)
Expand All @@ -62,8 +68,8 @@ class CunningDocumentScannerPlugin : FlutterPlugin, MethodCallHandler, ActivityA

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
this.activity = binding.activity

addActivityResultListener(binding)
binding.addRequestPermissionsResultListener(this)
}

private fun addActivityResultListener(binding: ActivityPluginBinding) {
Expand Down Expand Up @@ -187,16 +193,28 @@ class CunningDocumentScannerPlugin : FlutterPlugin, MethodCallHandler, ActivityA
}
}.addOnFailureListener {
if (it is MlKitException) {
val intent = createDocumentScanIntent(noOfPages)
try {
ActivityCompat.startActivityForResult(
this.activity,
intent,
START_DOCUMENT_FB_ACTIVITY,
null
if (ContextCompat.checkSelfPermission(
activity,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
) {
val intent = createDocumentScanIntent(noOfPages)
try {
ActivityCompat.startActivityForResult(
this.activity,
intent,
START_DOCUMENT_FB_ACTIVITY,
null
)
} catch (e: ActivityNotFoundException) {
pendingResult?.error("ERROR", "FAILED TO START ACTIVITY", null)
}
} else {
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.CAMERA),
REQUEST_CAMERA_PERMISSION
)
} catch (e: ActivityNotFoundException) {
pendingResult?.error("ERROR", "FAILED TO START ACTIVITY", null)
}
} else {
pendingResult?.error("ERROR", "Failed to start document scanner Intent", null)
Expand All @@ -210,13 +228,45 @@ class CunningDocumentScannerPlugin : FlutterPlugin, MethodCallHandler, ActivityA

override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
addActivityResultListener(binding)
binding.addRequestPermissionsResultListener(this)
}

override fun onDetachedFromActivity() {
removeActivityResultListener()
binding?.removeRequestPermissionsResultListener(this)
}

private fun removeActivityResultListener() {
this.delegate?.let { this.binding?.removeActivityResultListener(it) }
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
): Boolean {
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
val intent = createDocumentScanIntent(noOfPages)
try {
ActivityCompat.startActivityForResult(
this.activity,
intent,
START_DOCUMENT_FB_ACTIVITY,
null
)
} catch (e: ActivityNotFoundException) {
pendingResult?.error("ERROR", "FAILED TO START ACTIVITY", null)
}
} else {
pendingResult?.error(
"CAMERA_PERMISSION_DENIED",
"Camera permission is required to scan documents.",
null
)
}
return true
}
return false
}
}
16 changes: 16 additions & 0 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.7"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
version: "1.4.0"
universal_io:
dependency: transitive
description:
name: universal_io
sha256: f63cbc48103236abf48e345e07a03ce5757ea86285ed313a6a032596ed9301e2
url: "https://pub.dev"
source: hosted
version: "2.3.1"
vector_math:
dependency: transitive
description:
Expand Down
21 changes: 11 additions & 10 deletions lib/src/cunning_document_scanner.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import 'dart:async';

import 'dart:io';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';

import 'exceptions.dart';
import 'ios_scanner_options.dart';
import '../cunning_document_scanner.dart';

/// A class that provides a simple way to scan documents.
class CunningDocumentScanner {
Expand All @@ -26,13 +25,15 @@ class CunningDocumentScanner {
bool isGalleryImportAllowed = false,
IosScannerOptions? iosScannerOptions,
}) async {
Map<Permission, PermissionStatus> statuses = await [
Permission.camera,
].request();
if (statuses.containsValue(PermissionStatus.denied) ||
statuses.containsValue(PermissionStatus.permanentlyDenied)) {
throw const CunningDocumentScannerException.permissionDenied(
'Camera permission not granted');
if (!Platform.isAndroid) {
Map<Permission, PermissionStatus> statuses = await [
Permission.camera,
].request();
if (statuses.containsValue(PermissionStatus.denied) ||
statuses.containsValue(PermissionStatus.permanentlyDenied)) {
throw const CunningDocumentScannerException.permissionDenied(
'Camera permission not granted');
}
}

final List<dynamic>? pictures = await _channel.invokeMethod('getPictures', {
Expand Down