QR Scanner Implementation in Android (Kotlin)

QR Scanner Implementation in Android

This document provides a step-by-step guide to implementing a QR scanner in an Android application using the zxing-android-embedded library. The implementation includes custom UI for the scanner and functionality to handle QR code scanning results.

Dependencies

To begin, install the following dependency in your project:

dependencies {
    implementation "com.journeyapps:zxing-android-embedded:4.3.0"
}

Permissions

Ensure the following permission is added to your AndroidManifest.xml file:

<uses-permission android:name="android.permission.CAMERA" />
Request camera permission at runtime if targeting Android 6.0 (API level 23) or higher:
kotlin
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
    != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), CAMERA_REQUEST_CODE)
}

Activity Setup

Registering the Scanner

Register the activity result to handle scanning:

val scanner = registerForActivityResult<ScanOptions, ScanIntentResult>(
    ScanContract()
) { result ->
    if (result.contents != null) {
        Toast.makeText(this, "${result.contents}", Toast.LENGTH_SHORT).show()
    } else {
        Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show()
    }
}

Launching the Scanner

Trigger the scanner from a button click:

b.homeActivityScanQrButton.setOnClickListener {
    if (checkKycStatus()) {
        scanner.launch(
            ScanOptions()
                .setPrompt("")
                .setDesiredBarcodeFormats(ScanOptions.QR_CODE)
                .setCaptureActivity(CustomCaptureActivity::class.java)
        )
    }
}

Custom Capture Activity

Create a custom activity by extending CaptureActivity to apply custom UI for the scanner:

class CustomCaptureActivity : CaptureActivity() {

    // DecoratedBarcodeView consists of both viewfinder & scanner
    private lateinit var barcodeScannerView: DecoratedBarcodeView

    override fun initializeContent(): DecoratedBarcodeView {
        // Use your custom layout
        setContentView(R.layout.custom_scan_layout)
        barcodeScannerView = findViewById(R.id.zxing_barcode_scan)

        // To set the red line invisible
        barcodeScannerView.viewFinder.setLaserVisibility(false)

        findViewById<ImageView>(R.id.close_button).setOnClickListener {
            finish()
        }

        return barcodeScannerView
    }
}

XML Layout for Custom Scanner UI

Create a custom layout file (e.g., res/layout/custom_scan.xml) for the scanner screen:

<FrameLayout 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/customscan"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.journeyapps.barcodescanner.DecoratedBarcodeView
        android:id="@+id/zxing_barcode_scan"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        app:zxing_framing_rect_height="250dp"
        app:zxing_framing_rect_width="250dp"
        app:zxing_viewfinder_laser_visibility="false" />

    <!-- Add the customizable view here -->
</FrameLayout>
8 Likes

Well explained Shoaib!! Good work

@Shoaib I would like to understand zxing-android-embedded library will just for scanning or can we generate dynamic QR inside the app itself?

yes we can create QR codes dynamically using “BarcodeEncoder”