QR Code Scanner Android app in Android Studio with source code

What Will I Learn in QR code scanner?
You will how to create a QR generator application using android studio.

Requirements

  • Android studio must be installed.
  • Knowledge in Java.
  • Knowledge in XML
  • Difficulty
  • Intermediate
  • Tutorial Contents
  • Download Android Studio: Click Here.

In this series of tutorials, we are going to be developing an android application QR code scanner that will be centered around QR code.

MainActivity.java

package com.technic.qrcode;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btnTakePicture, btnScanBarcode;

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

    private void initViews() {
        btnTakePicture = findViewById(R.id.btnTakePicture);
        btnScanBarcode = findViewById(R.id.btnScanBarcode);
        btnTakePicture.setOnClickListener(this);
        btnScanBarcode.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btnTakePicture:
                startActivity(new Intent(MainActivity.this, PictureBarcodeActivity.class));
                break;
            case R.id.btnScanBarcode:
                startActivity(new Intent(MainActivity.this, ScannedBarcodeActivity.class));
                break;
        }

    }
}

Firstly, We will create the QR code generator and QR code scanner in my next tutorial we will be creating which will clearly interpret the QR code.

<img src="qr-1.png"  alt="QR code scanner">

Without further ado, lets jump into development:

PictureBarcodeActivity.java

package com.technic.qrcode;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;

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

import java.io.File;
import java.io.FileNotFoundException;

public class PictureBarcodeActivity extends AppCompatActivity implements View.OnClickListener {

    Button btnOpenCamera;
    TextView txtResultBody;

    private BarcodeDetector detector;
    private Uri imageUri;
    private static final int REQUEST_CAMERA_PERMISSION = 200;
    private static final int CAMERA_REQUEST = 101;
    private static final String TAG = "API123";
    private static final String SAVED_INSTANCE_URI = "uri";
    private static final String SAVED_INSTANCE_RESULT = "result";

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

        initViews();

        if (savedInstanceState != null) {
            if (imageUri != null) {
                imageUri = Uri.parse(savedInstanceState.getString(SAVED_INSTANCE_URI));
                txtResultBody.setText(savedInstanceState.getString(SAVED_INSTANCE_RESULT));
            }
        }

        detector = new BarcodeDetector.Builder(getApplicationContext())
                .setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)
                .build();

        if (!detector.isOperational()) {
            txtResultBody.setText("Detector initialisation failed");
            return;
        }
    }

    private void initViews() {
        txtResultBody = findViewById(R.id.txtResultsBody);
        btnOpenCamera = findViewById(R.id.btnOpenCamera);
        txtResultBody = findViewById(R.id.txtResultsBody);
        btnOpenCamera.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btnOpenCamera:
                ActivityCompat.requestPermissions(PictureBarcodeActivity.this, new
                        String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
                break;
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_CAMERA_PERMISSION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                    takeBarcodePicture();
                } else {
                    Toast.makeText(getApplicationContext(), "Permission Denied!", Toast.LENGTH_SHORT).show();
                }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
            launchMediaScanIntent();
            try {


                Bitmap bitmap = decodeBitmapUri(this, imageUri);
                if (detector.isOperational() && bitmap != null) {
                    Frame frame = new Frame.Builder().setBitmap(bitmap).build();
                    SparseArray<Barcode> barcodes = detector.detect(frame);
                    for (int index = 0; index < barcodes.size(); index++) {
                        Barcode code = barcodes.valueAt(index);
                        txtResultBody.setText(txtResultBody.getText() + "\n" + code.displayValue + "\n");

                        int type = barcodes.valueAt(index).valueFormat;
                        switch (type) {
                            case Barcode.CONTACT_INFO:
                                Log.i(TAG, code.contactInfo.title);
                                break;
                            case Barcode.EMAIL:
                                Log.i(TAG, code.displayValue);
                                break;
                            case Barcode.ISBN:
                                Log.i(TAG, code.rawValue);
                                break;
                            case Barcode.PHONE:
                                Log.i(TAG, code.phone.number);
                                break;
                            case Barcode.PRODUCT:
                                Log.i(TAG, code.rawValue);
                                break;
                            case Barcode.SMS:
                                Log.i(TAG, code.sms.message);
                                break;
                            case Barcode.TEXT:
                                Log.i(TAG, code.displayValue);
                                break;
                            case Barcode.URL:
                                Log.i(TAG, "url: " + code.displayValue);
                                break;
                            case Barcode.WIFI:
                                Log.i(TAG, code.wifi.ssid);
                                break;
                            case Barcode.GEO:
                                Log.i(TAG, code.geoPoint.lat + ":" + code.geoPoint.lng);
                                break;
                            case Barcode.CALENDAR_EVENT:
                                Log.i(TAG, code.calendarEvent.description);
                                break;
                            case Barcode.DRIVER_LICENSE:
                                Log.i(TAG, code.driverLicense.licenseNumber);
                                break;
                            default:
                                Log.i(TAG, code.rawValue);
                                break;
                        }
                    }
                    if (barcodes.size() == 0) {
                        txtResultBody.setText("No barcode could be detected. Please try again.");
                    }
                } else {
                    txtResultBody.setText("Detector initialisation failed");
                }
            } catch (Exception e) {
                Toast.makeText(getApplicationContext(), "Failed to load Image", Toast.LENGTH_SHORT)
                        .show();
                Log.e(TAG, e.toString());
            }
        }
    }

    private void takeBarcodePicture() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File photo = new File(Environment.getExternalStorageDirectory(), "pic.jpg");
        imageUri = FileProvider.getUriForFile(PictureBarcodeActivity.this,
                BuildConfig.APPLICATION_ID + ".provider", photo);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(intent, CAMERA_REQUEST);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        if (imageUri != null) {
            outState.putString(SAVED_INSTANCE_URI, imageUri.toString());
            outState.putString(SAVED_INSTANCE_RESULT, txtResultBody.getText().toString());
        }
        super.onSaveInstanceState(outState);
    }

    private void launchMediaScanIntent() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(imageUri);
        this.sendBroadcast(mediaScanIntent);
    }

    private Bitmap decodeBitmapUri(Context ctx, Uri uri) throws FileNotFoundException {
        int targetW = 600;
        int targetH = 600;
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(ctx.getContentResolver().openInputStream(uri), null, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;

        return BitmapFactory.decodeStream(ctx.getContentResolver()
                .openInputStream(uri), null, bmOptions);
    }
}

Next a layout file is created in the activity_main.xml file an editted to look like this:

ScannedBarcodeActivity.java

The layout is mainly has a RelativeLayout as its root layout which arranges views in a row either horinzonatally or vertically.

activity_main.xml

Nextin QR code scanner a StringBuilder varibale is created called textToSend which will be used to concatenate the values of the string variables (name, email, phonenumber, address).
The string variables are later appended to the textToSend variable along with a bar symbol (|).

activity_email.xml

<Button
    android:id="@+id/btnSendEmail"
    android:layout_width="240dp"
    android:layout_height="60dp"
    android:background="@drawable/button_2"
    android:textSize="20dp"
    android:layout_below="@+id/inBody"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="26dp"
    android:text="Send Email" />


<TextView
    android:id="@+id/txtEmailAddress"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:textSize="20dp"
    android:text="Email Address: "
    android:textStyle="bold" />

<EditText
    android:id="@+id/inSubject"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/txtEmailAddress"
    android:layout_centerHorizontal="true"
    android:ems="10"
    android:hint="Subject" />

<EditText
    android:id="@+id/inBody"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/inSubject"
    android:layout_centerHorizontal="true"
    android:ems="10"
    android:hint="Body" />

This QR code scanner – Next,a Multiformater object is created which is used in encoding the bitMatrix object in the next line with the content of what is to be encoded, the format as specified in BarcodeFormat.QR_CODE and then the width and height as specifiec in the 600, 600.

activity_scan_barcode.xml

<SurfaceView
    android:id="@+id/surfaceView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/btnAction"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_centerVertical="true" />

<TextView
    android:id="@+id/txtBarcodeValue"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="@dimen/activity_horizontal_margin"
    android:layout_marginStart="@dimen/activity_horizontal_margin"
    android:text="No Barcode Detected"
    android:textColor="#ffffff"
    android:textSize="20sp" />


<Button
    android:id="@+id/btnAction"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:text="ADD CONTENT IN THE MAIL"
    android:background="@drawable/button2"
    android:layout_marginTop="10dp"
    android:textSize="18dp"/>

activity_barcode_picture.xml

<ImageView
    android:id="@+id/imageView"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:layout_centerHorizontal="true"
    android:src="@mipmap/journaldev_logo" />

<TextView
    android:id="@+id/txtResultsHeader"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/imageView"
    android:layout_centerHorizontal="true"
    android:text="Results"
    android:textSize="18sp"
    android:textStyle="bold" />

<TextView
    android:id="@+id/txtResultsBody"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/txtResultsHeader"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="@dimen/activity_horizontal_margin"
    android:gravity="center" />

<Button
    android:id="@+id/btnOpenCamera"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="@dimen/activity_horizontal_margin"
    android:layout_marginTop="@dimen/activity_horizontal_margin"
    android:text="Open Camera" />

A BarcodeEncoder object is created and used to create a bitmap using the bitMatrix object explained above.

Lastly, QR code scanner the ImageView is set with a bitmap object and the the visibility is set to visible because in the activity_main.xml file its visiblity was set to gone, meaning that at the beginning of the application , the imageView wont be seen but once a user clicks the create a QR code, the QR code is created and the ImageView is set to true.

AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.autofocus" />

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

<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="com.technic.qrcode.MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name="com.technic.qrcode.PictureBarcodeActivity" />
    <activity android:name="com.technic.qrcode.ScannedBarcodeActivity" />
    <activity
        android:name="com.technic.qrcode.EmailActivity"
        android:windowSoftInputMode="adjustPan" />

    <meta-data
        android:name="com.google.android.gms.vision.DEPENDENCIES"
        android:value="barcode" />

    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>


</application>

What’s a QR Code?


QR code (an abbreviation of Quick Response) or QR code scanner is a trademark for a two-dimensional barcode that consists of little black squares arranged on a white background in the form of a square. IT contains in horizontal and vertical directions and represents machine-readable information in the form of a grid (unlike classic barcode that store data in horizontal form only).

To decipher the information captured in a QR code , which is usually a hyperlink or text, a device does not require an internet connection (although, you’d probably need it to work with deciphered data).

build.gradle

apply plugin: ‘com.android.application’

android {
compileSdkVersion 29
buildToolsVersion “29.0.2”
defaultConfig {
applicationId “com.dude.qrcode”
minSdkVersion 15
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.1.0’
implementation ‘androidx.constraintlayout:constraintlayout:1.1.3’
testImplementation ‘junit:junit:4.12’
androidTestImplementation ‘androidx.test:runner:1.2.0’
androidTestImplementation ‘androidx.test.espresso:espresso-core:3.2.0’
implementation ‘com.google.android.gms:play-services-vision:11.8.0’
implementation ‘androidx.legacy:legacy-support-v4:1.0.0’
}

Create More Android Apps:

Create Browser app in Android studio : Click Here

Create Music Player in Android studio : Click Here

Create News app in Android studio : Click Here


Convert Website to Android app in Android studio : Click Here

QR Code Reader and Scanner Apps Popular Now

Summing up the affordability of QR technology (QR code creation takes literally no money or time, as well as its scanning), ease of its use, and impressive potential in terms of instant information sharing, you’ll get why the digital market is now full of QR code scanner apps. And it seems like developers won’t stop any time soon

Vice versa, they continue reinventing the use of QR codes taking them from warehouses to shops, public transport facilities, museums, and literally every other place we could list here. On our way of figuring out how to create a qr scanner app that would thrive on the market of today, we decided to dive into the top QR code reader and generator applications as it is in 2020

YouTube Video

The project is available here on YouTube
Obviously there are lots of improvements that can still be done to this app, the project is on YouTube, check it out and drop your contribution!

If you’re ever in need of extra help with your Android app development projects, you can find experienced Android developers on android Studio to help you with everything from UI design to creating a native Android app.

Get the source code android QR code Scanner application.

1.QR Apk: Click Here
2.Qr code Logo Download: Click Here

Download Source Code

Click below to get the full source code android QR Scanner application.

Conclusion

We have successfully created a QR Code Scanner Android application using Android Studio..


Cheers!

READ MORE…

Leave a Reply