Skip to main content

Barcode Scanner Classic UI Components | Android Document Scanner

Introduction

The Scanbot SDK provides the ability to scan and extract content from barcodes and QR codes. The result is encapsulated in a BarcodeScanningResult object as a list of BarcodeItem objects.

To provide better detection results, the Scanbot SDK supports the ability to accumulate multiple frames before running the detection. In this case, the Barcode Scanner will return empty results until the frames have been called a given number of times. The Barcode Scanner will then perform detection on the frame with the least amount of blur. This feature is intended for use with live detection.

The Barcode Scanner is available both as a RTU UI and as classic components (types of components are explained here).

Integration

Refer to our example project to see how to integrate the Barcode Scanner.

Add feature as a dependency

ScanbotBarcodeDetector is available with SDK Package 1. You have to add the following dependencies for it:

implementation("io.scanbot:sdk-package-1:$latestSdkVersion")
implementation("io.scanbot:sdk-barcode-assets:$latestSdkVersion")
caution

Please do not use multiple scanners at the same time. For example, do not combine generic document scanner, health insurance scanner, text data scanner, etc. at the same time! Each scanner instance requires a lot of memory, GPU, and processor resources. Using multiple scanners will lead to performance issues for the entire application.

Initialize the SDK

The Scanbot SDK must be initialized before use. Add the following code snippet to your Application class:

import io.scanbot.sdk.ScanbotSDKInitializer

class ExampleApplication : Application() {

override fun onCreate() {
super.onCreate()

// Initialize the Scanbot Scanner SDK:
ScanbotSDKInitializer().initialize(this)
}
}
caution

ScanbotSDKInitializer#prepareBarcodeScannerBlobs(true) is deprecated and removed from the API. All Barcode Scanner assets will be prepared automatically if the appropriate assets dependency is added.

caution

Unfortunately, we have noticed that all devices using a Cortex A53 processor DO NOT SUPPORT GPU acceleration. If you encounter any problems, please disable GPU acceleration for these devices.

ScanbotSDKInitializer()
.allowGpuAcceleration(false)

Full API references for these methods can be found on this page and this page.

Handling the result

Below is a simple example of presenting the result: BarcodeScanningResult data separated by a newline character, shown in a Toast notification.

val barcodeData = result.result!!
val barcodesTextResult = StringBuilder()
for (item in barcodeData.barcodeItems) {
barcodesTextResult.append(item.barcodeFormat.name + "\n" + item.text)
.append("\n")
.append("-------------------")
.append("\n")
}
Toast.makeText(this@MainActivity, barcodesTextResult.toString(), Toast.LENGTH_LONG).show()

Classic component

To integrate the classic component of the Barcode Scanner, you can have a look at our Barcode Scanner example apps or check the following step-by-step integration instructions.

Add feature dependencies and initialize the SDK

First of all, you have to add the SDK package and feature dependencies as described here.

Initialize the SDK as described here. More information about the SDK license initialization can be found here.

Integration of classic SDK components

Use the class BarcodeScannerView, which encapsulates the Barcode Scanning feature in one UI component. When using the BarcodeScannerView component, it is not required to work directly with the Camera view or to set up a finder view separately. Simply follow the steps below and you are ready to go.

To start using the barcode feature, add the following view into your layout XML:

    <io.scanbot.sdk.barcode.ui.BarcodeScannerView
android:id="@+id/barcode_scanner_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Then configure the view using the following calls:

barcodeScannerView = findViewById(R.id.barcode_scanner_view)
val barcodeDetector = ScanbotBarcodeScannerSDK(this).createBarcodeDetector()
barcodeDetector.modifyConfig {
// set the supported barcode formats here
setBarcodeFormats(BarcodeFormat.COMMON_CODES)
setSaveCameraPreviewFrame(false)
}
// both calls initCamera and initDetectionBehavior are required
barcodeScannerView.apply {
initCamera(CameraUiSettings(false))
initDetectionBehavior(barcodeDetector,
{ result ->
if (result is FrameHandlerResult.Success) {
// process the scanned result here
handleSuccess(result)
}
false
},
object : IBarcodeScannerViewCallback {
override fun onCameraOpen() {
barcodeScannerView.viewController.useFlash(flashEnabled)
}
override fun onPictureTaken(image: ByteArray, captureInfo: CaptureInfo) {
// process the full size images taken by BarcodeAutoSnappingController here
// to enable auto snapping use the following command:
// barcodeScannerView.viewController.autoSnappingEnabled = true
}
}
)
}

Delegate the methods onResume and onPause in your Activity class (or Fragment) to BarcodeScannerView:

class MyActivity : AppCompatActivity() {

...

override fun onResume() {
super.onResume()
barcodeScannerView.viewController.onResume()
}

override fun onPause() {
super.onPause()
barcodeScannerView.viewController.onPause()
}
}

It is possible to configure the finder view using the following commands:

// To disable the finder view
barcodeScannerView.finderViewController.setFinderEnabled(false)
// To set the required aspect ratio
barcodeScannerView.finderViewController.setRequiredAspectRatios(listOf(FinderAspectRatio(4.0, 1.0)))

You may also configure the camera or the behavior of the scanner using the corresponding configuration controllers:

// To switch to the front camera
barcodeScannerView.cameraConfiguration.setCameraModule(CameraModule.FRONT)
// To call the take picture function of the camera
barcodeScannerView.viewController.takePicture()

Classic components: alternative approach

Instead of using a single BarcodeScannerView, to get more flexibility you can also use the classes ScanbotCameraXView, BarcodeDetectorFrameHandler, ScanbotBarcodeDetector, BarcodeScannerConfig and BarcodeAutoSnappingController to build a custom scanner UI for barcode and QR code scanning.

Add ScanbotCameraXView to layout

<io.scanbot.sdk.ui.camera.ScanbotCameraXView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Get ScanbotBarcodeDetector instance from ScanbotSDK, and attach it to ScanbotCameraXView

val scanbotSdk = ScanbotSDK(this)
val barcodeDetector = scanbotSdk.createBarcodeDetector();
val barcodeDetectorFrameHandler = BarcodeDetectorFrameHandler.attach(cameraView, barcodeDetector);

Add a result handler for BarcodeDetectorFrameHandler:

You have to connect the ScanbotCameraXView with BarcodeDetectorFrameHandler and BarcodeAutoSnappingController. The ScanbotBarcodeDetector can be used to detect and parse barcodes from still images (Bitmap), e.g. JPG files from the photo library or other sources. Add a result handler for BarcodeDetectorFrameHandler:

barcodeDetectorFrameHandler.addResultHandler(object : BarcodeDetectorFrameHandler.ResultHandler {

override fun handle(result: FrameHandlerResult<BarcodeScanningResult?, SdkLicenseError>): Boolean {
when (result) {
is FrameHandlerResult.Success -> {
val detectedBarcodes = result.value
// do something with result here
}
is FrameHandlerResult.Failure -> {
// handle license error here
}
}

return false
}
})

Please refer to the full example implementation of a fully customizable Activity in our demo.

Additional configuration

Some peculiar use cases require special handling. For example, we can configure ScanbotBarcodeDetector to scan only barcodes of pre-specified lengths. This can reduce the number of false scans. Such parameters work only for enumerated types of barcodes and, usually, you don't need to modify their default values.

You can specify these parameters via the BarcodeScannerAdditionalConfig entity as a part of BarcodeScannerConfig:

val barcodeDetector = ScanbotSDK(context).createBarcodeDetector()
val additionalConfig = BarcodeScannerAdditionalConfig(
minimumTextLength = 0,
maximumTextLength = 0,
minimum1DQuietZoneSize = 10,
gs1DecodingEnabled = true,
lowPowerMode = false
)
val config = BarcodeScannerConfig(
additionalConfig = additionalConfig,
// modify other parameters
)
barcodeDetector.setConfig(config)

Alternatively, you can utilize methods modifyConfig and modifyAdditionalConfig to only edit some of the parameters:

barcodeDetector.modifyConfig {
modifyAdditionalConfig {
setMinimumTextLength(0)
setMaximumTextLength(0)
setMinimum1DQuietZoneSize(10)
setStripCheckDigits(false)
lowPowerMode(false)
setGs1HandlingMode(Gs1Handling.PARSE)
}
// modify other parameters
}

The parameters currently available in BarcodeScannerAdditionalConfig are:

  • minimumTextLength: Minimum required text length of the detected barcode. The default value is 0 (the setting is turned off). Currently only works for ITF and MSI Plessey barcodes!
  • maximumTextLength: Maximum text length of the detected barcode. Setting it to zero removes the limit. The default value is 0 (the setting is turned off). Currently only works for ITF and MSI Plessey barcodes!
  • minimum1DQuietZoneSize: Minimum required quiet zone of the barcode. Measured in modules (the minimum size of bar in a barcode). The default value is 10. Currently only works for ITF and MSI Plessey barcodes!
  • stripCheckDigits: when set to true, check digits for UPC, EAN and MSI Plessey codes are removed from the result. Has no effect if both single and double digit MSI Plessey checksums are enabled. The default is false.
  • gs1HandlingMode: GS1 handling mode. Available modes: Gs1Handling.NONE, Gs1Handling.PARSE, Gs1Handling.VALIDATE, Gs1Handling.DECODE. The default is Gs1Handling.PARSE. For more information, refer to the API references here.

Add a finder overlay

It is recommended to add a finder overlay. This feature allows you to predefine a barcode area over the ScanbotCameraXView screen. By using this overlay, the Barcode Scanner can skip the time-consuming step of searching for the barcode area and perform the recognition directly in the specified finder overlay area. By using this approach, the Barcode Scanner recognizes and extracts the barcode content much faster.

Details about applying finder view logic in the layout and in the code can be found here.

Manual data parsing

For manually parsing a decoded barcode string into formatted document data, use BarcodeDocumentParser.

val scanbotSDK = ScanbotSDK(context);
scanbotSDK.createBarcodeDocumentParser().parseDocument(barcodeString)

Want to scan longer than one minute?

Generate your free "no-strings-attached" Trial License and properly test the Scanbot SDK.

Get your free Trial License

What do you think of this documentation?