Skip to main content

Barcode Scanner | Android Barcode Scanner

Ready To Use UI Components#

The Ready-To-Use UI (RTU UI) is a set of easy to integrate and customize high-level UI components (Activities) for the most common tasks in Scanbot Barcode Scanner SDK:

  • Barcode and QR-Code Scanner - BarcodeScannerActivity

The design and behavior of these ready-to-use Activities are based on our many years of experience as well as the feedback from our SDK customers.

Customization of RTU UI#

  • UI: All colors and text resources (localization).
  • Behavior: Enable or disable features like Flashlight, Barcode Filter, Image Snapping.

Please note: The main idea of the RTU UI is to provide simple-to-integrate and simple-to-customize Activity components. Due to this idea there are some limitations with the possibilities of customization. If you need more customization options you have to implement custom Activities using our "Classical SDK UI Components".

Integration of RTU UI#


The RTU UI components are distributed as a separate package scanbot-barcode-scanner-sdk-ui. Add it as a dependency to your project:

implementation "io.scanbot:scanbot-barcode-scanner-sdk-ui:$scanbotSdkVersion"

Get the latest $scanbotBarcodeSdkVersion from the Changelog.

Start RTU UI Activity#

// Create the configuration (customization):val barcodeCameraConfiguration = BarcodeScannerConfiguration()barcodeCameraConfiguration.setFlashEnabled(true)barcodeCameraConfiguration.setCancelButtonTitle("Cancel")barcodeCameraConfiguration.setFinderLineColor(Color.GREEN)barcodeCameraConfiguration.setBarcodeFormatsFilter(...)// set further config properties ...
// Create an Intent for the BarcodeScannerActivity with the configuration and start it:val intent = BarcodeScannerActivity.newIntent(this@MainActivity, barcodeCameraConfiguration)startActivityForResult(intent, MY_BARCODE_UI_REQUEST_CODE)

Receive Activity Result#

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {    ...    if (requestCode == MY_BARCODE_UI_REQUEST_CODE && resultCode == Activity.RESULT_OK) {        val barcodeScanningResult = data?.getParcelableExtra<BarcodeScanningResult>(BaseBarcodeScannerActivity.SCANNED_BARCODE_EXTRA)        // handle the result:        barcodeScanningResult.barcodeItems ...    }}

Additional RTU barcode scanning parameters#

Please see chapter Additional configuration below to see some additional parameters description.

Full Example of the RTU UI Activity#

Please see this full example implementation in our demo:

๐Ÿ‘‰ MainActivity.kt

Classical SDK Components#

Our Classical SDK Components allows you to build your custom UI Activities which are very flexible and fully customizable. It is a set of easy to integrate and customize Views, Handlers, Controllers, etc. which can be used in your Activities to implement the most common tasks in Scanbot Barcode Scanner SDK.


  • UI: Fully customizable
  • Behavior: Fully customizable

Integration of Classical SDK Components#

Use the classes ScanbotCameraView, BarcodeDetectorFrameHandler, ScanbotBarcodeDetector, BarcodeScannerConfig and BarcodeAutoSnappingController to build a custom scanner UI for Barcode and QR-Code scanning.


The Android camera API might seem to be very tricky and far from being developer-friendly (in fact, very far). To help you avoid the same issues which we have encountered while developing Scanbot SDK, we created the ScanbotCameraView.

Add it to your layout, which is as simple as:

    <        android:id="@+id/camera"        android:layout_width="match_parent"        android:layout_height="match_parent" />

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

class MyActivity : AppCompatActivity() {
    override fun onResume() {        super.onResume()        cameraView?.onResume()    }
    override fun onPause() {        super.onPause()        cameraView?.onPause()    }}

That is it! You can start your app and you should see the camera preview.

Preview Mode

The ScanbotCameraView supports 2 preview modes:

  • CameraPreviewMode.FIT_IN - in this mode camera preview frames will be downscaled to the layout view size. Full preview frame content will be visible, but unused edges could appear in the preview layout.
  • CameraPreviewMode.FILL_IN - in this mode camera preview frames fill the layout view. The preview frames may contain additional content at the edges that is not visible in the preview layout.

By default, ScanbotCameraView uses FILL_IN mode. You can change it using the cameraView.setPreviewMode(CameraPreviewMode mode) method.

Autofocus Sound and Shutter Sound

You can enable/disable autofocus event system and shutter sounds using setters in ScanbotCameraView.

cameraView.setCameraOpenCallback(new CameraOpenCallback() {        @Override        public void onCameraOpened() {            cameraView.postDelayed(new Runnable() {                @Override                public void run() {                    cameraView.setAutoFocusSound(false);                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {                        cameraView.setShutterSound(false);                    }                }            }, 700);        }    });

cameraView.setShutterSound(boolean enabled) sets the camera shutter sound state. By default - true, the camera plays the system-defined camera shutter sound when takePicture() is called.

Note that devices may not always allow disabling the camera shutter sound. If the shutter sound state cannot be set to the desired value, this method will be ignored.

Additionally, this is only supported with Android API 17 and above.

Continuous Focus Mode#

For most use cases it is recommended to enable the "Continuous Focus Mode" of the Camera. Use the continuousFocus() method of ScanbotCameraView for this. It should be called from the main thread and only when the camera is opened (CameraOpenCallback):

cameraView = (ScanbotCameraView) findViewById(;cameraView.setCameraOpenCallback(new CameraOpenCallback() {    @Override    public void onCameraOpened() {        cameraView.postDelayed(new Runnable() {            @Override            public void run() {                cameraView.continuousFocus();            }        }, 700);    }});

Please note: The Continuous Focus Mode will be automatically disabled

  • after the autoFocus method call,
  • after a tap on the ScanbotCameraView to perform the autoFocus,
  • or after the takePicture event.

In these cases you have to call the continuousFocus() method again to re-enable the Continuous Focus Mode.

Orientation Lock

By default the ScanbotCameraView will create pictures with orientation based on the current device orientation. It is important to understand that the orientation of the taken picture is independent of the locked orientation mode of the Activity!

For example: if you just lock the Activity to portrait mode, the orientation of the taken image will still be based on the current device orientation!

To apply a real orientation lock in ScanbotCameraView, you can use the following methods: cameraView.lockToLandscape(boolean lockPicture) or cameraView.lockToPortrait(boolean lockPicture) to lock the Activity and the taken picture to a desired orientation:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    // ...
    cameraView = (ScanbotCameraView) findViewById(;
    // Lock the orientation of the Activity as well as the orientation of the taken picture to portrait:    cameraView.lockToPortrait(true);
    // ...}

Change the default storage directory#

It is strongly recommended to use the internal storage. However, you can override the default storage directory of the Scanbot SDK on initialization. The ScanbotBarcodeScannerSDKInitializer class provides the method sdkFilesDirectory(Application application, File sdkFilesDirectory) which allows changing the default storage directory.


import io.scanbot.sdk.barcode_scanner.ScanbotBarcodeScannerSDKInitializer;
// Example for using a sub-folder in the external(!) storage:File customStorageDir = new File(getExternalFilesDir(null), "my-custom-storage-dir");customStorageDir.mkdirs();
new ScanbotBarcodeScannerSDKInitializer()        .sdkFilesDirectory(this, customStorageDir)        ...        .initialize(this)

When overriding the default storage location, make sure

  • you have implemented a suitable storage permissions request handling
  • the storage directory is available (e.g. unmounted SD card).

Enable the page storage encryption#

By default an encryption for barcode images is disabled.

Scanbot Barcode Scanner SDK provides the ability to encrypt all stored barcode images in the SDK app folder.

To do this you have to follow the next steps:

  1. Add the Scanbot SDK Crypto Persistence library to your app dependencies
  1. Enable file encryption in ScanbotBarcodeScannerSDKInitializer
    ScanbotBarcodeScannerSDKInitializer()        .useFileEncryption(true)        .initialize(this)

And that's it!

Default Encryptor implementation uses the AndroidX Crypto solution under the hood. More info can be found here: The file encryptor uses AES256_GCM_HKDF_4KB file encryption scheme. More info here:


There are few limitations of encryption libraries usage:

  • security-crypto and security-identity-credential AndroidX libraries are still in development and have an Alpha version
  • Version 1.1.0-alpha02 of the Security library is supported on devices that run Android 7.0 (API level 24) and higher.

Furthermore, Scanbot SDK provides a custom AES based encryption solution io.scanbot.sdk.persistence.fileio.AESEncryptedFileIOProcessor. To enable it you have to set it in the SDK initializer in the useFileEncryption() method:

.useFileEncryption(true, AESEncryptedImageFileIOProcessor("any_user_password", AESEncryptedFileIOProcessor.AESEncrypterMode.AES256))

AESEncryptedFileIOProcessor does not save the password in any secure storage between app sessions, so you have to implement this by yourself and reuse it for SDK initialization.

Scanbot SDK allows setting up a completely custom encryption implementation. To do this you have to implement io.scanbot.sdk.persistence.fileio.FileIOProcessor interface and pass it to the useFileEncryption(true, your_file_io_processor) method.

An instance of FileIOProcessor will be available during the app session and the user can use it to read and copy decrypted image files and Bitmaps. For example:

val scanbotBarcodeScannerSDK = ScanbotBarcodeScannerSDK(context)val decryptedImageBitmap: Bitmap = scanbotBarcodeScannerSDK.fileIOProcessor().readImage(source: File, options: BitmapFactory.Options? = null)

Main configuration#

Scanbot SDK provides the ability to modify the default configuration of ScanbotBarcodeDetector. Here is an example how to specify a completely custom BarcodeScannerConfig:

val barcodeDetector = ScanbotBarcodeScannerSDK(this).createBarcodeDetector()val config = BarcodeScannerConfig(    barcodeFormats = BarcodeFormat.COMMON_CODES,    acceptedDocumentFormats = emptyList(),    engineMode = EngineMode.NextGen,    saveCameraPreviewFrame = false,    additionalConfig = BarcodeScannerAdditionalConfig())barcodeDetector.setConfig(config)

Alternatively, utilize method modifyConfig to edit only some of parameters:

barcodeDetector.modifyConfig {    setBarcodeFormats(BarcodeFormat.COMMON_CODE)    setEngineMode(EngineMode.NextGen)}

Parameters, currently available in BarcodeScannerConfig are:

  • barcodeFormats: list of BarcodeFormats to scan. Default is BarcodeFormat.COMMON_CODES
  • acceptedDocumentFormats: list of BarcodeDocumentFormats to scan. Default is the empty list, meaning no filtering is done and all formats are accepted.
  • engineMode: defines used Barcode Scanner EngineMode. Default is EngineMode.NextGen
  • saveCameraPreviewFrame: whether detector should save a frame with the successful detection result. If true - BarcodeScanningResult will contain the camera preview frame Bitmap, otherwise the preview frame will not be collected. Defaults to false.
  • additionalConfig: additional config for specific barcode types.

Additional configuration#

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

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

val barcodeDetector = ScanbotBarcodeScannerSDK(this).createBarcodeDetector()val additionalConfig = BarcodeScannerAdditionalConfig(    minimumTextLength = 0,    maximumTextLength = 0,    minimum1DQuietZoneSize = 10,    gs1DecodingEnabled = true,    msiPlesseyChecksumAlgorithms = EnumSet.of(MSIPlesseyChecksumAlgorithm.Mod10))val config = BarcodeScannerConfig(    additionalConfig = additionalConfig,    // modify other parameters    )barcodeDetector.setConfig(config)

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

barcodeDetector.modifyConfig {    modifyAdditionalConfig {        setMinimumTextLength(0)        setMaximumTextLength(0)        setMinimum1DQuietZoneSize(10)        setGs1DecodingEnabled(true)        setMsiPlesseyChecksumAlgorithms(EnumSet.of(MSIPlesseyChecksumAlgorithm.Mod10))    }    // modify other parameters}

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 works for ITF barcodes only!
  • maximumTextLength: maximum text length of the detected barcode. Setting to zero removes the limit. The default value is 0 (the setting is turned off). Currently works for ITF barcodes only!
  • minimum1DQuietZoneSize: minimum required quiet zone on the barcode. Measured in modules (the size of a minimal bar on the barcode). The default value is 10. Currently works for ITF barcodes only!
  • gs1DecodingEnabled: when set to true, the scanner assumes that the barcode can be a GS1 barcode. Turn it off, if you don't want to see decoded FNC1 characters ("]C1" and ASCII char 29). The default is true. Currently works for CODE128 barcodes only!
  • msiPlesseyChecksumAlgorithms: the checksum algorithms for MSI Plessey barcodes. The default value is MSIPlesseyChecksumAlgorithm.Mod10.

Full Example of a Custom Activity#

As a final step, you have to connect the ScanbotCameraView 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.

Please see this example implementation of a fully customizable Activity in our demo:

๐Ÿ‘‰ QRScanCameraViewActivity.kt