Replace barcodescanner with CameraX and ZXing

This removes the dependency on ``me.dm7.barcodescanner:zxing`` and replaces it
with our own QR code scanner implementation using CameraX and ZXing. The main
reason for this change is to hopefully get better compatibility with obscure
devices. The barcodescanner library we were previously using seems unmaintained,
while Google is apparently putting a lot of effort into CameraX.

ScannerActivity has been almost entirely rewritten, but the functionality is
exactly the same as before.
This commit is contained in:
Alexander Bakker 2020-06-07 22:29:52 +02:00
parent 626995ec91
commit c65ed16790
5 changed files with 183 additions and 141 deletions

View file

@ -0,0 +1,68 @@
package com.beemdevelopment.aegis.helpers;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import java.nio.ByteBuffer;
import static android.graphics.ImageFormat.YUV_420_888;
import static android.graphics.ImageFormat.YUV_422_888;
import static android.graphics.ImageFormat.YUV_444_888;
public class QrCodeAnalyzer implements ImageAnalysis.Analyzer {
private static final String TAG = QrCodeAnalyzer.class.getSimpleName();
private final QrCodeAnalyzer.Listener _listener;
public QrCodeAnalyzer(QrCodeAnalyzer.Listener listener) {
_listener = listener;
}
@Override
public void analyze(@NonNull ImageProxy image) {
int format = image.getFormat();
if (format != YUV_420_888 && format != YUV_422_888 && format != YUV_444_888) {
Log.e(TAG, String.format("Expected YUV format, got %d instead", format));
image.close();
return;
}
ByteBuffer buf = image.getPlanes()[0].getBuffer();
byte[] data = new byte[buf.remaining()];
buf.get(data);
buf.rewind();
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
data, image.getWidth(), image.getHeight(), 0, 0, image.getWidth(), image.getHeight(), false
);
QRCodeReader reader = new QRCodeReader();
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
Result result = reader.decode(bitmap);
if (_listener != null) {
_listener.onQrCodeDetected(result);
}
} catch (ChecksumException | FormatException | NotFoundException ignored) {
} finally {
image.close();
}
}
public interface Listener {
void onQrCodeDetected(Result result);
}
}