QR stands for "Quick Response" Which is a two-dimensional version of the barcode. QR Code stores a small piece of information like plain text, URL, email address, product’s unique information. Information is hidden from the outside world. QR Code and Barcode are very popular nowadays.

In this blog, we will learn How to create QR Code and Barcode scanner using Google Mobile Vision API. Please follow below steps to create QR Code scanner. 

Step 1. Create an Android Project with an empty Activity called MainActivity.  As we have created Activity, two files activity_main.xml and MainActivity.java will be created in its correspondent folders. You have to create two more activity QRCodeScanActivity and ScanResultActivity. One is used to scan the QR Code and second is used to show result text stored in QR Code. See project structure given at end of this blog.

Step to create new Activity: Right click on app-> New-> Activity-> Empty Activity-> Give proper name and Finish.

Step 2. Open app/build.gradle file and add Google Mobile Vision API library com.google.android.gms:play-services-vision:11.0.2 in a gradle file. After adding the library Sync project.

app/build.gradle

apply plugin: 'com.android.application'

  

android {

    compileSdkVersion 23

    buildToolsVersion "28.0.3"

  

    defaultConfig {

        applicationId "com.example.qrcodescanner"

        minSdkVersion 15

        targetSdkVersion 23

        versionCode 1

        versionName "1.0"

    }

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }

    }

}

  

dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])

    testCompile 'junit:junit:4.12'

    compile 'com.android.support:appcompat-v7:23.4.0'

    compile 'com.google.android.gms:play-services-vision:11.0.2' /* Add this dependency */

}

Step 3. Setup permission to access the mobile camera in AndroidMenifest.xml file.

AndroidMenifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.qrcodescanner">

  

    <!-- Set permission to access Camera -->

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

  

    <application

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:supportsRtl="true"

        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <activity android:name=".QRCodeScanActivity" />

        <activity android:name=".ScanResultActivity"></activity>

    </application>

  

</manifest>

Step 4. Open activity_main.xml, modify it according to your requirements. I have design it simple. Code is given below.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="#ffffff"

    tools:context=".MainActivity">

  

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:layout_marginBottom="40dp"

        android:gravity="center"

        android:orientation="vertical">

  

        <ImageView

            android:layout_width="120dp"

            android:layout_height="120dp"

            android:layout_marginBottom="20dp"

            android:src="@drawable/qrcode" />

  

        <TextView

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Click button to scan your QR Code"

            android:textSize="16dp" />

  

    </LinearLayout>

  

    <Button

        android:id="@+id/btnScanQRCode"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:padding="15dp"

        android:text="Scan QR Code"

        android:textSize="18dp" />

  

</RelativeLayout>

Step 5. Now open MainActivity.java file and write below code. On button click, it will open new activity which will be used to scan QR Code.

MainActivity.java

package com.example.qrcodescanner;

  

import android.content.Intent;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

  

public class MainActivity extends AppCompatActivity {

  

    Button btnScanQRCode;

  

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

  

        btnScanQRCode = (Button) findViewById(R.id.btnScanQRCode);

        btnScanQRCode.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                Intent intent = new Intent(MainActivity.this, QRCodeScanActivity.class);

                startActivity(intent);

            }

        });

    }

}

Step 6. As you click on Scan QR Code button it will open QRCodeScanActivity. It will ask you for permission to access the camera and as you allow, you will be able to scan the QR Code. When QR Code will detect it will do beep sound and redirect you to the next activity to show text stored in QR Code. Its code for XML and java file is given below. Please read my comments properly to understand the code.

activity_qrcode_scan.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    tools:context=".QRCodeScanActivity">

  

    <SurfaceView

        android:id="@+id/surfaceQRScanner"

        android:layout_width="match_parent"

        android:layout_height="match_parent" />

  

</LinearLayout>

QRCodeScanActivity.java

package com.example.qrcodescanner;

  

import android.Manifest;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.media.AudioManager;

import android.media.ToneGenerator;

import android.support.v4.app.ActivityCompat;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import android.util.SparseArray;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import com.google.android.gms.vision.CameraSource;

import com.google.android.gms.vision.Detector;

import com.google.android.gms.vision.barcode.Barcode;

import com.google.android.gms.vision.barcode.BarcodeDetector;

import java.io.IOException;

  

public class QRCodeScanActivity extends AppCompatActivity {

  

    SurfaceView surfaceQRScanner;

    BarcodeDetector barcodeDetector;

    CameraSource cameraSource;

    String scanResult = "";

  

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_qrcode_scan);

  

        initStuff(); /* Calling this function to initialize components */

  

    }

  

    /* Function used to initialize components of activity */

    public void initStuff() {

  

        /* Initializing objects */

        surfaceQRScanner = (SurfaceView) findViewById(R.id.surfaceQRScanner);

        barcodeDetector = new BarcodeDetector.Builder(this)

                .setBarcodeFormats(Barcode.ALL_FORMATS)

                .build();

        cameraSource = new CameraSource.Builder(getApplicationContext(), barcodeDetector)

                .setRequestedPreviewSize(1024, 768)

                .setAutoFocusEnabled(true)

                .build();

  

        /* Adding Callback method to SurfaceView */

        surfaceQRScanner.getHolder().addCallback(new SurfaceHolder.Callback() {

            @Override

            public void surfaceCreated(SurfaceHolder holder) {

                try {

                    /* Asking user to allow access of camera */

                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {

                        cameraSource.start(surfaceQRScanner.getHolder());

                    } else {

                        ActivityCompat.requestPermissions(QRCodeScanActivity.this, new

                                String[]{Manifest.permission.CAMERA}, 1024);

                    }

                } catch (IOException e) {

                    Log.e("Camera start error-->> ", e.getMessage().toString());

                }

            }

  

            @Override

            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

  

            @Override

            public void surfaceDestroyed(SurfaceHolder holder) {

                cameraSource.stop();

            }

        });

  

        /* Adding Processor to Barcode detector */

        barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {

            @Override

            public void release() {

  

            }

  

            @Override

            public void receiveDetections(Detector.Detections<Barcode> detections) {

                final SparseArray<Barcode> barcodes = detections.getDetectedItems(); /* Retrieving QR Code */

                if (barcodes.size() > 0) {

  

                    barcodeDetector.release(); /* Releasing barcodeDetector */

  

                    ToneGenerator toneNotification = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100); /* Setting beep sound */

                    toneNotification.startTone(ToneGenerator.TONE_PROP_BEEP, 150);

  

                    scanResult = barcodes.valueAt(0).displayValue.toString(); /* Retrieving text from QR Code */

  

                    Intent intent = new Intent(QRCodeScanActivity.this, ScanResultActivity.class);

                    intent.putExtra("ScanResult", scanResult); /* Sending text to next activity to display */

                    startActivity(intent);

                }

            }

        });

    }

  

    /* Initialize components again */

    @Override

    public void onResume() {

        super.onResume();

        initStuff();

    }

}

Understanding the code

  • SurfaceView: SurfaceView is used to capture a view of the camera. It renders GUI rapidly so it’s good to use SurfaceView to scan the QR Code.
  • Callback method: Callback method is added to SurfaceView using surfaceQRScanner.getHolder().addCallback() which is used to receive information about changes happens on surface. In this method when surface creates, I have written code to get permission to access camera which is further used to scan the QR Code.
  • BarcodeDetector: Barcode detector is used to detect QR Code with help of camera source. Barcode detector has barcodeDetector.setProcessor() method which detects QR Code and if QR Code found, it returns an array of barcodes in a receiveDetections method inside the processor. To get a text from array barcodes.valueAt(0).displayValue method is used.
  • CameraSource: Camera source is used to start a camera and scan QR Code.
  • ToneGenerator: It is used to set beep sound on QR Code detection.
  • onResume: This method is called when user return from result activity on back pressed. We need to initialize all our components here again, to start scanning again.

Step 7. Open ScanResultActivity and modify it. This activity retrieves text sent from previous activity and displays it. A code is given below.

activity_scan_result.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    android:paddingTop="50dp"

    tools:context=".ScanResultActivity">

  

    <ImageView

        android:layout_width="80dp"

        android:layout_height="80dp"

        android:layout_gravity="center_horizontal"

        android:src="@drawable/resulticon" />

  

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_marginTop="40dp"

        android:orientation="vertical">

  

        <TextView

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:paddingBottom="15dp"

            android:paddingLeft="20dp"

            android:text="QR Code details"

            android:textSize="16dp" />

  

        <TextView

            android:id="@+id/txtScanResult"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:background="#ffffff"

            android:padding="20dp"

            android:text="No data found..!!"

            android:textColor="#000000"

            android:textSize="18dp" />

  

    </LinearLayout>

  

</LinearLayout>

ScanResultActivity.java

package com.example.qrcodescanner;

  

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.widget.TextView;

  

public class ScanResultActivity extends AppCompatActivity {

  

    TextView txtScanResult;

  

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_scan_result);

  

        txtScanResult = (TextView) findViewById(R.id.txtScanResult); /* Find TextView and initialize it to object */

  

        Bundle extras = getIntent().getExtras();

        if (extras != null) {

            String scanResult = extras.getString("ScanResult"); /* Retrieving text of QR Code */

            txtScanResult.setText(scanResult);

        }

    }

}

Step 8. Now run your application, scan QR Code and see the result. If you have any query please comment to ask it.

Output

Your Project Structure may look like,

Hope this blog will help you. Thank you..!!