This is an old project that no longer receives support nor works 100% as expected.
For anyone looking for a simple solution to read QR codes you can use both Android CameraX library and Google ML Kit Barcode library as such:
build.gradle
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'com.google.mlkit:barcode-scanning:16.1.1'
implementation "androidx.camera:camera-camera2:1.0.0-beta07"
implementation "androidx.camera:camera-lifecycle:1.0.0-beta07"
implementation "androidx.camera:camera-view:1.0.0-alpha14"
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />
<application
....
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.camera.view.PreviewView
android:id="@+id/viewFinder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package com.example.cameraapptest;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.barcode.Barcode;
import com.google.mlkit.vision.barcode.BarcodeScanner;
import com.google.mlkit.vision.barcode.BarcodeScannerOptions;
import com.google.mlkit.vision.barcode.BarcodeScanning;
import com.google.mlkit.vision.common.InputImage;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE_PERMISSIONS = 10;
private static final String TAG = MainActivity.class.getSimpleName();
private ExecutorService cameraExecutor;
private PreviewView viewFinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//this view displays camera preview
viewFinder = findViewById(R.id.viewFinder);
//checks for permission to either start camera or request permission
if (hasCameraPermission()) {
startCamera();
} else {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_PERMISSIONS);
}
//executor where qr code evaluation will happen
cameraExecutor = Executors.newSingleThreadExecutor();
}
private boolean hasCameraPermission() {
return checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
private void startCamera() {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
//this will provide for us the frames from the camera
ProcessCameraProvider cameraProvider;
try {
cameraProvider = cameraProviderFuture.get();
} catch (ExecutionException | InterruptedException exception) {
Log.e(TAG, "Unable to get camera provider instance", exception);
return;
}
//set the view where preview will be shown
Preview preview = new Preview.Builder().build();
preview.setSurfaceProvider(viewFinder.createSurfaceProvider());
//use back camera
CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
//set up QR code analysis
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder().setTargetResolution(new Size(1280, 720)).build();
imageAnalysis.setAnalyzer(cameraExecutor, new QRCodeAnalyzer());
try {
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);
} catch (Exception exception) {
Log.e(TAG, "Use case binding failed", exception);
}
}, getMainExecutor());
}
@Override
protected void onDestroy() {
super.onDestroy();
cameraExecutor.shutdown();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (hasCameraPermission()) {
startCamera();
} else {
finish();
}
}
}
private static class QRCodeAnalyzer implements ImageAnalysis.Analyzer {
//this is from ml kit
private BarcodeScanner scanner;
QRCodeAnalyzer() {
BarcodeScannerOptions options = new BarcodeScannerOptions.Builder().setBarcodeFormats(Barcode.FORMAT_QR_CODE).build();
scanner = BarcodeScanning.getClient(options);
}
@Override
public void analyze(@NonNull ImageProxy image) {
//this analyze method will be called about every second and will provide a camera frame
//this API is from camerax library, so with this frame we will pass along ml kit library
//for it to tell us if there is any qr code in the image
ByteBuffer imageBuffer = image.getPlanes()[0].getBuffer();
InputImage inputImage = InputImage.fromByteBuffer(
imageBuffer,
image.getWidth(),
image.getHeight(),
image.getImageInfo().getRotationDegrees(),
InputImage.IMAGE_FORMAT_NV21
);
scanner.process(inputImage)
.addOnSuccessListener(barcodes -> {
//here we receive response from ml kit with the qr codes evaluated
for (Barcode barcode : barcodes) {
Log.i(TAG, "Read QR code: " + barcode.getDisplayValue());
}
if (barcodes.isEmpty()) {
Log.i(TAG, "No QR codes found");
}
})
.addOnFailureListener(e -> Log.e(TAG, "Failed to read QR code"));
image.close();
}
}
}
This is an old project that no longer receives support nor works 100% as expected.
For anyone looking for a simple solution to read QR codes you can use both Android CameraX library and Google ML Kit Barcode library as such:
build.gradle
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation 'com.google.mlkit:barcode-scanning:16.1.1' implementation "androidx.camera:camera-camera2:1.0.0-beta07" implementation "androidx.camera:camera-lifecycle:1.0.0-beta07" implementation "androidx.camera:camera-view:1.0.0-alpha14" }AndroidManifest.xml
activity_main.xml
MainActivity.java