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.
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..