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:
- Create a new Android project
- Add the ZXing dependencies
- Create the app layout
- Configure the app activity
- Change the orientation
- 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:
- On the welcome screen, click on New Project. If Android Studio is already open, on the top menu, select File > New > New Project.
- On the new window, select Phone and Tablet and choose the Empty Views Activity. Click Next.
- Set the following project configurations:
- Name: Choose a name for your app. In this tutorial, we’ll go with BarcodeScanner.
- Package Name: This field is automatically populated based on your project name.
- Save Location: Select a directory to save your project.
- Language: Choose the programming language (Java or Kotlin). To follow this guide, select Kotlin.
- 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).
- 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:
- Open the libs.versions.toml file.
- Under [versions] add
scanner = "4.3.0"
. - 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:
- Open the build.gradle.kts (Modular :app) file.
- 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 | |
Attribute | Description |
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 | |
Attribute | Description |
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.


We’ll achieve this in five steps:
- Prepare the project
- Initialize the SDK
- Set up the main screen
- Implement the scanning modes
- 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.

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.

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.

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!