From 35f6c0439e53c04f21de46fdd954f12aba26dd7c Mon Sep 17 00:00:00 2001
From: Serhii Chaban <>
Date: Wed, 25 Mar 2026 15:43:16 +0100
Subject: [PATCH 01/11] add document enhancer classic example module
---
classic-components-example/build.gradle | 2 +-
.../document-enhancer/build.gradle | 47 ++++
.../src/main/AndroidManifest.xml | 31 +++
.../scanbot/example/DocumentCameraActivity.kt | 256 ++++++++++++++++++
.../io/scanbot/example/ExampleApplication.kt | 55 ++++
.../java/io/scanbot/example/MainActivity.kt | 119 ++++++++
.../src/main/res/layout/activity_camera.xml | 59 ++++
.../src/main/res/layout/activity_main.xml | 45 +++
.../src/main/res/menu/menu_main.xml | 6 +
.../src/main/res/mipmap-hdpi/icon.png | Bin 0 -> 3418 bytes
.../src/main/res/mipmap-mdpi/icon.png | Bin 0 -> 2206 bytes
.../src/main/res/mipmap-xhdpi/icon.png | Bin 0 -> 4842 bytes
.../src/main/res/mipmap-xxhdpi/icon.png | Bin 0 -> 7718 bytes
.../src/main/res/values-w820dp/dimens.xml | 6 +
.../src/main/res/values/dimens.xml | 5 +
.../src/main/res/values/strings.xml | 6 +
.../src/main/res/values/styles.xml | 8 +
.../settings.gradle.kts | 1 +
18 files changed, 645 insertions(+), 1 deletion(-)
create mode 100644 classic-components-example/document-enhancer/build.gradle
create mode 100755 classic-components-example/document-enhancer/src/main/AndroidManifest.xml
create mode 100755 classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
create mode 100755 classic-components-example/document-enhancer/src/main/java/io/scanbot/example/ExampleApplication.kt
create mode 100644 classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt
create mode 100755 classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml
create mode 100755 classic-components-example/document-enhancer/src/main/res/layout/activity_main.xml
create mode 100755 classic-components-example/document-enhancer/src/main/res/menu/menu_main.xml
create mode 100755 classic-components-example/document-enhancer/src/main/res/mipmap-hdpi/icon.png
create mode 100755 classic-components-example/document-enhancer/src/main/res/mipmap-mdpi/icon.png
create mode 100755 classic-components-example/document-enhancer/src/main/res/mipmap-xhdpi/icon.png
create mode 100755 classic-components-example/document-enhancer/src/main/res/mipmap-xxhdpi/icon.png
create mode 100755 classic-components-example/document-enhancer/src/main/res/values-w820dp/dimens.xml
create mode 100755 classic-components-example/document-enhancer/src/main/res/values/dimens.xml
create mode 100755 classic-components-example/document-enhancer/src/main/res/values/strings.xml
create mode 100755 classic-components-example/document-enhancer/src/main/res/values/styles.xml
diff --git a/classic-components-example/build.gradle b/classic-components-example/build.gradle
index c3b0b6fa..d953f471 100644
--- a/classic-components-example/build.gradle
+++ b/classic-components-example/build.gradle
@@ -15,7 +15,7 @@ allprojects {
jvmToolchainVersion = 17
- scanbotSdkVersion = "8.1.0"
+ scanbotSdkVersion = "9.0.0.99-STAGING-SNAPSHOT"
androidCoreKtxVersion = "1.6.0"
constraintLayoutVersion = "2.0.4"
diff --git a/classic-components-example/document-enhancer/build.gradle b/classic-components-example/document-enhancer/build.gradle
new file mode 100644
index 00000000..c3414bb5
--- /dev/null
+++ b/classic-components-example/document-enhancer/build.gradle
@@ -0,0 +1,47 @@
+plugins {
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+}
+
+android {
+ namespace = project.ext.submodulesNamespace
+ compileSdk = project.ext.compileSdkVersion
+
+ defaultConfig {
+ applicationId = project.ext.exampleAppId
+ minSdk = project.ext.minSdkVersion
+ targetSdk = project.ext.targetSdkVersion
+ versionCode = 1
+ versionName = "1.0"
+ }
+
+ buildTypes {
+ named("debug") {
+ // set this to `false` to allow debugging and run a "non-release" build
+ minifyEnabled = false
+ debuggable = true
+ }
+ }
+
+ kotlin {
+ jvmToolchain(project.ext.jvmToolchainVersion)
+ }
+
+ packagingOptions {
+ exclude 'META-INF/LICENSE.txt'
+ exclude 'META-INF/LICENSE'
+ exclude 'META-INF/NOTICE.txt'
+ exclude 'META-INF/NOTICE'
+ exclude 'META-INF/DEPENDENCIES'
+ }
+
+ buildFeatures {
+ viewBinding = true
+ }
+}
+
+dependencies {
+ implementation(project(":common"))
+ implementation("io.scanbot:sdk-package-1:${project.ext.scanbotSdkVersion}")
+ implementation("androidx.appcompat:appcompat:${project.ext.androidxAppcompatVersion}")
+}
diff --git a/classic-components-example/document-enhancer/src/main/AndroidManifest.xml b/classic-components-example/document-enhancer/src/main/AndroidManifest.xml
new file mode 100755
index 00000000..4d1192e4
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/AndroidManifest.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
new file mode 100755
index 00000000..04db5f27
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
@@ -0,0 +1,256 @@
+package io.scanbot.example
+
+import android.Manifest
+import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.Color
+import android.graphics.Matrix
+import android.os.Bundle
+import android.view.View
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
+import androidx.core.view.WindowCompat
+import io.scanbot.common.onSuccess
+
+
+import io.scanbot.example.common.applyEdgeToEdge
+import io.scanbot.sdk.ScanbotSDK
+import io.scanbot.sdk.camera.CaptureInfo
+import io.scanbot.sdk.document.DocumentScannerFrameHandler
+import io.scanbot.sdk.document.ui.DocumentScannerView
+import io.scanbot.sdk.document.ui.IDocumentScannerViewCallback
+import io.scanbot.sdk.documentscanner.DocumentDetectionStatus
+import io.scanbot.sdk.documentscanner.DocumentEnhancer
+import io.scanbot.sdk.documentscanner.DocumentScanner
+import io.scanbot.sdk.documentscanner.DocumentStraighteningMode
+import io.scanbot.sdk.documentscanner.DocumentStraighteningParameters
+import io.scanbot.sdk.geometry.AspectRatio
+import io.scanbot.sdk.image.ImageRef
+import io.scanbot.sdk.process.ImageProcessor
+import io.scanbot.sdk.ui.camera.ShutterButton
+import io.scanbot.sdk.ui.view.base.configuration.CameraOrientationMode
+
+class DocumentCameraActivity : AppCompatActivity() {
+
+ private var lastUserGuidanceHintTs = 0L
+ private var flashEnabled = false
+ private var autoSnappingEnabled = true
+ private val ignoreOrientationMistmatch = true
+
+ private lateinit var documentScannerView: DocumentScannerView
+
+ private lateinit var resultView: ImageView
+ private lateinit var userGuidanceHint: TextView
+ private lateinit var autoSnappingToggleButton: Button
+ private lateinit var shutterButton: ShutterButton
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
+
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_camera)
+ askPermission()
+ supportActionBar!!.hide()
+ applyEdgeToEdge(findViewById(R.id.root_view))
+
+ val scanbotSdk = ScanbotSDK(this)
+
+ documentScannerView = findViewById(R.id.document_scanner_view)
+
+ resultView = findViewById(R.id.result) as ImageView
+ val documentEnhancer = scanbotSdk.createDocumentEnhancer()
+ scanbotSdk.createDocumentScanner().onSuccess { documentScanner ->
+
+ documentScannerView.apply {
+ initCamera()
+ initScanningBehavior(
+ documentScanner,
+ { result, frame ->
+ // Here you are continuously notified about document scanning results.
+ // For example, you can show a user guidance text depending on the current scanning status.
+ result.onSuccess { data ->
+ userGuidanceHint.post {
+ showUserGuidance(data.status)
+ }
+ }
+ false // typically you need to return false
+ },
+ object : IDocumentScannerViewCallback {
+ override fun onCameraOpen() {
+ // In this example we demonstrate how to lock the orientation of the UI (Activity)
+ // as well as the orientation of the taken picture to portrait.
+ documentScannerView.cameraConfiguration.setCameraOrientationMode(
+ CameraOrientationMode.PORTRAIT
+ )
+
+ documentScannerView.viewController.useFlash(flashEnabled)
+ }
+
+ override fun onPictureTaken(image: ImageRef, captureInfo: CaptureInfo) {
+ documentEnhancer.onSuccess { documentEnhancer ->
+ processPictureTaken(image, documentEnhancer)
+ }
+
+
+ // continue scanning
+ documentScannerView.postDelayed({
+ documentScannerView.viewController.startPreview()
+ }, 1000)
+ }
+ }
+ )
+
+ // See https://docs.scanbot.io/document-scanner-sdk/android/features/document-scanner/using-scanbot-camera-view/#preview-mode
+ // cameraConfiguration.setCameraPreviewMode(io.scanbot.sdk.camera.CameraPreviewMode.FIT_IN)
+ }
+ }
+
+
+
+ documentScannerView.polygonConfiguration.apply {
+ setPolygonFillColor(POLYGON_FILL_COLOR)
+ setPolygonFillColorOK(POLYGON_FILL_COLOR_OK)
+ }
+
+
+
+ documentScannerView.viewController.apply {
+ setAcceptedAngleScore(60.0)
+ setAcceptedSizeScore(75.0)
+ setIgnoreOrientationMismatch(ignoreOrientationMistmatch)
+
+ // Please note: https://docs.scanbot.io/document-scanner-sdk/android/features/document-scanner/autosnapping/#sensitivity
+ setAutoSnappingSensitivity(0.85f)
+ }
+
+ userGuidanceHint = findViewById(R.id.userGuidanceHint)
+
+ shutterButton = findViewById(R.id.shutterButton)
+ shutterButton.setOnClickListener { documentScannerView.viewController.takePicture(false) }
+ shutterButton.visibility = View.VISIBLE
+
+ findViewById(R.id.flashToggle).setOnClickListener {
+ flashEnabled = !flashEnabled
+ documentScannerView.viewController.useFlash(flashEnabled)
+ }
+
+ autoSnappingToggleButton = findViewById(R.id.autoSnappingToggle)
+ autoSnappingToggleButton.setOnClickListener {
+ autoSnappingEnabled = !autoSnappingEnabled
+ setAutoSnapEnabled(autoSnappingEnabled)
+ }
+ autoSnappingToggleButton.post { setAutoSnapEnabled(autoSnappingEnabled) }
+ }
+
+ private fun askPermission() {
+ if (ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission.CAMERA
+ ) != PackageManager.PERMISSION_GRANTED
+ ) {
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 999)
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ documentScannerView.viewController.onResume()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ documentScannerView.viewController.onPause()
+ }
+
+ private fun showUserGuidance(result: DocumentDetectionStatus) {
+ if (!autoSnappingEnabled) {
+ return
+ }
+ if (System.currentTimeMillis() - lastUserGuidanceHintTs < 400) {
+ return
+ }
+
+ when (result) {
+ DocumentDetectionStatus.OK -> {
+ userGuidanceHint.text = "Don't move"
+ userGuidanceHint.visibility = View.VISIBLE
+ }
+
+ DocumentDetectionStatus.OK_BUT_TOO_SMALL -> {
+ userGuidanceHint.text = "Move closer"
+ userGuidanceHint.visibility = View.VISIBLE
+ }
+
+ DocumentDetectionStatus.OK_BUT_BAD_ANGLES -> {
+ userGuidanceHint.text = "Perspective"
+ userGuidanceHint.visibility = View.VISIBLE
+ }
+
+ DocumentDetectionStatus.ERROR_NOTHING_DETECTED -> {
+ userGuidanceHint.text = "No Document"
+ userGuidanceHint.visibility = View.VISIBLE
+ }
+
+ DocumentDetectionStatus.ERROR_TOO_NOISY -> {
+ userGuidanceHint.text = "Background too noisy"
+ userGuidanceHint.visibility = View.VISIBLE
+ }
+
+ DocumentDetectionStatus.OK_BUT_BAD_ASPECT_RATIO -> {
+ if (ignoreOrientationMistmatch) {
+ userGuidanceHint.text = "Don't move"
+ } else {
+ userGuidanceHint.text = "Wrong aspect ratio.\nRotate your device."
+ }
+ userGuidanceHint.visibility = View.VISIBLE
+ }
+
+ DocumentDetectionStatus.ERROR_TOO_DARK -> {
+ userGuidanceHint.text = "Poor light"
+ userGuidanceHint.visibility = View.VISIBLE
+ }
+
+ else -> userGuidanceHint.visibility = View.GONE
+ }
+ lastUserGuidanceHintTs = System.currentTimeMillis()
+ }
+
+ private fun processPictureTaken(image: ImageRef, documentEnhancer: DocumentEnhancer) {
+ // STRAIGHTEN SCANNED IMAGE ASSUMING DOCUMENT IS BENT
+ // Run document enhancer unwarping on original image:
+ val result = documentEnhancer.straighten(image, DocumentStraighteningParameters().apply {
+ straighteningMode = DocumentStraighteningMode.STRAIGHTEN
+ // uncomment if you want wo set specific aspect ratios for documents
+ // aspectRatios = listOf(AspectRatio(29.0, 21.0))
+ }).getOrNull()
+
+ resultView.post { resultView.setImageBitmap(result?.straightenedImage?.toBitmap()?.getOrNull()) }
+ }
+
+ private fun setAutoSnapEnabled(enabled: Boolean) {
+ documentScannerView.viewController.apply {
+ autoSnappingEnabled = enabled
+ isFrameProcessingEnabled = enabled
+ }
+ documentScannerView.polygonConfiguration.setPolygonViewVisible(enabled)
+
+ autoSnappingToggleButton.text = "Automatic ${if (enabled) "ON" else "OFF"}"
+ if (enabled) {
+ shutterButton.showAutoButton()
+ } else {
+ shutterButton.showManualButton()
+ userGuidanceHint.visibility = View.GONE
+ }
+ }
+
+ companion object {
+ private val POLYGON_FILL_COLOR = Color.parseColor("#55ff0000")
+ private val POLYGON_FILL_COLOR_OK = Color.parseColor("#4400ff00")
+ }
+}
diff --git a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/ExampleApplication.kt b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/ExampleApplication.kt
new file mode 100755
index 00000000..d366bec5
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/ExampleApplication.kt
@@ -0,0 +1,55 @@
+package io.scanbot.example
+
+import android.app.Application
+import io.scanbot.sdk.ScanbotSDK
+import io.scanbot.sdk.ScanbotSDKInitializer
+import io.scanbot.sdk.util.log.LoggerProvider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlin.coroutines.CoroutineContext
+
+class ExampleApplication : Application(), CoroutineScope {
+
+ private var job: Job = Job()
+ override val coroutineContext: CoroutineContext
+ get() = Dispatchers.IO + job
+
+ /*
+ * TODO 1/2: Add the Scanbot SDK license key here.
+ * Please note: The Scanbot SDK will run without a license key for one minute per session!
+ * After the trial period is over all Scanbot SDK functions as well as the UI components will stop working.
+ * You can get an unrestricted "no-strings-attached" 30 day trial license key for free.
+ * Please submit the trial license form (https://scanbot.io/trial/) on our website by using
+ * the app identifier "io.scanbot.example.sdk.android" of this example app.
+ */
+ val licenseKey = ""
+
+ override fun onCreate() {
+ super.onCreate()
+
+ ScanbotSDKInitializer()
+ .withLogging(true)
+ // TODO 2/2: Enable the Scanbot SDK license key
+ //.license(this, licenseKey)
+ .licenseErrorHandler { status, feature, statusMessage ->
+ LoggerProvider.logger.d("ExampleApplication", "+++> License status: ${status.name}. Status message: $statusMessage")
+ LoggerProvider.logger.d("ExampleApplication", "+++> Feature not available: ${feature.name}")
+ }
+ //.sdkFilesDirectory(this, getExternalFilesDir(null)!!)
+ .initialize(this)
+
+ LoggerProvider.logger.d("ExampleApplication", "Scanbot SDK was initialized")
+
+ val licenseInfo = ScanbotSDK(this).licenseInfo
+ LoggerProvider.logger.d("ExampleApplication", "License status: ${licenseInfo.status}")
+ LoggerProvider.logger.d("ExampleApplication", "License isValid: ${licenseInfo.isValid}")
+ LoggerProvider.logger.d("ExampleApplication", "License expirationDate: ${licenseInfo.expirationDateString}")
+
+ launch {
+ // Clear all previously created documents in storage
+ ScanbotSDK(this@ExampleApplication).documentApi.deleteAllDocuments()
+ }
+ }
+}
diff --git a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt
new file mode 100644
index 00000000..ddb5fe21
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt
@@ -0,0 +1,119 @@
+package io.scanbot.example
+
+import android.Manifest
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import androidx.activity.result.PickVisualMediaRequest
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import io.scanbot.common.onSuccess
+
+
+import io.scanbot.example.common.Const
+import io.scanbot.example.common.applyEdgeToEdge
+import io.scanbot.example.common.showToast
+import io.scanbot.example.databinding.ActivityMainBinding
+import io.scanbot.sdk.ScanbotSDK
+import io.scanbot.sdk.documentscanner.DocumentStraighteningMode
+import io.scanbot.sdk.documentscanner.DocumentStraighteningParameters
+import io.scanbot.sdk.image.ImageRef
+import io.scanbot.sdk.util.PolygonHelper
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
+Please, check the official documentation for more details:
+Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
+ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
+ */
+
+class MainActivity : AppCompatActivity() {
+
+ private val scanbotSdk: ScanbotSDK by lazy { ScanbotSDK(this) }
+
+ private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
+
+ private val requestCameraLauncher =
+ registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
+ if (isGranted) {
+ startActivity(Intent(this, DocumentCameraActivity::class.java))
+ } else {
+ this@MainActivity.showToast("Camera permission is required to run this example!")
+ }
+ }
+
+ private val selectGalleryImageResultLauncher =
+ registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
+ if (!scanbotSdk.licenseInfo.isValid) {
+ this@MainActivity.showToast("1-minute trial license has expired!")
+ Log.e(Const.LOG_TAG, "1-minute trial license has expired!")
+ return@registerForActivityResult
+ }
+
+ if (uri == null) {
+ showToast("Error obtaining selected image!")
+ Log.e(Const.LOG_TAG, "Error obtaining selected image!")
+ return@registerForActivityResult
+ }
+
+ lifecycleScope.launch { processImage(uri) }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(binding.root)
+ supportActionBar?.hide()
+ applyEdgeToEdge(findViewById(R.id.root_view))
+
+ binding.showDocScannerBtn.setOnClickListener {
+ requestCameraLauncher.launch(Manifest.permission.CAMERA)
+ }
+
+ binding.importImage.setOnClickListener {
+ selectGalleryImageResultLauncher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
+ }
+ }
+
+ /** Imports a selected image as original image and performs auto document scanning on it. */
+ private suspend fun processImage(uri: Uri) {
+ withContext(Dispatchers.Main) {
+ binding.progressBar.visibility = View.VISIBLE
+ this@MainActivity.showToast("Importing page...")
+ }
+
+ val documentImage = withContext(Dispatchers.Default) {
+ // load the selected image
+ val image = contentResolver.openInputStream(uri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ } ?: throw IllegalStateException("Cannot open input stream from URI: $uri")
+
+ // create a new Page object with given image as original image:
+ val document = scanbotSdk.documentApi.createDocument()
+ .getOrNull() //can be handled with .getOrThrow() if needed
+ val page =
+ document?.addPage(image)?.getOrNull() //can be handled with .getOrThrow() if needed
+
+ // run document scanning on the page image:
+ page?.apply(newStraighteningParameters = DocumentStraighteningParameters().apply {
+ straighteningMode = DocumentStraighteningMode.STRAIGHTEN
+ // uncomment if you want wo set specific aspect ratios for documents
+ // aspectRatios = listOf(AspectRatio(29.0, 21.0))
+ })
+ page?.documentImage
+ }
+
+ withContext(Dispatchers.Main) {
+ binding.progressBar.visibility = View.GONE
+
+ // present cropped page image:
+ binding.importResultImage.setImageBitmap(documentImage)
+ binding.importResultImage.visibility = View.VISIBLE
+ }
+ }
+}
diff --git a/classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml b/classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml
new file mode 100755
index 00000000..ea4ca5ab
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/classic-components-example/document-enhancer/src/main/res/layout/activity_main.xml b/classic-components-example/document-enhancer/src/main/res/layout/activity_main.xml
new file mode 100755
index 00000000..638005e1
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/res/layout/activity_main.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/classic-components-example/document-enhancer/src/main/res/menu/menu_main.xml b/classic-components-example/document-enhancer/src/main/res/menu/menu_main.xml
new file mode 100755
index 00000000..8847389d
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/res/menu/menu_main.xml
@@ -0,0 +1,6 @@
+
diff --git a/classic-components-example/document-enhancer/src/main/res/mipmap-hdpi/icon.png b/classic-components-example/document-enhancer/src/main/res/mipmap-hdpi/icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..cde69bcccec65160d92116f20ffce4fce0b5245c
GIT binary patch
literal 3418
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
literal 0
HcmV?d00001
diff --git a/classic-components-example/document-enhancer/src/main/res/mipmap-xhdpi/icon.png b/classic-components-example/document-enhancer/src/main/res/mipmap-xhdpi/icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..bfa42f0e7b91d006d22352c9ff2f134e504e3c1d
GIT binary patch
literal 4842
zcmZ{oXE5C1x5t0WvTCfdv7&7fy$d2l*k#q|U5FAbL??P!61}%ovaIM)mL!5G(V|6J
zAtDH(OY|Du^}l!K&fFLG%sJ2JIp@rG=9y>Ci)Wq~U2RobsvA@Q0MM$dq4lq5{hy#9
zzgp+B{O(-=?1<7r0l>Q?>N6X%s~lmgrmqD6fjj_!c?AF`S0&6U06Z51fWOuNAe#jM
z%pSN#J-Mp}`ICpL=qp~?u~Jj$6(~K_%)9}Bn(;pY0&;M00H9x2N23h=CpR7kr8A9X
zU%oh4-E@i!Ac}P+&%vOPQ3warO9l!SCN)ixGW54Jsh!`>*aU)#&Mg7;#O_6xd5%I6
zneGSZL3Kn-4B^>#T7pVaIHs3^PY-N^v1!W=%gzfioIWosZ!BN?_M)OOux&6HCyyMf
z3ToZ@_h75A33KyC!T)-zYC-bp`@^1n;w3~N+vQ0#4V7!f|JPMlWWJ@+Tg~8>1$GzLlHGuxS)w&NAF*&Y;ef`T^w4HP7GK%6UA8(
z{&ALM(%!w2U7WFWwq8v4H3|0cOjdt7$JLh(;U8VcTG;R-vmR7?21nA?@@b+XPgJbD
z*Y@v&dTqo5Bcp-dIQQ4@?-m{=7>`LZ{g4jvo$CE&(+7(rp#WShT9&9y>V#ikmXFau03*^{&d(AId0Jg9G;tc7K_{ivzBjqHuJx08cx<8U`z2JjtOK3(
zvtuduBHha>D&iu#))5RKXm>(|$m=_;e?7ZveYy=J$3wjL>xPCte-MDcVW<;ng`nf=
z9);CVVZjI-&UcSAlhDB{%0v$wPd=w6MBwsVEaV!hw~8G(rs`lw@|#AAHbyA&(I-7Y
zFE&1iIGORsaskMqSYfX33U%&17oTszdHPjr&Sx(`IQzoccST*}!cU!ZnJ+~duBM6f
z{Lf8PITt%uWZ
zTY09Jm5t<2+Un~yC-%DYEP>c-7?=+|reXO4Cd^neCQ{&aP@yODLN8}TQAJ8ogsnkb
zM~O>~3&n6d+ee`V_m@$6V`^ltL&?uwt|-afgd7BQ9Kz|g{B@K#qQ#$o4ut`9lQsYfHofccNoqE+`V
zQ&UXP{X4=&Z16O_wCk9SFBQPKyu?<&B2zDVhI6%B$12c^SfcRYIIv!s1&r|8;xw5t
zF~*-cE@V$vaB;*+91`CiN~1l8w${?~3Uy#c|D{S$I?
zb!9y)DbLJ3pZ>!*+j=n@kOLTMr-T2>Hj^I~lml-a26UP1_?#!5S_a&v
zeZ86(21wU0)4(h&W0iE*HaDlw+-LngX=}es#X$u*1v9>qR&qUGfADc7yz6$WN`cx9
zzB#!5&F%AK=ed|-eV6kb;R>Atp2Rk=g3lU6(IVEP3!;0YNAmqz=x|-mE&8u5W+zo7
z-QfwS6uzp9K4wC-Te-1~u?zPb{RjjIVoL1bQ=-HK_a_muB>&3I
z*{e{sE_sI$CzyK-x>7abBc+uIZf?#e8;K_JtJexgpFEBMq92+Fm0j*DziUMras`o=
zTzby8_XjyCYHeE@q&Q_7x?i|V9XY?MnSK;cLV?k>vf?!N87)gFPc9#XB?p)bEWGs$
zH>f$8?U7In{9@vsd%#sY5u!I$)g^%ZyutkNBBJ0eHQeiR5!DlQbYZJ-@09;c?IP7A
zx>P=t*xm1rOqr@ec>|ziw@3e$ymK7YSXtafMk30i?>>1lC>LLK1~JV1n6EJUGJT{6
zWP4A(129xkvDP09j<3#1$T6j6$mZaZ@vqUBBM4Pi!H>U8xvy`bkdSNTGVcfkk&y8%
z=2nfA@3kEaubZ{1nwTV1gUReza>QX%_d}x&2`jE*6JZN{HZtXSr{{6v6`r47MoA~R
zejyMpeYbJ$F4*+?*=Fm7E`S_rUC0v+dHTlj{JnkW-_eRa#9V`9o!8yv_+|lB4*+p1
zUI-t)X$J{RRfSrvh80$OW_Wwp>`4*iBr|oodPt*&A9!SO(x|)UgtVvETLuLZ<-vRp
z&zAubgm&J8Pt647V?Qxh;`f6E#Zgx5^2XV($YMV7;Jn2kx6aJn8T>bo?5&;GM4O~|
zj>ksV0U}b}wDHW`pgO$L@Hjy2`a)T}s@(0#?y3n
zj;yjD76HU&*s!+k5!G4<3{hKah#gBz8HZ6v`bmURyDi(wJ!C7+F%bKnRD4=q{(Fl0
zOp*r}F`6~6HHBtq$afFuXsGAk58!e?O(W$*+3?R|cDO88<$~pg^|GRHN}yml3WkbL
zzSH*jmpY=`g#ZX?_XT`>-`INZ#d__BJ)Ho^&ww+h+3>y8Z&T*EI!mtgEqiofJ@5&E
z6M6a}b255hCw6SFJ4q(==QN6CUE3GYnfjFNE+x8T(+J!C!?v~Sbh`Sl_0CJ;vvXsP
z5oZRiPM-Vz{tK(sJM~GI&VRbBOd0JZmGzqDrr9|?iPT(qD#M*RYb$>gZi*i)xGMD`NbmZt;ky&FR_2+YqpmFb`8b`ry;}D+y&WpUNd%3cfuUsb8
z7)1$Zw?bm@O6J1CY9UMrle_BUM<$pL=YI^DCz~!@p25hE&g62n{j$?UsyYjf#LH~b
z_n!l6Z(J9daalVYSlA?%=mfp(!e+Hk%%oh`t%0`F`KR*b-Zb=7SdtDS4`&&S@A)f>bKC7vmRWwT2
zH}k+2Hd7@>jiHwz^GrOeU8Y#h?YK8>a*vJ#s|8-uX_IYp*$9Y=W_Edf%$V4>w;C3h
z&>ZDGavV7UA@0QIQV$&?Z_*)vj{Q%z&(IW!b-!MVDGytRb4DJJV)(@WG|MbhwCx!2
z6QJMkl^4ju9ou8Xjb*pv=Hm8DwYsw23wZqQFUI)4wCMjPB6o8yG7@Sn^5%fmaFnfD
zSxp8R-L({J{p&cR7)lY+PA9#8Bx87;mB$zXCW8VDh0&g#@Z@lktyArvzgOn&-zerA
zVEa9h{EYvWOukwVUGWUB5xr4{nh}a*$v^~OEasKj)~HyP`YqeLUdN~f!r;0dV7uho
zX)iSYE&VG67^NbcP5F*SIE@T#=NVjJ1=!Mn!^oeCg1L
z?lv_%(ZEe%z*pGM<(UG{eF1T(#PMw}$n0aihzGoJAP^UceQMiBuE8Y`lZ|sF2_h_6
zQw*b*=;2Ey_Flpfgsr4PimZ~8G~R(vU}^Zxmri5)l?N>M_dWyCsjZw<+a
zqjmL0l*}PXNGUOh)YxP>;ENiJTd|S^%BARx9D~%7x?F6u4K(Bx0`KK2mianotlX^9
z3z?MW7Coqy^ol0pH)Z3+GwU|Lyuj#7HCrqs#01ZF&KqEg!olHc$O#Wn>Ok_k2`zoD
z+LYbxxVMf<(d2OkPIm8Xn>bwFsF6m8@i7PA$sdK~ZA4|ic?k*q2j1YQ>&A
zjPO%H@H(h`t+irQqx+e)ll9LGmdvr1zXV;WTi}KCa>K82n90s|K
zi`X}C*Vb12p?C-sp5maVDP5{&5$E^k6~BuJ^UxZaM=o+@(LXBWChJUJ|KEckEJTZL
zI2K&Nd$U65YoF3_J6+&YU4uKGMq2W6ZQ%BG>4HnIM?V;;Ohes{`Ucs56ue^7@D7;4
z+EsFB)a_(%K6jhxND}n!UBTuF3wfrvll|mp7)3wi&2?LW$+PJ>2)2C-6c@O&lKAn
zOm=$x*dn&dI8!QCb(ul|t3oDY^MjHqxl~lp{p@#C%Od-U4y@NQ4=`U!YjK$7b=V}D
z%?E40*f8DVrvV2nV>`Z3f5yuz^??$#3qR#q6F($w>kmKK`x21VmX=9kb^+cPdBY2l
zGkIZSf%C+`2nj^)j
zo}g}v;5{nk<>%xj-2OqDbJ3S`7|tQWqdvJdgiL{1=w0!qS9$A`w9Qm7>N0Y*Ma%P_
zr@fR4>5u{mKwgZ33Xs$RD6(tcVH~Mas-87Fd^6M6iuV^_o$~ql+!eBIw$U)lzl`q9
z=L6zVsZzi0IIW=DT&ES9HajKhb5lz4yQxT-NRBLv_=2sn7WFX&Wp6Y!&}P+%`!A;s
zrCwXO3}jrdA7mB`h~N~HT64TM{R$lNj*~ekqSP^n9P~z;P
zWPlRPz0h6za8-P>!ARb+A1-r>8VF*xhrGa8W6J$p*wy`ULrD$CmYV7Gt^scLydQWbo7XN-o9X1i7;l+J_8Ncu
zc=EX&dg`GRo4==cz2d_Rz28oLS`Suf6OCp~f{0-aQ`t5YZ=!CAMc6-RZw#}A%;s44
znf2`6gcgm=0SezTH9h+JzeR3Lcm;8?*@+?FDfguK^9)z(Z`I!RKrSAI?H~4et6GTkz07Qgq4B6%Q*8Y0yPc4x
z8(^YwtZjYIeOvVLey#>@$UzIciJ#x0pJLFg=8UaZv%-&?Yzp7gWNIo_x^(d75=x2c
zv|LQ`HrKP(8TqFxTiP5gdT2>aTN0S7XW*pilASS$UkJ2*n+==D)0mgTGxv43t61fr
z47GkfMnD-zSH@|mZ26r*d3WEtr+l-xH@L}BM)~ThoMvKqGw=Ifc}BdkL$^wC}=(XSf4YpG;sA9#OSJf)V=rs#Wq$?Wj+nTlu$YXn
yn3SQon5>kvtkl(BT2@T#Mvca!|08g9w{vm``2PjZHg=b<1c17-HkzPl9sXa)&-Ts$
literal 0
HcmV?d00001
diff --git a/classic-components-example/document-enhancer/src/main/res/mipmap-xxhdpi/icon.png b/classic-components-example/document-enhancer/src/main/res/mipmap-xxhdpi/icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..324e72cdd7480cb983fa1bcc7ce686e51ef87fe7
GIT binary patch
literal 7718
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
literal 0
HcmV?d00001
diff --git a/classic-components-example/document-enhancer/src/main/res/values-w820dp/dimens.xml b/classic-components-example/document-enhancer/src/main/res/values-w820dp/dimens.xml
new file mode 100755
index 00000000..63fc8164
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/classic-components-example/document-enhancer/src/main/res/values/dimens.xml b/classic-components-example/document-enhancer/src/main/res/values/dimens.xml
new file mode 100755
index 00000000..47c82246
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
diff --git a/classic-components-example/document-enhancer/src/main/res/values/strings.xml b/classic-components-example/document-enhancer/src/main/res/values/strings.xml
new file mode 100755
index 00000000..21db9902
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/res/values/strings.xml
@@ -0,0 +1,6 @@
+
+ Scanbot SDK Example
+
+ Hello world!
+ Settings
+
diff --git a/classic-components-example/document-enhancer/src/main/res/values/styles.xml b/classic-components-example/document-enhancer/src/main/res/values/styles.xml
new file mode 100755
index 00000000..766ab993
--- /dev/null
+++ b/classic-components-example/document-enhancer/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/classic-components-example/settings.gradle.kts b/classic-components-example/settings.gradle.kts
index 36996292..4cc318dd 100755
--- a/classic-components-example/settings.gradle.kts
+++ b/classic-components-example/settings.gradle.kts
@@ -26,6 +26,7 @@ include(
":edit-polygon-view",
":camera-fragment",
":document-scanner",
+ ":document-enhancer",
":barcode-scanner",
":mrz-scanner",
":mc-scanner",
From 46705c03808bad2c6f43771a8146d049217b7c3d Mon Sep 17 00:00:00 2001
From: Serhii Chaban <>
Date: Wed, 25 Mar 2026 15:43:30 +0100
Subject: [PATCH 02/11] add document enhancer public doc snippet
---
.../app/build.gradle | 2 +-
.../DocumentDetectionSnippet.kt | 2 +-
.../DocumentQualityCheckSnippet.kt | 6 +-
.../DocumentStraighteningSnippet.kt | 95 +++++++++++++++++++
4 files changed, 100 insertions(+), 5 deletions(-)
create mode 100644 document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt
diff --git a/document-scanner-ready-to-use-ui-example/app/build.gradle b/document-scanner-ready-to-use-ui-example/app/build.gradle
index c42b895b..74baec39 100644
--- a/document-scanner-ready-to-use-ui-example/app/build.gradle
+++ b/document-scanner-ready-to-use-ui-example/app/build.gradle
@@ -39,7 +39,7 @@ android {
}
}
-def scanbotSdkVersion = "8.1.0"
+def scanbotSdkVersion = "9.0.0.99-STAGING-SNAPSHOT"
dependencies {
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentDetectionSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentDetectionSnippet.kt
index 3d5c380e..af9af00e 100644
--- a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentDetectionSnippet.kt
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentDetectionSnippet.kt
@@ -44,7 +44,7 @@ class DocumentDetectionSnippet : AppCompatActivity() {
.forEach { image ->
if (image == null) {
Log.e(
- "StandaloneCropSnippet",
+ "DocumentDetectionSnippet",
"Failed to load image from URI"
)
return@forEach
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt
index a2164c38..a02232f7 100644
--- a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt
@@ -43,14 +43,14 @@ class DocumentQualityCheckSnippet : AppCompatActivity() {
.forEach { image ->
if (image == null) {
Log.e(
- "StandaloneCropSnippet",
+ "QualityCheckSnippet",
"Failed to load image from URI"
)
return@forEach
}
document.addPage(image)
}
- startCropping(document)
+ startDqa(document)
}
}
}
@@ -62,7 +62,7 @@ class DocumentQualityCheckSnippet : AppCompatActivity() {
// Create a document detector instance
val qualityAnalyzer = scanbotSDK.createDocumentQualityAnalyzer().getOrNull()
- fun startCropping(document: Document) {
+ fun startDqa(document: Document) {
document.pages.forEach { page ->
// Run quality check on the created page
val documentQuality =
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt
new file mode 100644
index 00000000..4ff9d972
--- /dev/null
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt
@@ -0,0 +1,95 @@
+package com.example.scanbot.doc_code_snippet
+
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import com.example.scanbot.utils.getUrisFromGalleryResult
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import io.scanbot.common.onSuccess
+import io.scanbot.page.PageImageSource
+import io.scanbot.sdk.ScanbotSDK
+import io.scanbot.sdk.docprocessing.Document
+import io.scanbot.sdk.documentscanner.DocumentStraighteningMode
+import io.scanbot.sdk.documentscanner.DocumentStraighteningParameters
+import io.scanbot.sdk.geometry.AspectRatio
+import io.scanbot.sdk.util.isDefault
+import io.scanbot.sdk.util.toImageRef
+
+
+class DocumentStraighteningSnippet : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ // In the real application, you should call this function on button click
+ importImagesFromLibrary()
+ }
+
+ private val scanbotSDK = ScanbotSDK(this@DocumentStraighteningSnippet)
+ private val context = this
+
+ private val pictureForDocDetectionResult =
+ this.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
+ if (activityResult.resultCode == Activity.RESULT_OK) {
+ activityResult.data?.let { imagePickerResult ->
+ lifecycleScope.launch {
+ withContext(Dispatchers.Default) {
+ scanbotSDK.documentApi.createDocument().onSuccess { document ->
+ getUrisFromGalleryResult(imagePickerResult)
+ .asSequence() // process images one by one instead of collecting the whole list - less memory consumption
+ .map { it.toImageRef(contentResolver).getOrNull() }
+ .forEach { image ->
+ if (image == null) {
+ Log.e(
+ "StraighteningSnippet",
+ "Failed to load image from URI"
+ )
+ return@forEach
+ }
+ document.addPage(image)
+ }
+ startStraightening(document)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // @Tag("Direct Document straightening on page")
+ fun startStraightening(document: Document) {
+ document.pages.forEach { page ->
+ page.apply(
+ newStraighteningParameters = DocumentStraighteningParameters(
+ straighteningMode = DocumentStraighteningMode.STRAIGHTEN,
+ // Expected aspect ratios for the documents. Comment if unknown.
+ aspectRatios = listOf(AspectRatio(3.0, 4.0))
+ )
+ )
+ // Set the source of the page to IMPORTED if needs
+ page.source = PageImageSource.IMPORTED
+ }
+ }
+ // @EndTag("Direct Document detection on page")
+
+ private fun importImagesFromLibrary() {
+ val imageIntent = Intent()
+ imageIntent.type = "image/*"
+ imageIntent.action = Intent.ACTION_GET_CONTENT
+ imageIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, false)
+ imageIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
+ imageIntent.putExtra(
+ Intent.EXTRA_MIME_TYPES,
+ arrayOf("image/jpeg", "image/png", "image/webp", "image/heic")
+ )
+ pictureForDocDetectionResult.launch(Intent.createChooser(imageIntent, "Select Picture"))
+ }
+
+}
+
From e5a24d4ccf9003ff5728f40ed49076d656f8b520 Mon Sep 17 00:00:00 2001
From: Serhii Chaban <>
Date: Fri, 27 Mar 2026 17:05:49 +0100
Subject: [PATCH 03/11] add image enhancer snippets
---
.../DocumentStraighteningSnippet.kt | 2 +-
.../ImageStraighteningSnippet.kt | 93 +++++++++++++++++++
2 files changed, 94 insertions(+), 1 deletion(-)
create mode 100644 document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageStraighteningSnippet.kt
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt
index 4ff9d972..25aa77db 100644
--- a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentStraighteningSnippet.kt
@@ -76,7 +76,7 @@ class DocumentStraighteningSnippet : AppCompatActivity() {
page.source = PageImageSource.IMPORTED
}
}
- // @EndTag("Direct Document detection on page")
+ // @EndTag("Direct Document straightening on page")
private fun importImagesFromLibrary() {
val imageIntent = Intent()
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageStraighteningSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageStraighteningSnippet.kt
new file mode 100644
index 00000000..3e66fe4e
--- /dev/null
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageStraighteningSnippet.kt
@@ -0,0 +1,93 @@
+package com.example.scanbot.doc_code_snippet
+
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import com.example.scanbot.utils.getUrisFromGalleryResult
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import io.scanbot.common.onFailure
+import io.scanbot.common.onSuccess
+import io.scanbot.page.PageImageSource
+import io.scanbot.sdk.ScanbotSDK
+import io.scanbot.sdk.docprocessing.Document
+import io.scanbot.sdk.documentscanner.DocumentStraighteningMode
+import io.scanbot.sdk.documentscanner.DocumentStraighteningParameters
+import io.scanbot.sdk.geometry.AspectRatio
+import io.scanbot.sdk.image.ImageRef
+import io.scanbot.sdk.util.isDefault
+import io.scanbot.sdk.util.toImageRef
+
+
+class ImageStraighteningSnippet : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ // In the real application, you should call this function on button click
+ importImagesFromLibrary()
+ }
+
+ private val scanbotSDK = ScanbotSDK(this@ImageStraighteningSnippet)
+ private val context = this
+
+ private val pictureForDocDetectionResult =
+ this.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
+ if (activityResult.resultCode == RESULT_OK) {
+ activityResult.data?.let { imagePickerResult ->
+ lifecycleScope.launch {
+ withContext(Dispatchers.Default) {
+ getUrisFromGalleryResult(imagePickerResult)
+ .asSequence() // process images one by one instead of collecting the whole list - less memory consumption
+ .map { it.toImageRef(contentResolver).getOrNull() }
+ .forEach { image ->
+ if (image == null) {
+ Log.e(
+ "StraighteningSnippet",
+ "Failed to load image from URI"
+ )
+ return@forEach
+ }
+ startStraightening(image)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // @Tag("Direct Document straightening on image")
+ fun startStraightening(imageRef: ImageRef) {
+ scanbotSDK.createDocumentEnhancer().onSuccess { enhancer ->
+ val params = DocumentStraighteningParameters(
+ straighteningMode = DocumentStraighteningMode.STRAIGHTEN,
+ // Expected aspect ratios for the documents. Comment if unknown.
+ aspectRatios = listOf(AspectRatio(3.0, 4.0))
+ )
+ enhancer.straighten(imageRef, params).onSuccess { straightenedImage ->
+ // straightenedImage is an ImageRef of the straightened image, you can display it in the UI or save it to storage
+ }
+ }
+ }
+ // @EndTag("Direct Document straightening on image")
+
+ private fun importImagesFromLibrary() {
+ val imageIntent = Intent()
+ imageIntent.type = "image/*"
+ imageIntent.action = Intent.ACTION_GET_CONTENT
+ imageIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, false)
+ imageIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
+ imageIntent.putExtra(
+ Intent.EXTRA_MIME_TYPES,
+ arrayOf("image/jpeg", "image/png", "image/webp", "image/heic")
+ )
+ pictureForDocDetectionResult.launch(Intent.createChooser(imageIntent, "Select Picture"))
+ }
+
+}
+
From 12c4ce2384c3c4f728c2edc0b5ac19616ef725b9 Mon Sep 17 00:00:00 2001
From: Serhii Chaban <>
Date: Tue, 31 Mar 2026 13:20:15 +0200
Subject: [PATCH 04/11] cleanup
---
.../scanbot/example/DocumentCameraActivity.kt | 81 ++-----------------
.../src/main/res/layout/activity_camera.xml | 16 ----
2 files changed, 7 insertions(+), 90 deletions(-)
diff --git a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
index 04db5f27..1b62844d 100755
--- a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
+++ b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
@@ -75,20 +75,11 @@ class DocumentCameraActivity : AppCompatActivity() {
// Here you are continuously notified about document scanning results.
// For example, you can show a user guidance text depending on the current scanning status.
result.onSuccess { data ->
- userGuidanceHint.post {
- showUserGuidance(data.status)
- }
}
false // typically you need to return false
},
object : IDocumentScannerViewCallback {
override fun onCameraOpen() {
- // In this example we demonstrate how to lock the orientation of the UI (Activity)
- // as well as the orientation of the taken picture to portrait.
- documentScannerView.cameraConfiguration.setCameraOrientationMode(
- CameraOrientationMode.PORTRAIT
- )
-
documentScannerView.viewController.useFlash(flashEnabled)
}
@@ -105,21 +96,14 @@ class DocumentCameraActivity : AppCompatActivity() {
}
}
)
-
- // See https://docs.scanbot.io/document-scanner-sdk/android/features/document-scanner/using-scanbot-camera-view/#preview-mode
- // cameraConfiguration.setCameraPreviewMode(io.scanbot.sdk.camera.CameraPreviewMode.FIT_IN)
}
}
-
-
documentScannerView.polygonConfiguration.apply {
setPolygonFillColor(POLYGON_FILL_COLOR)
setPolygonFillColorOK(POLYGON_FILL_COLOR_OK)
}
-
-
-
+
documentScannerView.viewController.apply {
setAcceptedAngleScore(60.0)
setAcceptedSizeScore(75.0)
@@ -129,8 +113,6 @@ class DocumentCameraActivity : AppCompatActivity() {
setAutoSnappingSensitivity(0.85f)
}
- userGuidanceHint = findViewById(R.id.userGuidanceHint)
-
shutterButton = findViewById(R.id.shutterButton)
shutterButton.setOnClickListener { documentScannerView.viewController.takePicture(false) }
shutterButton.visibility = View.VISIBLE
@@ -168,69 +150,20 @@ class DocumentCameraActivity : AppCompatActivity() {
documentScannerView.viewController.onPause()
}
- private fun showUserGuidance(result: DocumentDetectionStatus) {
- if (!autoSnappingEnabled) {
- return
- }
- if (System.currentTimeMillis() - lastUserGuidanceHintTs < 400) {
- return
- }
-
- when (result) {
- DocumentDetectionStatus.OK -> {
- userGuidanceHint.text = "Don't move"
- userGuidanceHint.visibility = View.VISIBLE
- }
-
- DocumentDetectionStatus.OK_BUT_TOO_SMALL -> {
- userGuidanceHint.text = "Move closer"
- userGuidanceHint.visibility = View.VISIBLE
- }
-
- DocumentDetectionStatus.OK_BUT_BAD_ANGLES -> {
- userGuidanceHint.text = "Perspective"
- userGuidanceHint.visibility = View.VISIBLE
- }
-
- DocumentDetectionStatus.ERROR_NOTHING_DETECTED -> {
- userGuidanceHint.text = "No Document"
- userGuidanceHint.visibility = View.VISIBLE
- }
-
- DocumentDetectionStatus.ERROR_TOO_NOISY -> {
- userGuidanceHint.text = "Background too noisy"
- userGuidanceHint.visibility = View.VISIBLE
- }
-
- DocumentDetectionStatus.OK_BUT_BAD_ASPECT_RATIO -> {
- if (ignoreOrientationMistmatch) {
- userGuidanceHint.text = "Don't move"
- } else {
- userGuidanceHint.text = "Wrong aspect ratio.\nRotate your device."
- }
- userGuidanceHint.visibility = View.VISIBLE
- }
-
- DocumentDetectionStatus.ERROR_TOO_DARK -> {
- userGuidanceHint.text = "Poor light"
- userGuidanceHint.visibility = View.VISIBLE
- }
-
- else -> userGuidanceHint.visibility = View.GONE
- }
- lastUserGuidanceHintTs = System.currentTimeMillis()
- }
-
private fun processPictureTaken(image: ImageRef, documentEnhancer: DocumentEnhancer) {
// STRAIGHTEN SCANNED IMAGE ASSUMING DOCUMENT IS BENT
// Run document enhancer unwarping on original image:
val result = documentEnhancer.straighten(image, DocumentStraighteningParameters().apply {
straighteningMode = DocumentStraighteningMode.STRAIGHTEN
// uncomment if you want wo set specific aspect ratios for documents
- // aspectRatios = listOf(AspectRatio(29.0, 21.0))
+ // aspectRatios = listOf(AspectRatio(29.0, 21.0))
}).getOrNull()
- resultView.post { resultView.setImageBitmap(result?.straightenedImage?.toBitmap()?.getOrNull()) }
+ resultView.post {
+ resultView.setImageBitmap(
+ result?.straightenedImage?.toBitmap()?.getOrNull()
+ )
+ }
}
private fun setAutoSnapEnabled(enabled: Boolean) {
diff --git a/classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml b/classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml
index ea4ca5ab..f059f4db 100755
--- a/classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml
+++ b/classic-components-example/document-enhancer/src/main/res/layout/activity_camera.xml
@@ -25,22 +25,6 @@
android:layout_gravity="top|start"
android:text="Automatic" />
-
-
Date: Tue, 31 Mar 2026 13:22:12 +0200
Subject: [PATCH 05/11] cleanup
---
.../src/main/java/io/scanbot/example/DocumentCameraActivity.kt | 2 +-
.../src/main/java/io/scanbot/example/MainActivity.kt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
index 1b62844d..3800e7dc 100755
--- a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
+++ b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
@@ -103,7 +103,7 @@ class DocumentCameraActivity : AppCompatActivity() {
setPolygonFillColor(POLYGON_FILL_COLOR)
setPolygonFillColorOK(POLYGON_FILL_COLOR_OK)
}
-
+
documentScannerView.viewController.apply {
setAcceptedAngleScore(60.0)
setAcceptedSizeScore(75.0)
diff --git a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt
index ddb5fe21..c54eeb4e 100644
--- a/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/document-enhancer/src/main/java/io/scanbot/example/MainActivity.kt
@@ -27,7 +27,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
+Ths example uses new SDK APIs presented in Scanbot SDK v.8.x.x
Please, check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
From 95601288cf5b7c0155a75e01d13e08feaef3c046 Mon Sep 17 00:00:00 2001
From: Serhii Chaban <>
Date: Wed, 1 Apr 2026 13:42:38 +0200
Subject: [PATCH 06/11] Add rtu enhancer config snippet
---
.../app/build.gradle | 2 +-
.../rtu_ui/DocumentStraighteningSnippet.kt | 66 +++++++++++++++++++
2 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/DocumentStraighteningSnippet.kt
diff --git a/document-scanner-ready-to-use-ui-example/app/build.gradle b/document-scanner-ready-to-use-ui-example/app/build.gradle
index 74baec39..4b4f4c38 100644
--- a/document-scanner-ready-to-use-ui-example/app/build.gradle
+++ b/document-scanner-ready-to-use-ui-example/app/build.gradle
@@ -39,7 +39,7 @@ android {
}
}
-def scanbotSdkVersion = "9.0.0.99-STAGING-SNAPSHOT"
+def scanbotSdkVersion = "9.0.0.100-STAGING-SNAPSHOT"
dependencies {
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/DocumentStraighteningSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/DocumentStraighteningSnippet.kt
new file mode 100644
index 00000000..0e1487fc
--- /dev/null
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/DocumentStraighteningSnippet.kt
@@ -0,0 +1,66 @@
+package com.example.scanbot.doc_code_snippet.rtu_ui
+
+
+import android.os.Bundle
+import androidx.activity.result.ActivityResultLauncher
+import androidx.appcompat.app.AppCompatActivity
+import io.scanbot.common.Result
+import io.scanbot.common.onCancellation
+import io.scanbot.common.onFailure
+import io.scanbot.common.onSuccess
+import io.scanbot.sdk.documentscanner.DocumentStraighteningMode
+import io.scanbot.sdk.documentscanner.DocumentStraighteningParameters
+import io.scanbot.sdk.geometry.AspectRatio
+
+import io.scanbot.sdk.ui_v2.document.DocumentScannerActivity
+import io.scanbot.sdk.ui_v2.document.configuration.DocumentScanningFlow
+
+
+class DocumentStraighteningSnippet : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ // In the real application, you should call this function on button click
+ startScanning()
+ }
+
+ private val context = this
+ private val documentScannerResult: ActivityResultLauncher by lazy {
+ registerForActivityResult(DocumentScannerActivity.ResultContract()) { result ->
+ result.onSuccess { document ->
+ // Handle the scanned document.
+ }.onCancellation {
+ // Indicates that the cancel button was tapped. Or screen is closed by other reason.
+ }.onFailure {
+ when (it) {
+ is Result.InvalidLicenseError -> {
+ // indicate that the Scanbot SDK license is invalid
+ }
+
+ else -> {
+ // Handle other errors
+ }
+ }
+ }
+ }
+ }
+
+ // @Tag("Set Document Straightening Parameters")
+ fun startScanning() {
+ // Create the default configuration object.
+ val configuration = DocumentScanningFlow().apply {
+ // Set document straightening parameters for the scanning screen.
+ outputSettings.apply {
+ straighteningParameters = DocumentStraighteningParameters(
+ straighteningMode = DocumentStraighteningMode.STRAIGHTEN,
+ // Expected aspect ratios for the documents. Comment if unknown.
+ aspectRatios = listOf(AspectRatio(3.0, 4.0))
+ )
+ }
+ }
+ // Start the recognizer activity.
+ documentScannerResult.launch(configuration)
+ }
+ // @EndTag("Set Document Straightening Parameters")
+
+}
+
From de1fddbc4ef2096d880be8bb7a1fb328f9206976 Mon Sep 17 00:00:00 2001
From: Serhii Chaban <>
Date: Wed, 1 Apr 2026 16:12:32 +0200
Subject: [PATCH 07/11] fix compiling
---
.../doc_code_snippet/DocumentQualityCheckSnippet.kt | 11 +++++------
.../doc_code_snippet/ImageQualityCheckSnippet.kt | 11 +++++------
.../rtu_ui/AcknowledgeScreenSnippet.kt | 10 +++-------
3 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt
index a02232f7..71cd214a 100644
--- a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/DocumentQualityCheckSnippet.kt
@@ -16,6 +16,7 @@ import io.scanbot.common.onSuccess
import io.scanbot.sdk.ScanbotSDK
import io.scanbot.sdk.docprocessing.Document
import io.scanbot.sdk.documentqualityanalyzer.DocumentQuality
+import io.scanbot.sdk.documentqualityanalyzer.DocumentQualityAssessment
import io.scanbot.sdk.util.toImageRef
@@ -76,13 +77,11 @@ class DocumentQualityCheckSnippet : AppCompatActivity() {
// @EndTag("Analyze the quality of a document image")
// Print the result.
- fun printResult(quality: DocumentQuality?) {
+ fun printResult(quality: DocumentQualityAssessment?) {
when (quality) {
- DocumentQuality.VERY_POOR -> print("The quality of the document is very poor")
- DocumentQuality.POOR -> print("The quality of the document is poor")
- DocumentQuality.REASONABLE -> print("The quality of the document is reasonable")
- DocumentQuality.GOOD -> print("The quality of the document is good")
- DocumentQuality.EXCELLENT -> print("The quality of the document is excellent")
+ DocumentQualityAssessment.ACCEPTABLE -> print("The quality of the document is good enough for processing.")
+ DocumentQualityAssessment.UNACCEPTABLE -> print("The quality of the document is not good enough for processing.")
+ DocumentQualityAssessment.UNCERTAIN -> print("The quality of the document is uncertain. It may be good enough for processing, but there is a risk that the result will not be good.")
else -> print("No document was found")
}
}
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageQualityCheckSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageQualityCheckSnippet.kt
index 12d0605b..2d4a7684 100644
--- a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageQualityCheckSnippet.kt
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/ImageQualityCheckSnippet.kt
@@ -13,6 +13,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import io.scanbot.sdk.ScanbotSDK
import io.scanbot.sdk.documentqualityanalyzer.DocumentQuality
+import io.scanbot.sdk.documentqualityanalyzer.DocumentQualityAssessment
import io.scanbot.sdk.image.ImageRef
import io.scanbot.sdk.util.toImageRef
@@ -62,13 +63,11 @@ class ImageQualityCheckSnippet : AppCompatActivity() {
// @EndTag("Analyze the quality of an image")
// Print the result.
- fun printResult(quality: DocumentQuality?) {
+ fun printResult(quality: DocumentQualityAssessment?) {
when (quality) {
- DocumentQuality.VERY_POOR -> print("The quality of the document is very poor")
- DocumentQuality.POOR -> print("The quality of the document is poor")
- DocumentQuality.REASONABLE -> print("The quality of the document is reasonable")
- DocumentQuality.GOOD -> print("The quality of the document is good")
- DocumentQuality.EXCELLENT -> print("The quality of the document is excellent")
+ DocumentQualityAssessment.ACCEPTABLE -> print("The quality of the document is good enough for processing.")
+ DocumentQualityAssessment.UNACCEPTABLE -> print("The quality of the document is not good enough for processing.")
+ DocumentQualityAssessment.UNCERTAIN -> print("The quality of the document is uncertain. It may be good enough for processing, but there is a risk that the result will not be good.")
else -> print("No document was found")
}
}
diff --git a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/AcknowledgeScreenSnippet.kt b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/AcknowledgeScreenSnippet.kt
index 08bd4300..5c6bf379 100644
--- a/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/AcknowledgeScreenSnippet.kt
+++ b/document-scanner-ready-to-use-ui-example/app/src/main/java/com/example/scanbot/doc_code_snippet/rtu_ui/AcknowledgeScreenSnippet.kt
@@ -59,20 +59,16 @@ class AcknowledgeScreenSnippet : AppCompatActivity() {
// - `NONE`: Skips the quality check entirely.
acknowledgementMode = AcknowledgementMode.ALWAYS
- // Set the minimum acceptable document quality.
- // Options: excellent, good, reasonable, poor, veryPoor, or noDocument.
- minimumQuality = DocumentQuality.GOOD
-
// Set the background color for the acknowledgment screen.
backgroundColor = ScanbotColor(value = "#EFEFEF")
// You can also configure the buttons in the bottom bar of the acknowledgment screen.
// e.g To force the user to retake, if the captured document is not OK.
- bottomBar.acceptWhenNotOkButton.visible = false
+ bottomBar.acceptWhenUncertainButton.visible = false
// Hide the titles of the buttons.
- bottomBar.acceptWhenNotOkButton.title.visible = false
- bottomBar.acceptWhenOkButton.title.visible = false
+ bottomBar.acceptWhenUncertainButton.title.visible = false
+ bottomBar.acceptWhenAcceptableButton.title.visible = false
bottomBar.retakeButton.title.visible = false
// Configure the acknowledgment screen's hint message which is shown if the least acceptable quality is not met.
From fdb7badb719f368696c97b036708fbb787acb101 Mon Sep 17 00:00:00 2001
From: Serhii Chaban <>
Date: Tue, 21 Apr 2026 10:29:21 +0200
Subject: [PATCH 08/11] cleanup examples
---
README.md | 2 +-
classic-components-example/README.md | 11 ++++++++
.../adjustable-filters/proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/FilterActivity.kt | 4 +--
.../java/io/scanbot/example/MainActivity.kt | 17 +++++++++----
.../example/ui/BarcodeScannerViewActivity.kt | 11 ++++----
.../io/scanbot/example/ui/MainActivity.kt | 23 ++++++++++++-----
classic-components-example/build.gradle | 2 +-
.../camera-fragment/proguard-rules.pro | 17 -------------
.../java/io/scanbot/example/MainActivity.kt | 21 ++++++++++------
.../java/io/scanbot/example/MainActivity.kt | 6 ++---
.../java/io/scanbot/example/MainActivity.kt | 18 ++++++-------
.../check-scanner/proguard-rules.pro | 21 ----------------
.../AutoSnappingCheckRecognizerActivity.kt | 2 +-
.../scanbot/example/CheckScannerActivity.kt | 2 +-
.../example/CheckScannerResultActivity.kt | 2 +-
.../java/io/scanbot/example/MainActivity.kt | 21 ++++++++++++----
.../common/build.gradle | 3 ---
.../common/consumer-rules.pro | 0
.../common/proguard-rules.pro | 21 ----------------
.../creditcard-scanner/proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 4 +--
.../io/scanbot/example/ScannerActivity.kt | 2 +-
.../proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 25 +++++++++++++------
.../io/scanbot/example/ScannerActivity.kt | 2 +-
.../proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 4 +--
.../io/scanbot/example/ScannerActivity.kt | 2 +-
.../proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 18 ++++++++-----
.../scanbot/example/DocumentCameraActivity.kt | 8 +++---
.../java/io/scanbot/example/MainActivity.kt | 11 +++-----
.../java/io/scanbot/example/MainActivity.kt | 6 ++---
.../manual-processing/proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 21 ++++++++++++----
.../mc-scanner/proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 22 +++++++++++-----
...ManualMedicalCertificateScannerActivity.kt | 2 +-
.../MedicalCertificateRecognizerActivity.kt | 2 +-
.../mrz-scanner/proguard-rules.pro | 21 ----------------
.../example/MRZLiveScanningActivity.kt | 2 +-
.../example/MRZStillImageDetectionActivity.kt | 19 +++++++++++---
.../java/io/scanbot/example/MainActivity.kt | 4 +--
.../src/main/res/layout/activity_main.xml | 1 +
.../ocr/proguard-rules.pro | 17 -------------
.../java/io/scanbot/example/MainActivity.kt | 6 ++---
.../ocr/src/main/res/menu/menu_main.xml | 6 +++--
.../pdf-generation/proguard-rules.pro | 17 -------------
.../java/io/scanbot/example/MainActivity.kt | 2 +-
.../java/io/scanbot/example/PdfActivity.kt | 4 +--
.../io/scanbot/example/PdfWithOcrActivity.kt | 4 +--
.../text-pattern-scanner/proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 4 +--
.../io/scanbot/example/ScannerActivity.kt | 16 ++++++------
.../tiff-generation/proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 20 +++++++++------
.../vin-scanner/proguard-rules.pro | 21 ----------------
.../java/io/scanbot/example/MainActivity.kt | 4 +--
.../io/scanbot/example/ScannerActivity.kt | 2 +-
.../README.md | 19 ++++++++++++++
.../app/build.gradle | 8 ++----
.../java/io/scanbot/example/Application.kt | 2 +-
.../java/io/scanbot/example/util/FontSpan.kt | 14 ++++++++---
.../io/scanbot/example/util/GalleryUtils.kt | 23 ++++++++++++-----
.../README.md | 6 +++++
.../app/build.gradle | 4 +--
.../app/proguard-rules.pro | 21 ----------------
.../example/scanbot/di/ExampleSingleton.kt | 8 +++---
69 files changed, 293 insertions(+), 504 deletions(-)
create mode 100644 classic-components-example/README.md
delete mode 100755 classic-components-example/adjustable-filters/proguard-rules.pro
delete mode 100755 classic-components-example/camera-fragment/proguard-rules.pro
delete mode 100755 classic-components-example/check-scanner/proguard-rules.pro
delete mode 100644 classic-components-example/common/consumer-rules.pro
delete mode 100644 classic-components-example/common/proguard-rules.pro
delete mode 100755 classic-components-example/creditcard-scanner/proguard-rules.pro
delete mode 100755 classic-components-example/document-data-extractor-autosnapping/proguard-rules.pro
delete mode 100755 classic-components-example/document-data-extractor-livedetection/proguard-rules.pro
delete mode 100755 classic-components-example/document-quality-analyzer/proguard-rules.pro
delete mode 100644 classic-components-example/manual-processing/proguard-rules.pro
delete mode 100755 classic-components-example/mc-scanner/proguard-rules.pro
delete mode 100755 classic-components-example/mrz-scanner/proguard-rules.pro
delete mode 100755 classic-components-example/ocr/proguard-rules.pro
delete mode 100755 classic-components-example/pdf-generation/proguard-rules.pro
delete mode 100755 classic-components-example/text-pattern-scanner/proguard-rules.pro
delete mode 100755 classic-components-example/tiff-generation/proguard-rules.pro
delete mode 100755 classic-components-example/vin-scanner/proguard-rules.pro
create mode 100644 data-capture-ready-to-use-ui-example/README.md
delete mode 100644 document-scanner-ready-to-use-ui-example/app/proguard-rules.pro
diff --git a/README.md b/README.md
index 7550815f..a6d3d77e 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Make sure you have the latest stable version of [Android Studio](https://develop
2. There are 4 separate folders with standalone examples:
- * **classic-components-example**: Example project for the Scanbot SDK Classic Components which allow for full customization.
+ * **classic-components-example**: Example project for the Scanbot SDK Classic Components which allow for full customization.
* **compose-custom-ui-example**: Example project for the Scanbot SDK Compose Custom Components which allow for full customization.
* **document-scanner-ready-to-use-ui-example:** Example project for the Scanbot Document Scanner SDK using our Ready-To-Use UI components.
* **data-capture-ready-to-use-ui-example**: Example project showcasing the Scanbot Data Capture Modules using our Ready-to-Use UI components.
diff --git a/classic-components-example/README.md b/classic-components-example/README.md
new file mode 100644
index 00000000..05ee2654
--- /dev/null
+++ b/classic-components-example/README.md
@@ -0,0 +1,11 @@
+# Scanbot SDK Classic Components examples
+
+This project contains multiple standalone Android app modules demonstrating the Scanbot SDK Classic Components. Each module can be opened and run on its own. The only shared code lives in the `common` module.
+
+## How to run a module
+
+1. Open `scanbot-sdk-example-android/classic-components-example` in Android Studio.
+2. Sync Gradle.
+3. Choose one module in the **Run** configuration (each module is an `application`).
+4. Add your Scanbot SDK license key in the module’s `ExampleApplication` or stay on demo mode.
+5. Run the app on a device or emulator.
diff --git a/classic-components-example/adjustable-filters/proguard-rules.pro b/classic-components-example/adjustable-filters/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/adjustable-filters/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/FilterActivity.kt b/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/FilterActivity.kt
index facb3372..ee30d555 100644
--- a/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/FilterActivity.kt
+++ b/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/FilterActivity.kt
@@ -25,8 +25,8 @@ import io.scanbot.sdk.imageprocessing.ParametricFilter
import kotlinx.coroutines.*
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
diff --git a/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/MainActivity.kt
index 8604397d..27519171 100755
--- a/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/adjustable-filters/src/main/java/io/scanbot/example/MainActivity.kt
@@ -22,8 +22,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
- Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
- Please, check the official documentation for more details:
+ This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+ Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -105,9 +105,16 @@ class MainActivity : AppCompatActivity() {
private suspend fun createAndScanDocumentPage(imageUri: Uri): String? {
val imageRef = withContext(Dispatchers.IO) {
- val inputStream = contentResolver.openInputStream(imageUri)
- ?: throw Exception("Cannot open input stream from URI")
- ImageRef.fromInputStream(inputStream)
+ contentResolver.openInputStream(imageUri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ }
+ if (imageRef == null) {
+ withContext(Dispatchers.Main) {
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $imageUri")
+ showToast("Error opening selected image!")
+ }
+ return null
}
val sdk = ScanbotSDK(this)
diff --git a/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/BarcodeScannerViewActivity.kt b/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/BarcodeScannerViewActivity.kt
index 7a38a12e..7bcd04d5 100644
--- a/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/BarcodeScannerViewActivity.kt
+++ b/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/BarcodeScannerViewActivity.kt
@@ -4,17 +4,12 @@ import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
-import android.view.View
-import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
-import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
-import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.updateLayoutParams
import io.scanbot.common.Result
import io.scanbot.common.onFailure
import io.scanbot.common.onSuccess
@@ -88,7 +83,11 @@ class BarcodeScannerViewActivity : AppCompatActivity() {
image: ImageRef,
captureInfo: CaptureInfo
) {
- TODO("Not yet implemented")
+ image.toBitmap().onSuccess { bitmap ->
+ resultView.post {
+ resultView.setImageBitmap(bitmap)
+ }
+ }
}
override fun onSelectionOverlayBarcodeClicked(barcodeItem: BarcodeItem) {
diff --git a/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/MainActivity.kt b/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/MainActivity.kt
index b92d96a5..ebd15f03 100644
--- a/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/MainActivity.kt
+++ b/classic-components-example/barcode-scanner/src/main/java/io/scanbot/example/ui/MainActivity.kt
@@ -28,8 +28,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -101,14 +101,25 @@ class MainActivity : AppCompatActivity() {
binding.progressBar.isVisible = true
}
- withContext(Dispatchers.Default) {
- val inputStream = contentResolver.openInputStream(uri) ?: throw IllegalStateException("Cannot open input stream from URI: $uri")
- val imageRef = ImageRef.fromInputStream(inputStream)
+ val imageRef = withContext(Dispatchers.IO) {
+ contentResolver.openInputStream(uri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ }
+ if (imageRef == null) {
+ withContext(Dispatchers.Main) {
+ binding.progressBar.isVisible = false
+ showToast("Error opening selected image!")
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $uri")
+ }
+ return
+ }
+ withContext(Dispatchers.Default) {
val scanner = scanbotSdk.createBarcodeScanner().getOrThrow()
scanner.setConfiguration(scanner.copyCurrentConfiguration().copy().apply {
setBarcodeFormats(barcodeFormats = BarcodeTypeRepository.selectedTypes.toList())
- } )
+ })
val result = scanner.run(imageRef).getOrNull()
BarcodeResultRepository.barcodeResultBundle = result?.let { BarcodeResultBundle(it, imageRef) }
diff --git a/classic-components-example/build.gradle b/classic-components-example/build.gradle
index d953f471..b89ab9d6 100644
--- a/classic-components-example/build.gradle
+++ b/classic-components-example/build.gradle
@@ -15,7 +15,7 @@ allprojects {
jvmToolchainVersion = 17
- scanbotSdkVersion = "9.0.0.99-STAGING-SNAPSHOT"
+ scanbotSdkVersion = "9.0.0.108-STAGING-SNAPSHOT"
androidCoreKtxVersion = "1.6.0"
constraintLayoutVersion = "2.0.4"
diff --git a/classic-components-example/camera-fragment/proguard-rules.pro b/classic-components-example/camera-fragment/proguard-rules.pro
deleted file mode 100755
index a988b426..00000000
--- a/classic-components-example/camera-fragment/proguard-rules.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /Users/artem.kubiria/Development/sdk/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/classic-components-example/camera-fragment/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/camera-fragment/src/main/java/io/scanbot/example/MainActivity.kt
index 7d6927a6..37bf2c88 100755
--- a/classic-components-example/camera-fragment/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/camera-fragment/src/main/java/io/scanbot/example/MainActivity.kt
@@ -25,8 +25,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -115,12 +115,15 @@ class MainActivity : AppCompatActivity() {
}
val documentImage = withContext(Dispatchers.Default) {
- catchWithResult {
- // load the selected image:
- val inputStream = contentResolver.openInputStream(imageUri)
- ?: throw IllegalStateException("Cannot open input stream from URI: $imageUri")
- val image = ImageRef.fromInputStream(inputStream)
+ val image = contentResolver.openInputStream(imageUri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ if (image == null) {
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $imageUri")
+ return@withContext null
+ }
+ catchWithResult {
// create a new Document object with given image as original image:
val newDocument = scanbotSdk.documentApi.createDocument()
.getOrReturn() // can be handled with .getOrNull() if needed
@@ -144,6 +147,10 @@ class MainActivity : AppCompatActivity() {
withContext(Dispatchers.Main) {
progressBar.visibility = View.GONE
+ if (documentImage == null) {
+ this@MainActivity.showToast("Error opening selected image!")
+ return@withContext
+ }
// show Page's document image:
importResultImage.setImageBitmap(documentImage)
importResultImage.visibility = View.VISIBLE
diff --git a/classic-components-example/camera-view-aspect-ratio-finder/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/camera-view-aspect-ratio-finder/src/main/java/io/scanbot/example/MainActivity.kt
index 4ecce016..966b646a 100755
--- a/classic-components-example/camera-view-aspect-ratio-finder/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/camera-view-aspect-ratio-finder/src/main/java/io/scanbot/example/MainActivity.kt
@@ -36,8 +36,8 @@ import io.scanbot.sdk.ui.camera.ShutterButton
import io.scanbot.sdk.util.PolygonHelper
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -64,7 +64,7 @@ class MainActivity : AppCompatActivity(), DocumentScannerFrameHandler.ResultHand
askPermission()
setContentView(R.layout.activity_main)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
cameraView = findViewById(R.id.camera) as ScanbotCameraXView
diff --git a/classic-components-example/camera-view/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/camera-view/src/main/java/io/scanbot/example/MainActivity.kt
index 0cd1654d..0df39e65 100755
--- a/classic-components-example/camera-view/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/camera-view/src/main/java/io/scanbot/example/MainActivity.kt
@@ -43,8 +43,8 @@ import io.scanbot.sdk.ui.camera.ShutterButton
import io.scanbot.sdk.util.PolygonHelper
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -63,13 +63,13 @@ class MainActivity : AppCompatActivity(), DocumentScannerFrameHandler.ResultHand
private var lastUserGuidanceHintTs = 0L
private var flashEnabled = false
private var autoSnappingEnabled = true
- private val ignoreOrientationMistmatch = true
+ private val ignoreOrientationMismatch = true
override fun onCreate(savedInstanceState: Bundle?) {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
super.onCreate(savedInstanceState)
askPermission()
setContentView(R.layout.activity_main)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
cameraView = findViewById(R.id.camera) as ScanbotCameraXView
@@ -83,7 +83,7 @@ class MainActivity : AppCompatActivity(), DocumentScannerFrameHandler.ResultHand
// Please note: https://docs.scanbot.io/document-scanner-sdk/android/features/document-scanner/ui-components/
setConfiguration(copyCurrentConfiguration().apply {
parameters.apply {
- this.ignoreOrientationMismatch = ignoreOrientationMistmatch
+ this.ignoreOrientationMismatch = ignoreOrientationMismatch
this.acceptedSizeScore = 75
this.acceptedAngleScore = 60
}
@@ -150,11 +150,11 @@ class MainActivity : AppCompatActivity(), DocumentScannerFrameHandler.ResultHand
)
}
}.onFailure { error ->
- when(error){
- is Result.InvalidLicenseError ->{
+ when (error) {
+ is Result.InvalidLicenseError -> {
Toast.makeText(this@MainActivity, "License is invalid: ${error.message}", Toast.LENGTH_LONG).show()
}
- else -> {
+ else -> {
Toast.makeText(this@MainActivity, "${error.message}", Toast.LENGTH_LONG).show()
}
}
@@ -224,7 +224,7 @@ class MainActivity : AppCompatActivity(), DocumentScannerFrameHandler.ResultHand
}
DocumentDetectionStatus.OK_BUT_BAD_ASPECT_RATIO -> {
- if (ignoreOrientationMistmatch) {
+ if (ignoreOrientationMismatch) {
userGuidanceHint.text = "Don't move"
// change polygon color to "OK"
polygonView.setFillColor(POLYGON_FILL_COLOR_OK)
diff --git a/classic-components-example/check-scanner/proguard-rules.pro b/classic-components-example/check-scanner/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/check-scanner/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/AutoSnappingCheckRecognizerActivity.kt b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/AutoSnappingCheckRecognizerActivity.kt
index f5df0939..71d08e9e 100644
--- a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/AutoSnappingCheckRecognizerActivity.kt
+++ b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/AutoSnappingCheckRecognizerActivity.kt
@@ -39,7 +39,7 @@ class AutoSnappingCheckScannerActivity : AppCompatActivity() {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_autosnapping_check_scanner)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
cameraView = findViewById(R.id.camera).also { cameraView ->
diff --git a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerActivity.kt b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerActivity.kt
index d9cf7677..9ac8bf25 100644
--- a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerActivity.kt
+++ b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerActivity.kt
@@ -31,7 +31,7 @@ class CheckScannerActivity : AppCompatActivity() {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_check_scanner)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
cameraView = findViewById(R.id.camera).also { cameraView ->
diff --git a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerResultActivity.kt b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerResultActivity.kt
index a0fd2d03..7e6cedb1 100644
--- a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerResultActivity.kt
+++ b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/CheckScannerResultActivity.kt
@@ -19,7 +19,7 @@ class CheckScannerResultActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_check_result)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
val fieldsLayout = findViewById(R.id.check_result_fields_layout)
diff --git a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/MainActivity.kt
index d42d517d..de3ed48e 100644
--- a/classic-components-example/check-scanner/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/check-scanner/src/main/java/io/scanbot/example/MainActivity.kt
@@ -25,8 +25,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -77,10 +77,21 @@ class MainActivity : AppCompatActivity() {
private suspend fun scanCheck(uri: Uri) {
withContext(Dispatchers.Main) { binding.progressBar.isVisible = true }
- val result = withContext(Dispatchers.Default) {
- val inputStream = contentResolver.openInputStream(uri) ?: throw IllegalStateException("Cannot open input stream from URI: $uri")
- val imageRef = ImageRef.fromInputStream(inputStream)
+ val imageRef = withContext(Dispatchers.IO) {
+ contentResolver.openInputStream(uri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ }
+ if (imageRef == null) {
+ withContext(Dispatchers.Main) {
+ binding.progressBar.isVisible = false
+ showToast("Error opening selected image!")
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $uri")
+ }
+ return
+ }
+ val result = withContext(Dispatchers.Default) {
val scanner = scanbotSdk.createCheckScanner().getOrThrow()
scanner.run(imageRef).getOrNull()
}
diff --git a/classic-components-example/common/build.gradle b/classic-components-example/common/build.gradle
index e2a1776f..ef52fd20 100644
--- a/classic-components-example/common/build.gradle
+++ b/classic-components-example/common/build.gradle
@@ -9,14 +9,11 @@ android {
defaultConfig {
minSdk = project.ext.minSdkVersion
-
- proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro", "consumer-rules.pro")
}
buildTypes {
named("release") {
minifyEnabled = false
- proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
diff --git a/classic-components-example/common/consumer-rules.pro b/classic-components-example/common/consumer-rules.pro
deleted file mode 100644
index e69de29b..00000000
diff --git a/classic-components-example/common/proguard-rules.pro b/classic-components-example/common/proguard-rules.pro
deleted file mode 100644
index 481bb434..00000000
--- a/classic-components-example/common/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/classic-components-example/creditcard-scanner/proguard-rules.pro b/classic-components-example/creditcard-scanner/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/creditcard-scanner/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/MainActivity.kt
index 5bf14381..329ac035 100755
--- a/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/MainActivity.kt
@@ -13,8 +13,8 @@ import androidx.core.content.ContextCompat
import io.scanbot.example.common.applyEdgeToEdge
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
diff --git a/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/ScannerActivity.kt b/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/ScannerActivity.kt
index 43327b2c..6bcddc17 100644
--- a/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/ScannerActivity.kt
+++ b/classic-components-example/creditcard-scanner/src/main/java/io/scanbot/example/ScannerActivity.kt
@@ -28,7 +28,7 @@ class ScannerActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
binding = ActivityScannerBinding.inflate(layoutInflater)
setContentView(binding.root)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
// init scanbot sdk and create credit card scanner
diff --git a/classic-components-example/document-data-extractor-autosnapping/proguard-rules.pro b/classic-components-example/document-data-extractor-autosnapping/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/document-data-extractor-autosnapping/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/MainActivity.kt
index 0f0d3c65..2038fdad 100755
--- a/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/MainActivity.kt
@@ -22,8 +22,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -51,11 +51,22 @@ class MainActivity : AppCompatActivity() {
lifecycleScope.launch {
val dataExtractor = scanbotSdk.createDocumentDataExtractor().getOrThrow()
- val result = withContext(Dispatchers.Default) {
- val inputStream = contentResolver.openInputStream(uri) ?: throw IllegalStateException("Cannot open input stream from URI: $uri")
- val imageRef = ImageRef.fromInputStream(inputStream)
- dataExtractor.run(imageRef).getOrNull()
- }
+ val imageRef = withContext(Dispatchers.IO) {
+ contentResolver.openInputStream(uri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ }
+ if (imageRef == null) {
+ withContext(Dispatchers.Main) {
+ showToast("Error opening selected image!")
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $uri")
+ }
+ return@launch
+ }
+
+ val result = withContext(Dispatchers.Default) {
+ dataExtractor.run(imageRef).getOrNull()
+ }
withContext(Dispatchers.Main) {
DocumentsResultsStorage.result = result
diff --git a/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/ScannerActivity.kt b/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/ScannerActivity.kt
index 8d8d6399..d440f4b0 100644
--- a/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/ScannerActivity.kt
+++ b/classic-components-example/document-data-extractor-autosnapping/src/main/java/io/scanbot/example/ScannerActivity.kt
@@ -38,7 +38,7 @@ class ScannerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scanner)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
scanbotSdk = ScanbotSDK(this)
diff --git a/classic-components-example/document-data-extractor-livedetection/proguard-rules.pro b/classic-components-example/document-data-extractor-livedetection/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/document-data-extractor-livedetection/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/MainActivity.kt
index f792adc3..2305a525 100755
--- a/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/MainActivity.kt
@@ -10,8 +10,8 @@ import io.scanbot.example.common.showToast
import io.scanbot.example.databinding.ActivityMainBinding
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
diff --git a/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/ScannerActivity.kt b/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/ScannerActivity.kt
index 25011a5c..1b5bc7fc 100644
--- a/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/ScannerActivity.kt
+++ b/classic-components-example/document-data-extractor-livedetection/src/main/java/io/scanbot/example/ScannerActivity.kt
@@ -28,7 +28,7 @@ class ScannerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scanner)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(this.findViewById(R.id.root_view))
cameraView = findViewById(R.id.cameraView)
diff --git a/classic-components-example/document-quality-analyzer/proguard-rules.pro b/classic-components-example/document-quality-analyzer/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/document-quality-analyzer/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/document-quality-analyzer/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/document-quality-analyzer/src/main/java/io/scanbot/example/MainActivity.kt
index dab4b065..33775076 100755
--- a/classic-components-example/document-quality-analyzer/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/document-quality-analyzer/src/main/java/io/scanbot/example/MainActivity.kt
@@ -19,8 +19,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -55,7 +55,7 @@ class MainActivity : AppCompatActivity() {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
super.onCreate(savedInstanceState)
setContentView(binding.root)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(findViewById(R.id.root_view))
binding.galleryButton.setOnClickListener {
@@ -72,11 +72,17 @@ class MainActivity : AppCompatActivity() {
private suspend fun estimateOnStillImage(imageUri: Uri) {
val image = withContext(Dispatchers.IO) {
- contentResolver.openInputStream(imageUri).use { inputStream ->
- inputStream?.let { ImageRef.fromInputStream(it) }
+ contentResolver.openInputStream(imageUri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
}
}
- if (image == null) return
+ if (image == null) {
+ withContext(Dispatchers.Main) {
+ showToast("Error opening selected image!")
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $imageUri")
+ }
+ return
+ }
withContext(Dispatchers.Main) {
binding.stillImageImageView.setImageBitmap(image?.toBitmap()?.getOrNull())
}
diff --git a/classic-components-example/document-scanner/src/main/java/io/scanbot/example/DocumentCameraActivity.kt b/classic-components-example/document-scanner/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
index 266e13c0..6be44604 100755
--- a/classic-components-example/document-scanner/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
+++ b/classic-components-example/document-scanner/src/main/java/io/scanbot/example/DocumentCameraActivity.kt
@@ -36,7 +36,7 @@ class DocumentCameraActivity : AppCompatActivity() {
private var lastUserGuidanceHintTs = 0L
private var flashEnabled = false
private var autoSnappingEnabled = true
- private val ignoreOrientationMistmatch = true
+ private val ignoreOrientationMismatch = true
private lateinit var documentScannerView: DocumentScannerView
@@ -52,7 +52,7 @@ class DocumentCameraActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
askPermission()
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(findViewById(R.id.root_view))
val scanbotSdk = ScanbotSDK(this)
@@ -116,7 +116,7 @@ class DocumentCameraActivity : AppCompatActivity() {
documentScannerView.viewController.apply {
setAcceptedAngleScore(60.0)
setAcceptedSizeScore(75.0)
- setIgnoreOrientationMismatch(ignoreOrientationMistmatch)
+ setIgnoreOrientationMismatch(ignoreOrientationMismatch)
// Please note: https://docs.scanbot.io/document-scanner-sdk/android/features/document-scanner/autosnapping/#sensitivity
setAutoSnappingSensitivity(0.85f)
@@ -196,7 +196,7 @@ class DocumentCameraActivity : AppCompatActivity() {
}
DocumentDetectionStatus.OK_BUT_BAD_ASPECT_RATIO -> {
- if (ignoreOrientationMistmatch) {
+ if (ignoreOrientationMismatch) {
userGuidanceHint.text = "Don't move"
} else {
userGuidanceHint.text = "Wrong aspect ratio.\nRotate your device."
diff --git a/classic-components-example/document-scanner/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/document-scanner/src/main/java/io/scanbot/example/MainActivity.kt
index 047a0795..3c14c76e 100644
--- a/classic-components-example/document-scanner/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/document-scanner/src/main/java/io/scanbot/example/MainActivity.kt
@@ -11,8 +11,6 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import io.scanbot.common.onSuccess
-
-
import io.scanbot.example.common.Const
import io.scanbot.example.common.applyEdgeToEdge
import io.scanbot.example.common.showToast
@@ -25,10 +23,10 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
-Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
-ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
+ * This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+ * Please check the official documentation for more details:
+ * Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
+ * ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
class MainActivity : AppCompatActivity() {
@@ -91,7 +89,6 @@ class MainActivity : AppCompatActivity() {
ImageRef.fromInputStream(inputStream)
} ?: throw IllegalStateException("Cannot open input stream from URI: $uri")
-
// create a new Page object with given image as original image:
val document = scanbotSdk.documentApi.createDocument()
.getOrNull() //can be handled with .getOrThrow() if needed
diff --git a/classic-components-example/edit-polygon-view/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/edit-polygon-view/src/main/java/io/scanbot/example/MainActivity.kt
index 9d46ed9c..62cc365a 100755
--- a/classic-components-example/edit-polygon-view/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/edit-polygon-view/src/main/java/io/scanbot/example/MainActivity.kt
@@ -24,8 +24,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -58,7 +58,7 @@ class MainActivity : AppCompatActivity() {
scanner = scanbotSDK.createDocumentScanner().getOrThrow()
- supportActionBar!!.hide()
+ supportActionBar?.hide()
editPolygonView = findViewById(R.id.polygonView)
magnifierView = findViewById(R.id.magnifier)
diff --git a/classic-components-example/manual-processing/proguard-rules.pro b/classic-components-example/manual-processing/proguard-rules.pro
deleted file mode 100644
index f1b42451..00000000
--- a/classic-components-example/manual-processing/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/manual-processing/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/manual-processing/src/main/java/io/scanbot/example/MainActivity.kt
index 3748b32b..f7c8b384 100755
--- a/classic-components-example/manual-processing/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/manual-processing/src/main/java/io/scanbot/example/MainActivity.kt
@@ -23,8 +23,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -66,10 +66,21 @@ class MainActivity : AppCompatActivity() {
private suspend fun processImage(imageUri: Uri) {
withContext(Dispatchers.Main) { binding.progressBar.visibility = View.VISIBLE }
+ val image = withContext(Dispatchers.IO) {
+ contentResolver.openInputStream(imageUri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ }
+ if (image == null) {
+ withContext(Dispatchers.Main) {
+ binding.progressBar.visibility = View.GONE
+ showToast("Error opening selected image!")
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $imageUri")
+ }
+ return
+ }
+
val page = withContext(Dispatchers.Default) {
- val inputStream = contentResolver.openInputStream(imageUri)
- ?: throw IllegalStateException("Cannot open input stream from URI: $imageUri")
- val image = ImageRef.fromInputStream(inputStream)
val scanner = scanbotSdk.createDocumentScanner().getOrThrow()
val detectedPolygon =
scanner.run(image).getOrNull()?.pointsNormalized ?: PolygonHelper.getFullPolygon()
diff --git a/classic-components-example/mc-scanner/proguard-rules.pro b/classic-components-example/mc-scanner/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/mc-scanner/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MainActivity.kt
index 9add4cac..06eac728 100755
--- a/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MainActivity.kt
@@ -22,8 +22,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
@@ -56,11 +56,21 @@ class MainActivity : AppCompatActivity() {
binding.progressBar.isVisible = true
}
- val result = withContext(Dispatchers.Default) {
- val inputStream = contentResolver.openInputStream(uri)
- ?: throw IllegalStateException("Cannot open input stream from URI: $uri")
- val imageRef = ImageRef.fromInputStream(inputStream)
+ val imageRef = withContext(Dispatchers.IO) {
+ contentResolver.openInputStream(uri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ }
+ if (imageRef == null) {
+ withContext(Dispatchers.Main) {
+ binding.progressBar.isVisible = false
+ showToast("Error opening selected image!")
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $uri")
+ }
+ return
+ }
+ val result = withContext(Dispatchers.Default) {
val scanner = scanbotSdk.createMedicalCertificateScanner().getOrThrow()
scanner.run(
diff --git a/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/ManualMedicalCertificateScannerActivity.kt b/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/ManualMedicalCertificateScannerActivity.kt
index b2e75d7b..f5ff95ff 100755
--- a/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/ManualMedicalCertificateScannerActivity.kt
+++ b/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/ManualMedicalCertificateScannerActivity.kt
@@ -42,7 +42,7 @@ class ManualMedicalCertificateScannerActivity : AppCompatActivity() {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_manual_mc_scanner)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(findViewById(R.id.root_view))
askPermission()
diff --git a/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MedicalCertificateRecognizerActivity.kt b/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MedicalCertificateRecognizerActivity.kt
index 77346fde..62524112 100755
--- a/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MedicalCertificateRecognizerActivity.kt
+++ b/classic-components-example/mc-scanner/src/main/java/io/scanbot/example/MedicalCertificateRecognizerActivity.kt
@@ -44,7 +44,7 @@ class MedicalCertificateScannerActivity : AppCompatActivity() {
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mc_scanner)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(findViewById(R.id.root_view))
askPermission()
resultImageView = findViewById(R.id.resultImageView)
diff --git a/classic-components-example/mrz-scanner/proguard-rules.pro b/classic-components-example/mrz-scanner/proguard-rules.pro
deleted file mode 100755
index f1b42451..00000000
--- a/classic-components-example/mrz-scanner/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZLiveScanningActivity.kt b/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZLiveScanningActivity.kt
index 2955a1ea..e821f204 100755
--- a/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZLiveScanningActivity.kt
+++ b/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZLiveScanningActivity.kt
@@ -36,7 +36,7 @@ class MRZLiveScanningActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_mrz_live_scanner)
askPermission()
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(findViewById(R.id.root_view))
// Configure Initial camera state
diff --git a/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZStillImageDetectionActivity.kt b/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZStillImageDetectionActivity.kt
index 74c1b4b1..5245158c 100755
--- a/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZStillImageDetectionActivity.kt
+++ b/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MRZStillImageDetectionActivity.kt
@@ -66,7 +66,7 @@ class MrzStillImageScanningActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
- supportActionBar!!.hide()
+ supportActionBar?.hide()
applyEdgeToEdge(findViewById(R.id.root_view))
docScannerResultLauncher =
@@ -121,10 +121,21 @@ class MrzStillImageScanningActivity : AppCompatActivity() {
}
private suspend fun importImageToPage(uri: Uri) {
- val page = withContext(Dispatchers.Default) {
- val inputStream = contentResolver.openInputStream(uri) ?: throw IllegalStateException("Cannot open input stream from URI: $uri")
- val image = ImageRef.fromInputStream(inputStream)
+ val image = withContext(Dispatchers.IO) {
+ contentResolver.openInputStream(uri)?.use { inputStream ->
+ ImageRef.fromInputStream(inputStream)
+ }
+ }
+ if (image == null) {
+ withContext(Dispatchers.Main) {
+ binding.progressBar.visibility = View.GONE
+ showToast("Error opening selected image!")
+ Log.e(Const.LOG_TAG, "Cannot open input stream from URI: $uri")
+ }
+ return
+ }
+ val page = withContext(Dispatchers.Default) {
val document = scanbotSdk.documentApi.createDocument().getOrThrow() // can be handled with .getOrNull() if needed
val page = document.addPage(image).getOrThrow() // can be handled with .getOrNull() if needed
diff --git a/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MainActivity.kt b/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MainActivity.kt
index 8d255df7..9aa64ea4 100755
--- a/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MainActivity.kt
+++ b/classic-components-example/mrz-scanner/src/main/java/io/scanbot/example/MainActivity.kt
@@ -8,8 +8,8 @@ import io.scanbot.example.common.applyEdgeToEdge
import io.scanbot.example.databinding.ActivityMainBinding
/**
-Ths example uses new sdk APIs presented in Scanbot SDK v.8.x.x
-Please, check the official documentation for more details:
+This example uses the SDK APIs introduced in Scanbot SDK v8.x.x.
+Please check the official documentation for more details:
Result API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/result-api/
ImageRef API https://docs.scanbot.io/android/document-scanner-sdk/detailed-setup-guide/image-ref-api/
*/
diff --git a/classic-components-example/mrz-scanner/src/main/res/layout/activity_main.xml b/classic-components-example/mrz-scanner/src/main/res/layout/activity_main.xml
index c82a7bb8..a0ff3b8c 100755
--- a/classic-components-example/mrz-scanner/src/main/res/layout/activity_main.xml
+++ b/classic-components-example/mrz-scanner/src/main/res/layout/activity_main.xml
@@ -18,6 +18,7 @@
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.502" />