Building a QR Code Scanner with Android

Introduction

QR codes are a convenient and efficient way to store data that can be scanned and processed by devices. Building a QR code scanner in Android allows users to easily scan QR codes and retrieve the information they contain. In this article, we'll guide you through the process of creating a QR code scanner app using Android's Camera API and ZXing library.

Setting Up Your Android Project

To begin, you'll need to set up a new Android project in Android Studio. Follow the steps below to get started:

XML
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="match_parent"/> <Button android:id="@+id/scan_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Scan QR Code" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> </RelativeLayout>

Adding ZXing Library

ZXing ("Zebra Crossing") is an open-source library that allows easy integration of QR code scanning functionality into your Android app. You can add ZXing to your project via Gradle by including the following dependency in your build.gradle file:

Gradle
dependencies { implementation 'com.google.zxing:core:3.4.1' implementation 'com.journeyapps:zxing-android-embedded:4.1.0' }

Creating the QR Code Scanner Activity

Now that the project is set up and the ZXing library is integrated, it's time to create the activity that will handle QR code scanning. This activity will utilize the camera to capture the QR code and decode it using the ZXing library.

Kotlin
package com.example.qrcodescanner import android.os.Bundle import android.util.Log import android.view.SurfaceHolder import android.view.SurfaceView import android.widget.Button import androidx.appcompat.app.AppCompatActivity import com.google.zxing.Result import me.dm7.barcodescanner.zxing.ZXingScannerView class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler { private lateinit var scannerView: ZXingScannerView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_scanner) val surfaceView = findViewById<SurfaceView>(R.id.camera_preview) val scanButton = findViewById<Button>(R.id.scan_button) scannerView = ZXingScannerView(this) scannerView.setResultHandler(this) val holder: SurfaceHolder = surfaceView.holder holder.addCallback(object : SurfaceHolder.Callback { override fun surfaceCreated(holder: SurfaceHolder) { scannerView.startCamera() } override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { // handle surface changes if needed } override fun surfaceDestroyed(holder: SurfaceHolder) { scannerView.stopCamera() } }) scanButton.setOnClickListener { scannerView.resumeCameraPreview(this@ScannerActivity) } } override fun handleResult(rawResult: Result?) { // Handle the scanned result here Log.v("QRScanner", rawResult?.text ?: "No Result") } }

Handling Camera Permissions

Since accessing the camera requires user permissions, you need to ensure that the app handles permissions correctly. Add the following permissions to your AndroidManifest.xml:

XML
<uses-permission android:name="android.permission.CAMERA" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".ScannerActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>

Running the App and Scanning QR Codes

Once you’ve set up the QR code scanner activity and handled the necessary permissions, you can build and run your app. When the app launches, it will access the camera and allow you to scan QR codes. The scanned result will be displayed in the log for further processing or display.

Displaying QR Code Scanning Results

Instead of just logging the QR code content, you can display the result directly to the user in a more user-friendly way. For example, you can show the scanned QR code result in a TextView or even take specific actions based on the content (e.g., opening a URL in a browser if the QR code contains a link).

Kotlin
override fun handleResult(rawResult: Result?) { rawResult?.let { val scannedResult = it.text // Display the result in a TextView or take specific actions findViewById(R.id.result_text).text = scannedResult // Example: If the result is a URL, open it in a browser if (scannedResult.startsWith("http://") || scannedResult.startsWith("https://")) { val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(scannedResult)) startActivity(browserIntent) } // Resume the camera preview after a delay Handler(Looper.getMainLooper()).postDelayed({ scannerView.resumeCameraPreview(this) }, 2000) } }

Customizing the QR Code Scanner UI

The default ZXing scanner interface is minimalistic, but you can customize the UI to match your app's design language. For example, you can change the colors of the scan line, customize the scanner layout, or add additional UI elements such as a flashlight toggle button.

XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="match_parent"/> <Button android:id="@+id/scan_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Scan QR Code" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> <Button android:id="@+id/flashlight_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Toggle Flashlight" android:layout_above="@id/scan_button" android:layout_centerHorizontal="true"/> </RelativeLayout>

Handling QR Code Scanning Errors

In a real-world app, you need to consider scenarios where QR code scanning might fail, such as poor lighting conditions, a moving camera, or an invalid QR code. You can handle these errors by displaying appropriate messages to the user or retrying the scan after a short delay.

Kotlin
override fun handleResult(rawResult: Result?) { if (rawResult == null) { Toast.makeText(this, "Failed to scan QR code. Please try again.", Toast.LENGTH_SHORT).show() scannerView.resumeCameraPreview(this) } else { // Handle successful scan result val scannedResult = rawResult.text findViewById<TextView>(R.id.result_text).text = scannedResult } }

Conclusion

Building a QR code scanner app in Android is a great way to learn more about Android's Camera API and how to integrate third-party libraries like ZXing. With this guide, you should have a good starting point for developing a fully functional QR code scanner. From here, you can expand the app's functionality, improve its UI, and handle more complex QR code data types.

Further Enhancements

Here are some ideas for further enhancing your QR code scanner app:

  • Save Scanned Results: Store scanned QR code results in a local database for future reference.
  • Support for Multiple QR Codes: Allow scanning of multiple QR codes in a single session and batch process the results.
  • QR Code Generation: Add functionality to generate QR codes directly within your app.
  • Analytics: Track how often QR codes are scanned and gather insights on user behavior.

References

For more information on QR code scanning and Android development, you can refer to the following resources:

Post a Comment

Previous Post Next Post