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 ! 🙂