How to create your own QR Code and Barcode scanner reader Android App? – complete source code

This video shows the steps to create your own QR code (Quick response) and barcode scanner Android App in Android Studio. It uses zxing library ‘com.journeyapps:zxing-android-embedded:4.0.2’.

In this video it shows how to create an IntentIntegrator object to scan the codes from your phone. The code in this video has been kept very simple to follow.

The testing of the App has been done using a real phone as camera features aren’t emulated in the emulator.

The screenshots of the test results is below:

Test 1:

Hello Programmer World Bar Code
ProgrammerWorld Barcode Scanned

Test 2:

Sample Barcode from Google
Sample Barcode Scanned2
Sample Barcode Scanned1

Test 3:

Sample QR Code from Google
Sample QR code Scanned1
Sample QR code Scanned2

For any suggestions, comments, queries or appreciations we will be glad to hear at: programmerworld1990@gmail.com

Complete source code is available below:

Java Code:

package com.example.myqrcodebarcodescanner;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

public class MainActivity extends AppCompatActivity {

private TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PackageManager.PERMISSION_GRANTED);
}

public void ScanButton(View view){
IntentIntegrator intentIntegrator = new IntentIntegrator(this);
intentIntegrator.initiateScan();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (intentResult != null){
if (intentResult.getContents() == null){
textView.setText(“Cancelled”);
}else {
textView.setText(intentResult.getContents());
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}

Gradle File:

apply plugin: ‘com.android.application’

android {
compileSdkVersion 29
buildToolsVersion “29.0.2”
defaultConfig {
applicationId “com.example.myqrcodebarcodescanner”
minSdkVersion 26
targetSdkVersion 29
versionCode 1
versionName “1.0”
testInstrumentationRunner “androidx.test.runner.AndroidJUnitRunner”
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(‘proguard-android-optimize.txt’), ‘proguard-rules.pro’
}
}
}

dependencies {
implementation fileTree(dir: ‘libs’, include: [‘*.jar’])
implementation ‘androidx.appcompat:appcompat:1.0.2’
implementation ‘androidx.constraintlayout:constraintlayout:1.1.3’
testImplementation ‘junit:junit:4.12’
androidTestImplementation ‘androidx.test.ext:junit:1.1.0’
androidTestImplementation ‘androidx.test.espresso:espresso-core:3.1.1’

implementation ‘com.journeyapps:zxing-android-embedded:4.0.2’
}

Manifest File:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myqrcodebarcodescanner">

    <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=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest> 

Layout XML File:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="236dp"
        android:layout_height="150dp"
        android:text="@string/results_appear_here"
        android:textAlignment="center"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.428" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="163dp"
        android:layout_marginTop="105dp"
        android:onClick="ScanButton"
        android:text="@string/scan"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

23 comments

  1. Getting the below error after I used the zxing dependency
    Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 24 declared in library [com.journeyapps:zxing-android-embedded:4.0.2] C:\Users\kotegadde\.gradle\caches\transforms-2\files-2.1\6592bc29195442758ca6a63c1d889be5\jetified-zxing-android-embedded-4.0.2\AndroidManifest.xml as the library might be using APIs not available in 16
    Suggestion: use a compatible library with a minSdk of at most 16,
    or increase this project’s minSdk version to at least 24,
    or use tools:overrideLibrary=”com.google.zxing.client.android” to force usage (may lead to runtime failures)

    • The error message is quite self-explanatory. Either increase the minimum SDK API level to above 24 or use previous versions of Zxing library which supports API level 16.

      I will suggest to go with first option and increase the minimum SDK level in gradle file to 24 or above. Do not forget to sync the gradle file after this change.

      Regarding the second opinion, I cannot see any reason to use such an old SDKs (level 16) in your case.

      Good Luck
      Programmer World

  2. Hey, Thank you so much for the Tutorial!
    i just have one small doubt .
    How do i use the camera in portrait mode ?

    • Just create another class as below:

      import android.os.Bundle;

      import com.journeyapps.barcodescanner.CaptureActivity;
      import com.journeyapps.barcodescanner.DecoratedBarcodeView;

      public class CaptureActivityPortrait extends CaptureActivity {

      @Override
      protected DecoratedBarcodeView initializeContent() {
      setContentView(R.layout.custom_layout);
      return (DecoratedBarcodeView)findViewById(R.id.zxing_barcode_scanner);
      }

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      }
      }

      And use this class in the scan intent (of IntentIntegrator) as below:

      intentIntegrator.setCaptureActivity(CaptureActivityPortrait.class);

      Cheers
      Programmer World

      • QR scanner will read what is encoded in the QR code. If you need to convert the output in another form (xml to weblink in this case) then a separate method would required to be written to adapt to the required format. I don’t think QR scanner can do it on its own.

        Cheers
        Programmer World

  3. Can you explain in detail about how do i use the camera in portrait mode, please?
    About custom_layout, and scan call. Thanks.

    • Just create another class as below:

      import android.os.Bundle;

      import com.journeyapps.barcodescanner.CaptureActivity;
      import com.journeyapps.barcodescanner.DecoratedBarcodeView;

      public class CaptureActivityPortrait extends CaptureActivity {

      @Override
      protected DecoratedBarcodeView initializeContent() {
      setContentView(R.layout.custom_layout);
      return (DecoratedBarcodeView)findViewById(R.id.zxing_barcode_scanner);
      }

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      }
      }

      And use this class in the scan intent (of IntentIntegrator) as below:

      intentIntegrator.setCaptureActivity(CaptureActivityPortrait.class);

      Cheers
      Programmer World

      • CaptureActivityPortrait is considered as an activity and will crash the app if not added in the manifest. However it’s not possible to add it in the manifest

      • ohh I got it in the manifest but however I had this error
        java.lang.NullPointerException: Attempt to invoke virtual method ‘com.journeyapps.barcodescanner.BarcodeView com.journeyapps.barcodescanner.DecoratedBarcodeView.getBarcodeView()’ on a null object reference
        at com.journeyapps.barcodescanner.CaptureManager.(CaptureManager.java:127)
        at com.journeyapps.barcodescanner.CaptureActivity.onCreate(CaptureActivity.java:23)

    • I found way to change Orientation of zxing scanner activity automatically when device Orientation change

      Try this way

      CaptureActivityPortrait

      public class CaptureActivityPortrait extends CaptureActivity {
      //Nothing in side.
      }
      CaptureActivityPortrait in manifest file

      use this way in your activity

      public class MyActivity extends AppCompatActivity {

      IntentIntegrator qrScan;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_my);

      qrScan = new IntentIntegrator(this).setCaptureActivity(CaptureActivityPortrait.class);

      qrScan.setOrientationLocked(false);
      qrScan.initiateScan();
      }

      }

  4. Hi, Thanx for your code
    Hey just i want add some extra , that i want to compare obatained barcode scanner results their product name and i want to convert those results into audio.is it possible ?

  5. How could I get it to send the data to another activity, cause I tried to do something like this but couldn’t get it to work.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if (intentResult != null){
    if (intentResult.getContents() == null){
    Intent error = new Intent(barcodeScanner.this, ErrorPage.class);
    // error.putExtra(“error”,”Barcode scanner is gestopt of werkte niet”);
    startActivity(error);
    }else {
    Intent productInfo = new Intent(barcodeScanner.this, productInfo.class);
    // productInfo.putExtra(“error”,intentResult.getContents());
    startActivity(productInfo);
    }
    }
    super.onActivityResult(requestCode, resultCode, data);

    • I am not sure as I do not have this project loaded in my environment currently. But try to convert the intentResult to some known object form. Say for example: intentResult.getContents().toString() and see if it works. Something like below line:

      productInfo.putExtra(“error”,intentResult.getContents().toString());

      If this still gives error please let me know.

      Cheers
      Programmer World

  6. ‘com.google.zxing.integration.android.IntentIntegrator’ is deprecated.
    How to fix this?

Leave a Reply