QR code and Barcode technology are being more famous this day. Almost every product has a barcode on it. QR code and Barcode can contain any information like name, ids. These QR / Barcodes are not humanly readable it can be read by using the QR Code Scanner and Bar Code Scanner. So in this post, we learn to build Android QR Code Scanner and Android Barcode Scanner.
DOWNLOAD PROJECT
DEMO
What is QR Code?
QR code is a bundle of Black and White squares. Information like URLs, Personal information, etc. are stored in QR codes. Smartphones or Cameras can read this encoded information. For Android smartphone users there are plenty of apps on Playstore.
What is Barcode?
Barcode is a Bundle of vertical lines with a variety of widths. Contains products full information like serial number, product number, etc. Smartphones or Barcode Scanners can read this encoded information.
Building Android QR Code Scanner / Android Barcode Scanner
Create a new Android studio project File -> New Project or use existing. To decode information from barcodes and QR codes we need the Zxing library.
Adding Zxing Library into project
1. Open build.gradle(module app) file and modify according to following snippets.
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.loopwiki.qrsacnner"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
/*Add QR Zxing Library Here */
implementation 'com.journeyapps:zxing-android-embedded:3.5.0'
}
Creating Custom Scanner Activity
2. Create a new layout -> custom_scanner.xml. This layout will contain BarcodeView and ViewfinderView.
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--Bar code Scanner window-->
<com.journeyapps.barcodescanner.BarcodeView
android:id="@+id/zxing_barcode_surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_framing_rect_height="200dp"
app:zxing_framing_rect_width="250dp" />
<!--Full Camera Window with viewfinder-->
<com.journeyapps.barcodescanner.ViewfinderView
android:id="@+id/zxing_viewfinder_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_possible_result_points="@color/colorPrimary"
app:zxing_result_view="@color/colorAccent"
app:zxing_viewfinder_laser="@color/colorPrimaryDark"
app:zxing_viewfinder_mask="@color/transparent_blue" />
<!--Help Text-->
<TextView
android:id="@+id/zxing_status_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:gravity="center"
android:text="@string/message"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="@color/zxing_status_text" />
</merge>
Breaking custom_scanner.xml
BarcodeView is a small window from ViewfinderView. This is the area in which we will move QR code or Barcode to scan.
ViewfinderView this is a view where camera visuals are shown.
3. Create a new layout -> content_scanner.xml. This layout will DecoratedBarcodeView and flashlight button. Add the Following snippets to it.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.loopwiki.qrsacnner.ScannerActivity"
tools:showIn="@layout/activity_scanner">
<! – set custom layout for scanner-->
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="@+id/zxing_barcode_scanner"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_scanner_layout="@layout/custom_scanner" />
<! – FlashLight Button-->
<Button
android:id="@+id/switch_flashlight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="@string/turn_off_flashlight" />
</RelativeLayout>
4. create new layout ->activity_scanner.xml will contain our toolbar and content_scanner.xml.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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="com.loopwiki.qrsacnner.ScannerActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_scanner" />
</android.support.design.widget.CoordinatorLayout>
5. Create new class Package Name -> ScannerActivity.java. In this class, we can put our programmable logic as follows.
package com.loopwiki.qrsacnner;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
public class ScannerActivity extends AppCompatActivity implements
DecoratedBarcodeView.TorchListener {
private CaptureManager capture;
private DecoratedBarcodeView barcodeScannerView;
private Button switchFlashlightButton;
private boolean isFlashLightOn = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scanner);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initialize barcode scanner view
barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);
//set torch listener
barcodeScannerView.setTorchListener(this);
//switch flashlight button
switchFlashlightButton = (Button) findViewById(R.id.switch_flashlight);
// if the device does not have flashlight in its camera,
// then remove the switch flashlight button...
if (!hasFlash()) {
switchFlashlightButton.setVisibility(View.GONE);
} else {
switchFlashlightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switchFlashlight();
}
});
}
//start capture
capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.decode();
}
/**
* Check if the device's camera has a Flashlight.
*
* @return true if there is Flashlight, otherwise false.
*/
private boolean hasFlash() {
return getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
public void switchFlashlight() {
if (isFlashLightOn) {
barcodeScannerView.setTorchOff();
isFlashLightOn = false;
} else {
barcodeScannerView.setTorchOn();
isFlashLightOn = true;
}
}
@Override
public void onTorchOn() {
switchFlashlightButton.setText(R.string.turn_off_flashlight);
}
@Override
public void onTorchOff() {
switchFlashlightButton.setText(R.string.turn_on_flashlight);
}
@Override
protected void onResume() {
super.onResume();
capture.onResume();
}
@Override
protected void onPause() {
super.onPause();
capture.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
capture.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
capture.onSaveInstanceState(outState);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
}
Breaking ScannerActivity
Following piece of code is used to initialize QR / Barcode Scanner.
capture = new CaptureManager(this, barcodeScannerView); capture.initializeFromIntent(getIntent(), savedInstanceState); capture.decode();
Now if users smartphone has flashlight feature then we will initialize flashlight button. This button will turn flashlight according to the user’s choice.
//switch flashlight button
switchFlashlightButton = (Button) findViewById(R.id.switch_flashlight);
// if the device does not have flashlight in its camera,
// then remove the switch flashlight button...
if (!hasFlash()) {
switchFlashlightButton.setVisibility(View.GONE);
} else {
switchFlashlightButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switchFlashlight();
}
});
}
/**
* Check if the device's camera has a Flashlight.
*
* @return true if there is Flashlight, otherwise false.
*/
private boolean hasFlash() {
return getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
public void switchFlashlight() {
if (isFlashLightOn) {
barcodeScannerView.setTorchOff();
isFlashLightOn = false;
} else {
barcodeScannerView.setTorchOn();
isFlashLightOn = true;
}
}
Creating MainActvity
6. Create new layout -> content_main.xml. This layout will contain scan button which will launch QR/Barcode scan.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.loopwiki.qrsacnner.MainActivity"
tools:showIn="@layout/activity_main">
<Button
android:id="@+id/buttonScan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Scan" />
</RelativeLayout>
7. Create new layout -> activity_main.xml contain toolbar and content_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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="com.loopwiki.qrsacnner.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
8. Create new class Package name ->MainActivity.java. This is activity class. In this class, we will launch Scanning by clicking scan button.
package com.loopwiki.qrsacnner;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Scan Button
Button buttonBarCodeScan = findViewById(R.id.buttonScan);
buttonBarCodeScan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//initiate scan with our custom scan activity
new IntentIntegrator(MainActivity.this).setCaptureActivity(ScannerActivity.class).initiateScan();
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//We will get scan results here
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
//check for null
if (result != null) {
if (result.getContents() == null) {
Toast.makeText(this, "Scan Cancelled", Toast.LENGTH_LONG).show();
} else {
//show dialogue with result
showResultDialogue(result.getContents());
}
} else {
// This is important, otherwise the result will not be passed to the fragment
super.onActivityResult(requestCode, resultCode, data);
}
}
//method to construct dialogue with scan results
public void showResultDialogue(final String result) {
AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
} else {
builder = new AlertDialog.Builder(this);
}
builder.setTitle("Scan Result")
.setMessage("Scanned result is " + result)
.setPositiveButton("Copy result", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Scan Result", result);
clipboard.setPrimaryClip(clip);
Toast.makeText(MainActivity.this, "Result copied to clipboard", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
dialog.dismiss();
}
})
.show();
}
}
Breaking MainActivity
Following snippets will launch our Scanner Activity for results. Seems after launching ScannerActvity this activity will wait for the result of the scan.
//initiate scan with our custom scan activity
new IntentIntegrator(MainActivity.this).setCaptureActivity(ScannerActivity.class).initiateScan();
There are two cases here user will scan any QR/barcode and a user will cancel the scan. Manage both results in onActivityResult() method. Show Result to the user if the user scans QR code or Barcode.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//We will get scan results here
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
//check for null
if (result != null) {
if (result.getContents() == null) {
Toast.makeText(this, "Scan Cancelled", Toast.LENGTH_LONG).show();
} else {
//show dialogue with result
showResultDialogue(result.getContents());
}
} else {
// This is important, otherwise the result will not be passed to the fragment
super.onActivityResult(requestCode, resultCode, data);
}
}
To show the result to the user we will build a dialogue. This dialogue is constructed by using showResultDialogue() method. This dialogue will display the result with copy and cancel button.
//method to construct dialogue with scan results
public void showResultDialogue(final String result) {
AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
} else {
builder = new AlertDialog.Builder(this);
}
builder.setTitle("Scan Result")
.setMessage("Scanned result is " + result)
.setPositiveButton("Copy result", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Scan Result", result);
clipboard.setPrimaryClip(clip);
Toast.makeText(MainActivity.this, "Result copied to clipboard", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
dialog.dismiss();
}
})
.show();
}
9. Download the Values folder from here. This folder contains the necessary styles, colors, and strings. Copy and paste these styles, colors, and strings to your project.
10. Modify manifest.xml as follows. Remember to add camera permission.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.loopwiki.qrsacnner">
<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"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
</activity>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Done now run the application.

If you still have any queries, please post them in the comments section below, I will be happy to help you.
20 Comments
How to move the camera view to little up. It always coming in centre.
i want the scanned result in the scanner page itself ,it gives me result in previous page…how to avoid it
Hello sir, This code not working in fragments
Hello Sir, I wanted to know if this implementation can be done in a dialog class.
how to data post in textbox plz help
this is the best example that i found!!
One question;
how do we able to expand the rectangle scan area by entire screen. Currently only focus on the small rectangle at center of screen.
Thank you.
After browsing so many tutorials this is the most complete and logical one! Great job!
One question here:
Where do I capture the scenario where the QR code is empty (i.e. there is QR code but it translates to nothing)?
Which is it – at the “if(result == null)” or at the “if(result.getContents() == null)” of onActivityResult method?
Yes buddy you are correct you adjust that in if(result.getContents() == null)
how to do this with an toolbar view. Such as an super market scanner-app
Read this article carefully Zking has all functionality that you need.
Sir can’t we create a history section and store all the scanned qr code information instead of copying it to clipboard.
Yes we can create that one too. I just wanted to keep this tutorial focused to main topic.
Clear,Succinct and Great Tutorial !!! You saved my day. Thank you, Sir.
Welcome mate
Good job sir. i was wondering how to open a url automatically if scan result is a website address
You can use Intent with action as view.
how to switch back camera to front camera
Just invoke by Intent and set extra SCAN_CAMERA_ID to the ID of the camera you want — usually 1 for the front one.
Example
Working Perfectly.Great job. Thank a lot. You saved my day.
Welcome Mate ! 🙂