Skip to content

Building a PDF417 Scanner Android app in Kotlin

Kevin February 28, 2025 7 mins read
app store

In this tutorial, we’ll build an Android app for scanning PDF417 barcodes using Kotlin, Android Studio, and the Scanbot Android Barcode Scanner SDK.

The app will initially display a single “Start scanning” button. When clicked, the interface will open, enabling the user to scan a PDF417 code. After reading the barcode, the scanner will close, and the scanned value will be displayed on the screen. In an optional step, we’ll enhance the user experience by implementing an AR overlay and a confirmation dialog.

Scanning a PDF417 barcode with our barcode scanner web app
Scanning a PDF417 barcode and returning the result immediately
Scanning a PDF417 with the AR overlay and a confirmation dialog
Scanning a PDF417 barcode with an AR overlay and confirmation dialog

We’ll achieve this by …

  1. Preparing the project
  2. Initializing the SDK
  3. Setting up the main screen
  4. Implementing the barcode scanner
  5. Setting up PDF417 scanning
  6. Optional: Adjusting the scanning behavior

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

Step 1: Prepare the project

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

When your project is ready, go to settings.gradle.kts and add the Maven repositories for the Scanbot 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:6.2.1")
    implementation("io.scanbot:rtu-ui-v2-barcode:6.2.1")

Sync the project.

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

Since we need to access the device camera to scan PDF417 codes, 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: Initialize the SDK

Before we can use the 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 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 to generate the license.

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

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

Step 3: Set up the main screen

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

You can copy the following code for a simple one-button layout 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_pdf417_scanning"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Scan PDF417 Barcode"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.5" />

</androidx.constraintlayout.widget.ConstraintLayout>

Step 4: Implement the barcode scanner

Now we’ll connect the button with the RTU UI’s single-barcode scanning mode.

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.configuration.*

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 Scan PDF417 Barcode button. When the button is clicked, it launches barcodeResultLauncher using a configuration object.

findViewById<Button>(R.id.btn_pdf417_scanning).setOnClickListener {
    val config = BarcodeScannerConfiguration().apply {
    }
    barcodeResultLauncher.launch(config)
}

Step 5: Set up PDF417 scanning

As it is now, our scanner will read any barcode type. Restricting it to scanning only PDF417 codes prevents unintended scans and improves the scanner’s performance, as it doesn’t need to check each supported symbology. So let’s implement this in our code.

this.recognizerConfiguration.barcodeFormats = listOf(BarcodeFormat.PDF_417)

By default, the scanner has a square viewfinder. An PDF417 barcode is generally much wider than it is high, which we can convey to the user by adjusting the viewfinder’s aspect ratio accordingly.

this.viewFinder.aspectRatio.height = 1.0
this.viewFinder.aspectRatio.width = 3.0

The result should look something like this:

findViewById<Button>(R.id.btn_pdf417_scanning).setOnClickListener {
    val config = BarcodeScannerConfiguration().apply {
        // Restrict scanning to PDF417 barcodes
        this.recognizerConfiguration.barcodeFormats = listOf(BarcodeFormat.PDF_417)

        // Define the viewfinder's aspect ratio.
        this.viewFinder.aspectRatio.height = 1.0
        this.viewFinder.aspectRatio.width = 3.0
    }
    barcodeResultLauncher.launch(config)
}

Now build and run your app and scan a PDF417 code …

A PDF417 barcode for testing

… to test your scanner!

Scanning a PDF417 barcode with our barcode scanner web app

Optional: Adjust the scanning behavior

The way we set up our PDF417 barcode scanner is one way to do it, but with the Scanbot SDK, you can create all kinds of scanning experiences.

For example, you can remove the viewfinder entirely …

this.viewFinder.visible = false

… and display each PDF417 barcode’s value directly on the screen in real time while letting users tap on a barcode value to submit it.

this.arOverlay.visible = true
this.arOverlay.automaticSelectionEnabled = false

We can also display a confirmation dialog for each tapped barcode.

this.confirmationSheetEnabled = true

The result should look like this:

findViewById<Button>(R.id.btn_pdf417_scanning).setOnClickListener {
    val config = BarcodeScannerConfiguration().apply {
        // Initialize the use case for single scanning.
        this.useCase = SingleScanningMode().apply {
            // Enable the AR overlay and disable automatic selection
            this.arOverlay.visible = true
            this.arOverlay.automaticSelectionEnabled = false

            // Enable the confirmation dialog
            this.confirmationSheetEnabled = true
        }
        // Restrict scanning to PDF417 barcodes
        this.recognizerConfiguration.barcodeFormats = listOf(BarcodeFormat.PDF_417)

        // Define the viewfinder's aspect ratio.
        this.viewFinder.aspectRatio.height = 1.0
        this.viewFinder.aspectRatio.width = 3.0

        // Disable the viewfinder
        this.viewFinder.visible = false
    }
    barcodeResultLauncher.launch(config)
}

Now build and run your scanner again to test out its new behavior.

Scanning a PDF417 with the AR overlay and a confirmation dialog

Conclusion

🎉 With this, you now have a fully functional Android app for scanning PDF417 barcodes!

There are many more scanner configurations for you to try – take a look at the SDK’s RTU UI documentation and the API reference to learn more.

💡 The Scanbot SDK also comes with built-in data parsers for various barcode formats, including PDF417 codes on ID cards, driver’s licenses, boarding passes, and German medical certificates.

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 scanning! 🤳