package org.awesomeapp.messenger.ui.qr; import android.hardware.Camera; import android.hardware.Camera.PreviewCallback; import android.hardware.Camera.Size; import android.os.AsyncTask; import android.util.Log; import com.google.zxing.BinaryBitmap; import com.google.zxing.LuminanceSource; import com.google.zxing.PlanarYUVLuminanceSource; import com.google.zxing.Reader; import com.google.zxing.ReaderException; import com.google.zxing.Result; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.QRCodeReader; @SuppressWarnings("deprecation") public class QrCodeDecoder implements PreviewConsumer, PreviewCallback { private static final String TAG = QrCodeDecoder.class.getPackage().getName(); private final Reader reader = new QRCodeReader(); private final ResultCallback callback; private boolean stopped = false; public QrCodeDecoder(ResultCallback callback) { this.callback = callback; } public void start(Camera camera) { Log.d(TAG, "Started"); stopped = false; askForPreviewFrame(camera); } public void stop() { Log.d(TAG, "Stopped"); stopped = true; } private void askForPreviewFrame(Camera camera) { if(!stopped) camera.setOneShotPreviewCallback(this); } public void onPreviewFrame(byte[] data, Camera camera) { if(!stopped) { Size size = camera.getParameters().getPreviewSize(); new DecoderTask(camera, data, size.width, size.height).execute(); } } private class DecoderTask extends AsyncTask<Void, Void, Void> { final Camera camera; final byte[] data; final int width, height; DecoderTask(Camera camera, byte[] data, int width, int height) { this.camera = camera; this.data = data; this.width = width; this.height = height; } @Override protected Void doInBackground(Void... params) { long now = System.currentTimeMillis(); LuminanceSource src = new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(src)); Result result = null; try { result = reader.decode(bitmap); } catch(ReaderException e) { return null; // No barcode found } finally { reader.reset(); } long duration = System.currentTimeMillis() - now; Log.d(TAG, "Decoding barcode took " + duration + " ms"); callback.handleResult(result); return null; } @Override protected void onPostExecute(Void result) { askForPreviewFrame(camera); } } public interface ResultCallback { void handleResult(Result result); } }