Skip to content

ZXing Android Embedded tutorial – integrating a barcode scanner in Android Studio

Kevin August 8, 2024 20 mins read
app store

ZXing is an open-source project that provides a barcode image processing library. ZXing Android Embedded is a standalone library that facilitates barcode scanning within Android applications.

In this tutorial, we’ll show you how to use ZXing Android Embedded to integrate a barcode scanner into your Android app using Kotlin and Android Studio.

To achieve this, we’ll do the following:

  1. Create a new Android project
  2. Add the ZXing dependencies
  3. Create the app layout
  4. Configure the app activity
  5. Change the orientation
  6. Run the app

Let’s get started! 🧑🏻‍💻

Step 1: Create a new Android project

To create a new Android project, launch Android Studio and follow the steps below:

  1. On the welcome screen, click on New Project. If Android Studio is already open, on the top menu, select File > New > New Project.
  2. On the new window, select Phone and Tablet and choose the Empty Views Activity. Click Next.
  3. Set the following project configurations:
    1. Name: Choose a name for your app. In this tutorial, we’ll go with BarcodeScanner.
    2. Package Name: This field is automatically populated based on your project name.
    3. Save Location: Select a directory to save your project.
    4. Language: Choose the programming language (Java or Kotlin). To follow this guide, select Kotlin.
    5. Minimum SDK: Select the minimum Android version your app will support. Fewer devices will support the newer versions. For this tutorial, choose API 24(“Nougat”; Android 7.0).
  4. Click Finish to create your project.

When you create the new project, Android Studio will make the necessary configurations and build the modules. After this is finished, you should see a project with an organization similar to the one below.

Step 2: Add the ZXing dependencies

To start, you have to add ZXing to your project dependencies. First, add ZXing to your project’s libraries:

  1. Open the libs.versions.toml file.
  2. Under [versions] add scanner = "4.3.0".
  3. Under [libraries] add scanner = { group = "com.journeyapps", name = "zxing-android-embedded", version.ref = "scanner" }. Here, you are including the library and naming it as scanner, which you will use to add to your project.

The libs.versions.tom file should look something like this:

[versions]
agp = "8.4.0"
kotlin = "1.9.0"
coreKtx = "1.13.1"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
appcompat = "1.7.0"
material = "1.12.0"
activity = "1.9.0"
scanner = "4.3.0" 
constraintlayout = "2.1.4"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
scanner = { group = "com.journeyapps", name = "zxing-android-embedded", version.ref = "scanner" }


[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

Afterwards, you have to include the library in your project’s build.gradle.kts (Modular :app) using the scanner name:

  1. Open the build.gradle.kts (Modular :app) file.
  2. Add implementation(libs.scanner) within dependencies.

The build.gradle.kts (Modular :app) file should look like this:

plugins {
   alias(libs.plugins.android.application)
   alias(libs.plugins.jetbrains.kotlin.android)
}

android {
   namespace = "com.example.barcodescanner"
   compileSdk = 34

   defaultConfig {
       applicationId = "com.example.barcodescanner"
       minSdk = 24
       targetSdk = 34
       versionCode = 1
       versionName = "1.0"

       testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
   }

   buildTypes {
       release {
           isMinifyEnabled = false
           proguardFiles(
               getDefaultProguardFile("proguard-android-optimize.txt"),
               "proguard-rules.pro"
           )
       }
   }
   compileOptions {
       sourceCompatibility = JavaVersion.VERSION_1_8
       targetCompatibility = JavaVersion.VERSION_1_8
   }
   kotlinOptions {
       jvmTarget = "1.8"
   }
}

dependencies {

   implementation(libs.androidx.core.ktx)
   implementation(libs.androidx.appcompat)
   implementation(libs.material)
   implementation(libs.androidx.activity)
   implementation(libs.androidx.constraintlayout)
   implementation(libs.scanner)
   testImplementation(libs.junit)
   androidTestImplementation(libs.androidx.junit)
   androidTestImplementation(libs.androidx.espresso.core)
}

Step 3: Create the app layout

Before using the functionalities provided by the ZXing library, you need to add the visual elements to your app to enable the user to interact with it. For this tutorial, the app is composed of two elements:

  • A Button the user will use to start the scanning process.
  • A TextView to display the bar code after finishing the scanning process.

To add the above components to your app, open the activity_main.xml file, which you will find under app > res > layout. Replace the existing content with the following code.

💡 If you open the activity_main.xml file and no code appears on your screen, click the Split button at the top right of Android Studio.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/main"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="@android:color/white"
   tools:context=".MainActivity">

   <!-- Button for starting the barcode scanning process -->
   <Button
       android:id="@+id/scanBtn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Scan Barcode"
       app:layout_constraintBottom_toBottomOf="parent"
       android:layout_marginBottom="250dp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintHorizontal_bias="0.5"
       app:layout_constraintStart_toStartOf="parent" />

   <!-- TextView to display the scanned barcode value -->
   <TextView
       android:id="@+id/scannedValue"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Scanned Value"
       android:textColor="@android:color/black"
       android:textSize="20sp"
       android:textStyle="bold"
       app:layout_constraintTop_toBottomOf="@id/scanBtn"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

The configurations used for each component are described in the following tables.

Button
AttributeDescription
android:id="@+id/scanBtn"Unique identifier for the Button.
android:layout_width="wrap_content"The width of the Button is set to wrap its content.
android:layout_height="wrap_content"The height of the Button is set to wrap its content.
android:text="Scan Bar Code"The text displayed on the Button.
app:layout_constraintBottom_toBottomOf="parent"Constraint to align the bottom of the Button with the bottom of the parent layout.
android:layout_marginBottom="250dp"Margin at the bottom of the Button.
app:layout_constraintEnd_toEndOf="parent"Constraint to align the end (right) of the Button with the end (right) of the parent layout.
app:layout_constraintHorizontal_bias="0.5"Horizontal bias to center the Button horizontally.
app:layout_constraintStart_toStartOf="parent"Constraint to align the start (left) of the Button with the start (left) of the parent layout.
TextView
AttributeDescription
android:id="@+id/scannedValue"Unique identifier for the TextView.
android:layout_width="wrap_content"The width of the TextView is set to wrap its content.
android:layout_height="wrap_content"The height of the TextView is set to wrap its content.
android:text="Scanned Value"The text displayed in the TextView.
android:textColor="@android:color/black"The color of the text is set to black.
android:textSize="20sp"The size of the text is set to 20sp (scaled pixels).
android:textStyle="bold"The text style is set to bold.
app:layout_constraintTop_toBottomOf="@id/scanBtn"Constraint to align the top of the TextView with the bottom of the Button.
app:layout_constraintBottom_toBottomOf="parent"Constraint to align the bottom of the TextView with the bottom of the parent layout.
app:layout_constraintEnd_toEndOf="parent"Constraint to align the end (right) of the TextView with the end (right) of the parent layout.
app:layout_constraintStart_toStartOf="parent"Constraint to align the start (left) of the TextView with the start (left) of the parent layout.

After setting up the above configuration on the activity_main.xml file, Android Studio should present an app preview.

Step 4: Configure the app activity

After adding the components, it’s time to configure the app functionalities. At this step, you will define the functions that define the Button and TextView behaviour.

To start, open the MainActivity.kt file, which you will find under app > kotling+java > com.example.barcodescanner.

First, declare a Button and a TextView variable within the MainActivity class. Then, override the onCreate function to assign the Button and TextView variables to respective Ids defined in the activity_main.xml file. After that, add the registerUiListener() function, which you will define next. The beginning of the MainActivity class should be equal to the content of the following code block:

class MainActivity : AppCompatActivity() {

    private lateinit var scanBtn: Button
    private lateinit var scannedValue: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        scanBtn = findViewById(R.id.scanBtn)
        scannedValue = findViewById(R.id.scannedValue)

        registerUiListener()
    }

Next, you have to define the registerUiListener() function. The registerUiListener method sets up an OnClickListener for the scanBtn button. When someone clicks the button, it triggers the scannerLauncher to launch the barcode scanner. At this point, you can specify the options to define the scanner behaviour. Check ScanOptions.java to see all the available options. This tutorial uses the following options:

  • setPrompt("Scan Barcode"): Specifies the text that will appear when the app accesses the camera to scan the barcode.
  • .setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES): Defines that only one-dimensional codes will be identified.

The following code block presents the registerUiListener() code.

private fun registerUiListener() {
   scanBtn.setOnClickListener {
       scannerLauncher.launch(
           ScanOptions().setPrompt("Scan Barcode")
               .setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES)
       )
   }
}

Last, you need to define the behaviour of the TextView after a barcode is scanned. For this, you will add the scannerLauncher activity, which will handle the result of the barcode scanning activity. Use the registerForActivityResult method to register it with a ScanContract. You also have to specify the callback function to handle the scan result. In this tutorial, the callback has the following behaviour:

  • The app displays a Canceled message if the scan was cancelled, meaning no content was scanned.
  • If the scan is successful, the app updates the scannedValue TextView with the scanned barcode contents, formatted as Scanned Value: [result].

The following code block presents the scannerLauncher code.

private val scannerLauncher = registerForActivityResult<ScanOptions, ScanIntentResult>(
   ScanContract()
) { result ->

   if (result.contents == null) {
       Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show()
   } else {
       scannedValue.text = buildString {
           append("Scanned Value : ")
           append(result.contents)
       }
   }

}

After adding all configurations, the MainActivity.kt file should have the following content:

package com.example.barcodescanner

import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.google.zxing.client.android.Intents.Scan
import com.journeyapps.barcodescanner.CaptureActivity
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions

class MainActivity : AppCompatActivity() {

   private lateinit var scanBtn: Button
   private lateinit var scannedValue: TextView

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       scanBtn = findViewById(R.id.scanBtn)
       scannedValue = findViewById(R.id.scannedValue)

       registerUiListener()
   }

   private fun registerUiListener() {
       scanBtn.setOnClickListener {
           scannerLauncher.launch(
               ScanOptions().setPrompt("Scan Barcode")
                   .setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES)
           )
       }
   }

   private val scannerLauncher = registerForActivityResult<ScanOptions, ScanIntentResult>(
       ScanContract()
   ) { result ->

       if (result.contents == null) {
           Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show()
       } else {
           scannedValue.text = buildString {
               append("Scanned Value : ")
               append(result.contents)
           }
       }

   }
}

Step 5: Change the orientation

By default, the ZXing Android Embedded uses landscape mode. To change this behaviour, you must change the AndroidManifest.xml file, which you find under app > manifests.

In the AndroidManifest.xml file, you have to add a new CaptureActivity to ensure the scanning interface is always in portrait orientation. The following code block presents the code you need to add to the file:

<activity android:name="com.journeyapps.barcodescanner.CaptureActivity"
            android:screenOrientation="portrait"
            tools:replace="screenOrientation"/>

In the above code, the tools:replace="screenOrientation" attribute informs the Android tools that this activity’s screenOrientation attribute should replace any previously declared screenOrientation attribute for this activity.

Step 6: Run the app

After completing the four steps, you can test the app’s final result. To test the app, you can connect your Android phone to your computer and enable the Developer Options, or use Virtual Devices. If you have never tested an app using Android Studio, you can check one of the following guides:

Before running the app, be sure to:

  • Save all files: Click File > Save All.
  • Sync the project: Click File > Sync Project with Gradle Files.

Build the project without any errors:  On the top menu, click Build > Rebuild Project. You should see the BUILD SUCCESSFUL in the Android Studio terminal.

Disadvantages of using the ZXing barcode scanner library

ZXing provides decent performance for basic barcode scanning tasks but sometimes struggles with more challenging scenarios. Its most notable drawbacks as a barcode scanning solution include:

  • Scanning accuracy and speed: ZXing struggles with scanning poorly lit or damaged barcodes. It often exhibits low recognition rates for smaller barcodes and can fail to decode them altogether.
  • Compatibility issues: ZXing may not perform reliably across all devices, particularly newer models. This has led to frustration among developers who require consistent performance across different platforms.
  • Lack of active development: As an open-source project, ZXing has seen limited updates and maintenance in recent years. This stagnation can lead to unresolved bugs and compatibility issues, making it less reliable for commercial applications.
  • Integration complexity: Integrating ZXing into your app can be cumbersome, especially for developers who may not be familiar with its architecture. This can lead to longer development times and increased chances of bugs during implementation.

For companies that heavily rely on barcode scanning in their business processes, we recommend using an enterprise-grade solution instead.

Building an Android Barcode Scanner with the Scanbot SDK

We developed the Scanbot Barcode Scanner SDK as a commercial solution to help enterprises overcome these hurdles presented by free barcode scanning software. Our goal was to have a developer-friendly solution available for a wide range of platforms that consistently delivers high-quality results – even in challenging circumstances.

In the following tutorial, we’ll use Android Studio and the Scanbot SDK Android Barcode Scanner library to create a simple app offering three different scanning modes: scanning one barcode at a time, multiple barcodes at once, and displaying the barcode values in the viewfinder using the SDK’s AR overlay.

Scanning a single barcode
Scanning a single barcode
Scanning multiple barcodes with the AR overlay
Scanning multiple barcodes with the AR overlay

We’ll achieve this in five steps:

  1. Prepare the project
  2. Initialize the SDK
  3. Set up the main screen
  4. Implement the scanning modes
  5. Scan some barcodes!

All you need is the latest version of Android Studio and you’re good to go.

Step 1: Preparing the project

Create a new Empty View Activity and name the project (e.g., “Android Barcode Scanner”).

When your project is ready, go to settings.gradle.kts and add the Maven repositories for our SDK:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()

        // Add the repositories here:
        maven(url = "https://nexus.scanbot.io/nexus/content/repositories/releases/")
        maven(url = "https://nexus.scanbot.io/nexus/content/repositories/snapshots/")
    }
}

Now go to app/build.gradle.kts and add the dependencies for the Scanbot SDK and the RTU UI:

dependencies {
    implementation("io.scanbot:scanbot-barcode-scanner-sdk:5.2.0")
    implementation("io.scanbot:rtu-ui-v2-barcode:5.2.0")

Sync the project.

💡 We use Barcode Scanner SDK version 5.2.0 in this tutorial. You can find the latest version in the changelog.

Since we need to access the device camera to scan barcodes, let’s also add the necessary permissions in AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />

    <application
    ...

Step 2: Initializing the SDK

Before we can use the Scanbot Barcode Scanner SDK, we need to initialize it. The recommended approach is to do it in your Application implementation. This ensures the SDK is correctly initialized even when the app’s process is restored after being terminated in the background.

First, we need to create an Application subclass by right-clicking on the folder app/kotlin+java/com.example.androidbarcodescanner, selecting New > Kotlin Class/File, and naming it (e.g. “ExampleApplication”).

In the resulting ExampleApplication.kt, let’s first add the necessary imports:

import android.app.Application
import io.scanbot.sdk.barcode_scanner.ScanbotBarcodeScannerSDKInitializer

Then we make ExampleApplication extend the Application class by adding : Application() and add the code for initializing the SDK inside it:

class ExampleApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ScanbotBarcodeScannerSDKInitializer()
            // Optional: uncomment the next line if you have a license key.
            // .license(this, LICENSE_KEY)
            .initialize(this)
    }
}

💡 Without a license key, our SDK only runs for 60 seconds per session. This is more than enough for the purposes of our tutorial, but if you like, you can generate a license key. Just make sure to change your applicationId in app/build.gradle.kts to io.scanbot.androidbarcodescanner and use that ID for generating the license.

Finally, we need to register the Example Application class in AndroidManifest.xml:

<application
   android:name=".ExampleApplication"
   ...

Step 3: Setting up the main screen

We’re going to build a rudimentary UI so we can quickly access the different scanning modes in our finished app.

For this tutorial, we’re going to go with this simple three-button layout, which you can copy into app/res/layout/activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_single_scanning"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Single-barcode scanning"
        app:layout_constraintBottom_toTopOf="@id/btn_multi_scanning"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="20dp" />

    <Button
        android:id="@+id/btn_multi_scanning"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Multi-barcode scanning"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp" />

    <Button
        android:id="@+id/btn_ar_overlay"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="AR overlay"
        app:layout_constraintTop_toBottomOf="@id/btn_multi_scanning"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="20dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

Step 4: Implementing the scanning modes

Now we’ll connect each button with one of our RTU UI’s scanning modes, starting with single-barcode scanning.

Go to MainActivity.kt and add the necessary imports:

import android.widget.Button
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import io.scanbot.sdk.ui_v2.barcode.BarcodeScannerActivity
import io.scanbot.sdk.ui_v2.common.activity.registerForActivityResultOk
import io.scanbot.sdk.ui_v2.barcode.common.mappers.COMMON_CODES
import io.scanbot.sdk.ui_v2.barcode.configuration.BarcodeFormat
import io.scanbot.sdk.ui_v2.barcode.configuration.CollapsedVisibleHeight
import io.scanbot.sdk.ui_v2.barcode.configuration.BarcodeScannerConfiguration
import io.scanbot.sdk.ui_v2.barcode.configuration.MultipleBarcodesScanningMode
import io.scanbot.sdk.ui_v2.barcode.configuration.MultipleScanningMode
import io.scanbot.sdk.ui_v2.barcode.configuration.SheetMode
import io.scanbot.sdk.ui_v2.barcode.configuration.SingleScanningMode
import io.scanbot.sdk.ui_v2.common.ScanbotColor

With that out of the way, let’s implement the first scanning mode.

Single-barcode scanning

In the MainActivity class, add a private property that we’ll use to launch the barcode scanner.

private val barcodeResultLauncher: ActivityResultLauncher<BarcodeScannerConfiguration> =
        registerForActivityResultOk(BarcodeScannerActivity.ResultContract()) { resultEntity ->
        // Barcode Scanner result callback:
        // Get the first scanned barcode from the result object...
        val barcodeItem = resultEntity.result?.items?.first()
        // ... and process the result as needed. For example, display as a Toast:
        Toast.makeText(
            this,
            "Scanned: ${barcodeItem?.text} (${barcodeItem?.type})",
            Toast.LENGTH_LONG
        ).show()
    }

Next, in the onCreate() method, we set up an OnClickListener for our Single-barcode scanning button. When the button is clicked, it should launch barcodeResultLauncher using a configuration object we’ll set up in the next step:

        findViewById<Button>(R.id.btn_single_scanning).setOnClickListener {
            barcodeResultLauncher.launch(config)
        }

Now paste the configuration for the RTU UI’s single-barcode scanning mode (from the documentation) above barcodeResultLauncher.launch(config):

        findViewById<Button>(R.id.btn_single_scanning).setOnClickListener {
            val config = BarcodeScannerConfiguration().apply {
                // Configure parameters (use explicit `this.` receiver for better code completion):

                // Initialize the use case for single scanning.
                this.useCase = SingleScanningMode().apply {
                    // Enable and configure the confirmation sheet.
                    this.confirmationSheetEnabled = true
                    this.sheetColor = ScanbotColor("#FFFFFF")

                    // Hide/unhide the barcode image.
                    this.barcodeImageVisible = true

                    // Configure the barcode title of the confirmation sheet.
                    this.barcodeTitle.visible = true
                    this.barcodeTitle.color = ScanbotColor("#000000")

                    // Configure the barcode subtitle of the confirmation sheet.
                    this.barcodeSubtitle.visible = true
                    this.barcodeSubtitle.color = ScanbotColor("#000000")

                    // Configure the cancel button of the confirmation sheet.
                    this.cancelButton.text = "Close"
                    this.cancelButton.foreground.color = ScanbotColor("#C8193C")
                    this.cancelButton.background.fillColor = ScanbotColor("#00000000")

                    // Configure the submit button of the confirmation sheet.
                    this.submitButton.text = "Submit"
                    this.submitButton.foreground.color = ScanbotColor("#FFFFFF")
                    this.submitButton.background.fillColor = ScanbotColor("#C8193C")

                    // Configure other parameters, pertaining to single-scanning mode as needed.
                }

                // Set an array of accepted barcode types.
                this.recognizerConfiguration.barcodeFormats = BarcodeFormat.COMMON_CODES

                // Configure other parameters as needed.
            }
            barcodeResultLauncher.launch(config)
        }

If you want, you can run the app to try out the single-barcode scanning feature before we move on to the next mode.

Android Barcode Scanner SDK integration tutorial

Multi-barcode scanning

Set up another OnClickListener, this time for the Multi-barcode scanning button …

        findViewById<Button>(R.id.btn_multi_scanning).setOnClickListener {
            barcodeResultLauncher.launch(config)
        }

… and paste in the configuration for multi-scanning above barcodeResultLauncher.launch(config):

        findViewById<Button>(R.id.btn_multi_scanning).setOnClickListener {
            val config = BarcodeScannerConfiguration().apply {
                // Configure parameters (use explicit `this.` receiver for better code completion):

                // Initialize the use case for multiple scanning.
                this.useCase = MultipleScanningMode().apply {
                    // Set the counting mode.
                    this.mode = MultipleBarcodesScanningMode.COUNTING

                    // Set the sheet mode for the barcodes preview.
                    this.sheet.mode = SheetMode.COLLAPSED_SHEET

                    // Set the height for the collapsed sheet.
                    this.sheet.collapsedVisibleHeight = CollapsedVisibleHeight.LARGE

                    // Enable manual count change.
                    this.sheetContent.manualCountChangeEnabled = true

                    // Set the delay before same barcode counting repeat.
                    this.countingRepeatDelay = 1000

                    // Configure the submit button.
                    this.sheetContent.submitButton.text = "Submit"
                    this.sheetContent.submitButton.foreground.color = ScanbotColor("#000000")

                    // Configure other parameters, pertaining to multiple-scanning mode as needed.
                }

                // Set an array of accepted barcode types.
                this.recognizerConfiguration.barcodeFormats = BarcodeFormat.COMMON_CODES

                // Configure other parameters as needed.
            }
            barcodeResultLauncher.launch(config)
        }

Try it out if you like and then move on to the final scanning mode.

Android Barcode Scanner SDK integration tutorial

AR overlay

You know the drill. Set up an OnClickListener

        findViewById<Button>(R.id.btn_ar_overlay).setOnClickListener {
            barcodeResultLauncher.launch(config)
        }

… and paste in the configuration for the AR overlay:

        findViewById<Button>(R.id.btn_ar_overlay).setOnClickListener {
            findViewById<Button>(R.id.btn_ar_overlay).setOnClickListener {
                val config = BarcodeScannerConfiguration().apply {
                    // Configure parameters (use explicit `this.` receiver for better code completion):


                    // Configure the use case.
                    this.useCase = MultipleScanningMode().apply {
                        this.mode = MultipleBarcodesScanningMode.UNIQUE
                        this.sheet.mode = SheetMode.COLLAPSED_SHEET
                        this.sheet.collapsedVisibleHeight = CollapsedVisibleHeight.SMALL
                        // Configure AR Overlay.
                        this.arOverlay.visible = true
                        this.arOverlay.automaticSelectionEnabled = false

                        // Configure other parameters, pertaining to use case as needed.
                    }

                    // Set an array of accepted barcode types.
                    this.recognizerConfiguration.barcodeFormats = BarcodeFormat.COMMON_CODES

                    // Configure other parameters as needed.
                }
                barcodeResultLauncher.launch(config)
            }
        }

Build and run the app… and that’s it! 🎉

Step 5: Scanning some barcodes!

You can now scan barcodes one at a time, multiple barcodes in one go, and display their values on the screen via the AR overlay.

Android Barcode Scanner SDK integration tutorial

Conclusion

If this tutorial has piqued your interest in integrating barcode scanning functionalities into your Android app, make sure to take a look at our SDK’s other neat features in our documentation – or run our example project for a more hands-on experience.

You can also try our Barcode Scanner demo app for a more feature-rich implementation of our SDK – just scan the following QR code:

Should you have questions about this tutorial or run into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io.

Happy coding!