Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f662429
fix compiling for data example app
4BooM04 Sep 19, 2025
1689b30
fix adjustable filters module
4BooM04 Oct 10, 2025
9990b3e
fix barcode scanner module
4BooM04 Oct 10, 2025
2145fdd
fix camera-fragment module
4BooM04 Oct 10, 2025
55b23f3
fix camera-view module
4BooM04 Oct 10, 2025
a50a0dd
fixed camera-view-aspect-ratio-finder module
4BooM04 Oct 10, 2025
ae2dad3
fixed check-scanner module
4BooM04 Oct 10, 2025
394f214
fix credit-card scanner
4BooM04 Oct 10, 2025
cbb18b7
fixed document-data-extractor-autosnapping module
4BooM04 Oct 10, 2025
79cbd94
fixed document-data-extractor-livedetection module
4BooM04 Oct 10, 2025
dd8b5cd
fixed document-scanner module
4BooM04 Oct 10, 2025
6c9532a
fix edit-poligon-view module
4BooM04 Oct 13, 2025
f1f936b
fix encryption module
4BooM04 Oct 13, 2025
3ea6607
fix manual processing module
4BooM04 Oct 13, 2025
4caf283
fixed mc-scanner module
4BooM04 Oct 13, 2025
6263bc0
fixed mrz-scanner module
4BooM04 Oct 13, 2025
8cca2fc
fixed ocr module
4BooM04 Oct 13, 2025
29bf1b2
fixed text-pattern-scanner module
4BooM04 Oct 13, 2025
127ffdc
fixed vin-scanner example
4BooM04 Oct 13, 2025
24e5858
fix mc snippet
4BooM04 Oct 24, 2025
72957f3
update tags in result api
4BooM04 Oct 24, 2025
4e6f6b8
fix result snippets
4BooM04 Oct 24, 2025
61b6bc1
fix snippet tags
4BooM04 Oct 24, 2025
fb97b57
fix comments
4BooM04 Oct 24, 2025
93d2524
add image ref snippets
4BooM04 Oct 30, 2025
07aa230
fix agp
4BooM04 Nov 4, 2025
ac066bf
fix image refs and result snippets compiling
4BooM04 Nov 5, 2025
8d43a39
fix classic component compiling
4BooM04 Nov 5, 2025
456026b
add imageRef to bitmap snippet
4BooM04 Nov 10, 2025
3fff2b1
update snipets to document result api
4BooM04 Nov 10, 2025
cc3a883
update data app frame handler results
4BooM04 Nov 11, 2025
9152225
update classic component document api results and frame handlers
4BooM04 Nov 11, 2025
c8a77ad
fix VIN snippet
4BooM04 Nov 11, 2025
788f8ac
update VIN snippet
4BooM04 Nov 11, 2025
44d921e
update result api sintacsis sugar
4BooM04 Nov 11, 2025
570f34e
add result api disclaimer
4BooM04 Nov 11, 2025
c06e542
fix snippets
4BooM04 Nov 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions classic-components-example/adjustable-filters/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ dependencies {
implementation("androidx.appcompat:appcompat:${project.ext.androidxAppcompatVersion}")
implementation("androidx.constraintlayout:constraintlayout:${project.ext.constraintLayoutVersion}")
implementation("io.scanbot:sdk-package-1:${project.ext.scanbotSdkVersion}")
implementation("io.scanbot:sdk-package-ui:${project.ext.scanbotSdkVersion}")
implementation("io.scanbot:sdk-ml-imageprocessor-assets:${project.ext.scanbotSdkVersion}")
implementation("com.squareup.picasso:picasso:${project.ext.picassoVersion}")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${project.ext.coroutinesCoreVersion}")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:${project.ext.coroutinesAndroidVersion}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package io.scanbot.example

import android.app.Application
import io.scanbot.example.common.Const
import io.scanbot.sap.SdkFeature
import io.scanbot.sdk.ScanbotSDK
import io.scanbot.sdk.ScanbotSDKInitializer
import io.scanbot.sdk.licensing.Feature
import io.scanbot.sdk.util.log.LoggerProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -37,11 +37,9 @@ class ExampleApplication : Application(), CoroutineScope {
.withLogging(true)
// TODO 2/2: Enable the Scanbot SDK license key
//.license(this, licenseKey)
.licenceErrorHandler { status, feature, statusMessage ->
.licenseErrorHandler { status, feature, statusMessage ->
logger.d(Const.LOG_TAG, "+++> License status: ${status.name}. Status message: $statusMessage")
if (feature != SdkFeature.NoSdkFeature) {
logger.d(Const.LOG_TAG, "+++> Feature not available: ${feature.name}")
}
}
//.sdkFilesDirectory(this, getExternalFilesDir(null)!!)
.initialize(this)
Expand All @@ -51,7 +49,7 @@ class ExampleApplication : Application(), CoroutineScope {
val licenseInfo = ScanbotSDK(this).licenseInfo
logger.d(Const.LOG_TAG, "License status: ${licenseInfo.status}")
logger.d(Const.LOG_TAG, "License isValid: ${licenseInfo.isValid}")
logger.d(Const.LOG_TAG, "License expirationDate: ${licenseInfo.expirationDate}")
logger.d(Const.LOG_TAG, "License expirationDate: ${licenseInfo.expirationDateString}")

launch {
// Clear all previously created documents in storage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import io.scanbot.example.common.showToast
import io.scanbot.example.databinding.ActivityFiltersTunesBinding
import io.scanbot.example.fragment.ErrorFragment
import io.scanbot.example.fragment.FiltersBottomSheetMenuFragment
import io.scanbot.sdk.imagefilters.ParametricFilter
import io.scanbot.sdk.ScanbotSDK
import io.scanbot.sdk.docprocessing.Document
import io.scanbot.sdk.docprocessing.Page
import io.scanbot.sdk.imageprocessing.ParametricFilter
import kotlinx.coroutines.*

class FilterActivity : AppCompatActivity(), FiltersListener {
Expand Down Expand Up @@ -89,7 +89,7 @@ class FilterActivity : AppCompatActivity(), FiltersListener {
}

private suspend fun loadDocument(docId: String) {
val doc = withContext(Dispatchers.IO) { scanbotSdk.documentApi.loadDocument(docId) }
val doc = withContext(Dispatchers.IO) { scanbotSdk.documentApi.loadDocument(docId).getOrNull() }
withContext(Dispatchers.Main) {
if (doc == null) {
showToast("Document with given ID was not found!")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.scanbot.example

import io.scanbot.sdk.imagefilters.ParametricFilter
import io.scanbot.sdk.imageprocessing.ParametricFilter

interface FiltersListener {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.scanbot.example

import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.util.Log
Expand All @@ -9,45 +8,61 @@ import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import io.scanbot.common.mapSuccess
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.DocumentDetectionStatus
import io.scanbot.sdk.image.ImageRef
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 binding by lazy { ActivityMainBinding.inflate(layoutInflater) }

private val scanbotSdk: ScanbotSDK by lazy { ScanbotSDK(this) }

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
}
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
}

lifecycleScope.launch {
val documentId = createAndScanDocumentPage(uri)
if (uri == null) {
showToast("Error obtaining selected image!")
Log.e(Const.LOG_TAG, "Error obtaining selected image!")
return@registerForActivityResult
}

if (documentId != null) {
filterActivityResultLauncher.launch(FilterActivity.newIntent(this@MainActivity, documentId))
} else {
Log.e(Const.LOG_TAG, "Error creating document with page!")
showToast("Error creating document with page!")
lifecycleScope.launch {
val documentId = createAndScanDocumentPage(uri)

if (documentId != null) {
filterActivityResultLauncher.launch(
FilterActivity.newIntent(
this@MainActivity,
documentId
)
)
} else {
Log.e(Const.LOG_TAG, "Error creating document with page!")
showToast("Error creating document with page!")
}
}
}
}

private val filterActivityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
Expand All @@ -61,7 +76,9 @@ class MainActivity : AppCompatActivity() {
return@registerForActivityResult
}

val page = ScanbotSDK(this).documentApi.loadDocument(documentId)?.pages?.firstOrNull()
val page =
ScanbotSDK(this).documentApi.loadDocument(documentId)
.getOrNull()?.pages?.firstOrNull()
if (page == null) {
Log.e(Const.LOG_TAG, "Error loading document with page!")
showToast("Error loading document with page!")
Expand All @@ -87,15 +104,10 @@ class MainActivity : AppCompatActivity() {
}

private suspend fun createAndScanDocumentPage(imageUri: Uri): String? {
val bitmap = withContext(Dispatchers.IO) {
val imageRef = withContext(Dispatchers.IO) {
val inputStream = contentResolver.openInputStream(imageUri)
BitmapFactory.decodeStream(inputStream)
}

if (bitmap == null) {
Log.e(Const.LOG_TAG, "Error loading image (bitmap is `null`)!")
showToast("Error loading image!")
return null
?: throw Exception("Cannot open input stream from URI")
ImageRef.fromInputStream(inputStream)
}

val sdk = ScanbotSDK(this)
Expand All @@ -107,31 +119,38 @@ class MainActivity : AppCompatActivity() {

binding.progressBar.visibility = View.VISIBLE
val resultDocument = withContext(Dispatchers.Default) {
val result = sdk.createDocumentScanner().scanFromBitmap(bitmap)
sdk.createDocumentScanner().mapSuccess { documentScanner ->

val result = documentScanner?.scan(imageRef)
?.getOrReturn() // it is also possible to check specific error by che
val detectionResult = result?.detectionResult
Log.d(Const.LOG_TAG, "Doc found: ${result}")

val status =
detectionResult?.status ?: DocumentDetectionStatus.ERROR_NOTHING_DETECTED

/** We allow all `OK_*` [statuses][DocumentDetectionStatus] just for purpose of this example.
* Otherwise it is a good practice to differentiate between statuses and handle them accordingly.
*/

val isScanOk = status?.name?.startsWith("OK", true) ?: false
if (isScanOk.not()) {
Log.e(
Const.LOG_TAG,
"Bad document photo - scanning status was ${status.name}!"
)
showToast("Bad document photo - status ${status.name}!")
throw Exception("Bad document photo - scanning status was ${status.name}!")
}

if (result == null) {
Log.e(Const.LOG_TAG, "Error finding document (result is `null`)!")
showToast("Error finding document!")
return@withContext null
}
Log.d(Const.LOG_TAG, "Doc found: ${result.status}")

/** We allow all `OK_*` [statuses][DocumentDetectionStatus] just for purpose of this example.
* Otherwise it is a good practice to differentiate between statuses and handle them accordingly.
*/
val isScanOk = result.status.name.startsWith("OK", true)
if (isScanOk.not()) {
Log.e(Const.LOG_TAG, "Bad document photo - scanning status was ${result.status.name}!")
showToast("Bad document photo - status ${result.status.name}!")
return@withContext null
sdk.documentApi.createDocument().onSuccess { document ->
val page = document.addPage(imageRef).getOrReturn() //can be handled with .getOrNull() if needed
Log.d(Const.LOG_TAG, "Page added: ${page.uuid}")
page.apply(newPolygon = detectionResult?.pointsNormalized)
document
}.getOrReturn()
}

val document = sdk.documentApi.createDocument()
val page = document.addPage(bitmap)
Log.d(Const.LOG_TAG, "Page added: ${page.uuid}")
page.apply(newPolygon = result.pointsNormalized)
document
}
}.getOrNull()

binding.progressBar.visibility = View.GONE
Log.d(Const.LOG_TAG, "Document created: ${resultDocument?.uuid}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.scanbot.example

import io.scanbot.sdk.imagefilters.ParametricFilter
import io.scanbot.sdk.imageprocessing.ParametricFilter


fun ParametricFilter?.getFilterName(): String {
return this?.javaClass?.simpleName ?: "None"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import android.widget.Button
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import io.scanbot.example.FiltersListener
import io.scanbot.example.R
import io.scanbot.sdk.imagefilters.BrightnessFilter
import io.scanbot.sdk.imagefilters.ColorDocumentFilter
import io.scanbot.sdk.imagefilters.ContrastFilter
import io.scanbot.sdk.imagefilters.CustomBinarizationFilter
import io.scanbot.sdk.imagefilters.GrayscaleFilter
import io.scanbot.sdk.imagefilters.ParametricFilter
import io.scanbot.sdk.imagefilters.ScanbotBinarizationFilter
import io.scanbot.sdk.imagefilters.WhiteBlackPointFilter
import io.scanbot.sdk.imageprocessing.BrightnessFilter
import io.scanbot.sdk.imageprocessing.ColorDocumentFilter
import io.scanbot.sdk.imageprocessing.ContrastFilter
import io.scanbot.sdk.imageprocessing.CustomBinarizationFilter
import io.scanbot.sdk.imageprocessing.GrayscaleFilter
import io.scanbot.sdk.imageprocessing.ParametricFilter
import io.scanbot.sdk.imageprocessing.ScanbotBinarizationFilter
import io.scanbot.sdk.imageprocessing.WhiteBlackPointFilter

/** Represents bottom menu sheet for page filters screen. */
class FiltersBottomSheetMenuFragment : BottomSheetDialogFragment() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

<Button
android:id="@+id/cancel"
style="@style/Scanbot.Toolbar.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CANCEL" />
Expand All @@ -30,7 +29,6 @@

<Button
android:id="@+id/done"
style="@style/Scanbot.Toolbar.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DONE" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.scanbot.example

import android.app.Application
import io.scanbot.sap.SdkFeature
import io.scanbot.sdk.ScanbotSDK
import io.scanbot.sdk.ScanbotSDKInitializer
import io.scanbot.sdk.util.log.LoggerProvider
Expand All @@ -24,11 +23,15 @@ class ExampleApplication : Application() {
.withLogging(true)
// TODO 2/2: Enable the Scanbot SDK license key
//.license(this, licenseKey)
.licenceErrorHandler { status, feature, statusMessage ->
LoggerProvider.logger.d("ExampleApplication", "+++> License status: ${status.name}. Status message: $statusMessage")
if (feature != SdkFeature.NoSdkFeature) {
LoggerProvider.logger.d("ExampleApplication", "+++> Feature not available: ${feature.name}")
}
.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)
Expand All @@ -38,6 +41,9 @@ class ExampleApplication : Application() {
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.expirationDate}")
LoggerProvider.logger.d(
"ExampleApplication",
"License expirationDate: ${licenseInfo.expirationDateString}"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class BarcodeResultActivity : AppCompatActivity() {
BarcodeItemBinding.inflate(layoutInflater, binding.scannedItems, false)
.also {
item.sourceImage?.let { image ->
it.image.setImageBitmap(image.toBitmap())
it.image.setImageBitmap(image.toBitmap()?.getOrNull())
}
it.barcodeFormat.text = item.format.name
it.docFormat.text = item.extractedDocument?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class BarcodeScanAndCountViewActivity : AppCompatActivity() {
nextButton = findViewById(R.id.nextButton)
snapResult = findViewById(R.id.snapped_message)

val scanner = ScanbotSDK(this).createBarcodeScanner()
val scanner = ScanbotSDK(this).createBarcodeScanner().getOrThrow()
scanner.setConfiguration(scanner.copyCurrentConfiguration().copy().apply {
setBarcodeFormats(barcodeFormats = BarcodeTypeRepository.selectedTypes.toList())
} )
Expand Down
Loading