Android QR Code Reader Made Easy

Making your Android application barcode aware should be easy! Luckily it is using Google Play services and the Mobile Vision APIs. It allows you to scan barcodes (e.g. QR codes) quickly and locally (making it really fast!) with very little effort on you the developer. All the classes you need are available through the namespace and this blog post will showcase through an example how to implement Google’s barcode reader.

The use case we will solve is “From this activity I’d like to scan a QR code and instantly get the scanned data back to this activity”.

Setting up the project

Just clone or download the GIT repository containing the ready-to-run project, open it in Android Studio and I will guide you through the main sections of the code.

In Android Studio, let’s make sure we have access to the Google Play services by going to SDK Tools (Tools → Android → SDK Manager → SDK Tools). If not already ticked, tick the Google Play services box and press the OK button to start the installation.

In your build.grade (Module: App) file you will notice that the project is pre-defined with the implement '' dependency according to:

dependencies {
    implement fileTree(dir: 'libs', include: ['*.jar'])
    implement ''
    implement ''

This will make the namespace available in our project.

Further, in the manifest file, you will notice that we ask for camera permission with:

<manifest xmlns:android=""

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

The workhorse classes

The project has two sub-packages barcode and camera. The packages contain files to handle the tracking and capturing of barcodes, and previewing the camera source respectively. The classes in the packages originate from the official Google example but are modified to work in accordance to our use case.

The barcode Package

This package contains three classes:

  • BarcodeCaptureActivity - Wrapper for starting the camera source and binding that source to the barcode tracker.
  • BarcodeTrackerFactory and BarcodeTracker - We start a tracker factory that associates graphics to new barcodes by creating BarcodeTrackers as needed.

The camera Package

This package contains two classes:

  • CameraSource - Receives and forwards frames from the camera to the detector.
  • CameraSourcePreview - Displays the camera frames.

Wrap it up!

Our MainActivity acts as a wrapper to start the barcode capturing activity and to print on screen the data contained in a given barcode. We start the BarcodeCaptureActivity from MainActivity and expect a result by:

val intent = Intent(applicationContext,
startActivityForResult(intent, BARCODE_READER_REQUEST_CODE)

…and we take care of the result in:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == BARCODE_READER_REQUEST_CODE) {
        if (resultCode == CommonStatusCodes.SUCCESS) {
            if (data != null) {
                val barcode = data.getParcelableExtra<Barcode>(BarcodeCaptureActivity.BarcodeObject)
                val p = barcode.cornerPoints
                mResultTextView.text = barcode.displayValue
            } else
        } else
            Log.e(LOG_TAG, String.format(getString(R.string.barcode_error_format),
    } else
        super.onActivityResult(requestCode, resultCode, data)

Test it!

Now you can go to your favorite qr-code generator site and test your app! You should expect to see something like this:


Given you have the barcode/camera classes (which you now have), the above code is all you need to care about to make your app scanning barcodes!

We have focused on QR codes in this post but all the standard formats are available to decrypt with the scanner we've implemented. If you want to change/add a different format just go to BarcodeCaptureActivity and find

BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).setBarcodeFormats(Barcode.QR_CODE)

Here we use setBarcodeFormats(…) to specify our formats and you can add any variant of the supported formats. For example (Barcode.QR_CODE | Barcode.DATA_MATRIX), or why not (Barcode.ALL_FORMATS). Keep them few and specific for fastest parsing.

Learn More

Read the Mobile Vision Barcode API documentation, explore advanced examples and/or drop a comment in the section below!