I have tried new Google Play Services feature - Barcode/QR scanner. In sample application is scanning started by taping on button and result is returned also on tap.
Is there a way to change its behavior to return first detected barcode/QR immediately?
I am not the first one curious about this.
Thank you in advance.
I would advice against creating static variables. They will bite you later.
My recommendation is to create some kind of listener/callback on your TrackerFactory
and use it on your Trackers
. This is the pattern that Fragments
, Adapters
and plenty of other Android classes use, so why not copy them?
Step 1: Create an Interface in your BarcodeGraphicTracker
(code for parts that changed): Here listener is initialised which sends the final callback response upon first successful detection, back to Tracker Activity
(one where camera first opens).
public class BarcodeGraphicTracker extends Tracker<Barcode> {
private GraphicOverlay<BarcodeGraphic> mOverlay;
private BarcodeGraphic mGraphic;
private NewDetectionListener mListener;
[...]
@Override
public void onNewItem(int id, Barcode item) {
mGraphic.setId(id);
if (mListener != null) mListener.onNewDetection(item);
}
public void setListener(NewDetectionListener mListener) {
this.mListener = mListener;
}
[...]
public interface NewDetectionListener {
void onNewDetection(Barcode barcode);
}
}
Step 2: Change the Constructor of your BarcodeTrackerFactory to implement the interface. The listener instance is passed on to BarcodeGraphicTracker
for initialisation. Code:
public class BarcodeTrackerFactory implements MultiProcessor.Factory<Barcode> {
private BarcodeGraphicTracker.NewDetectionListener newDetectionListener;
private GraphicOverlay<BarcodeGraphic> mGraphicOverlay;
public BarcodeTrackerFactory(GraphicOverlay<BarcodeGraphic> barcodeGraphicOverlay, BarcodeGraphicTracker.NewDetectionListener listener) {
mGraphicOverlay = barcodeGraphicOverlay;
newDetectionListener = listener;
}
@Override
public Tracker<Barcode> create(Barcode barcode) {
BarcodeGraphic graphic = new BarcodeGraphic(mGraphicOverlay);
BarcodeGraphicTracker tracker = new BarcodeGraphicTracker(mGraphicOverlay, graphic);
if (newDetectionListener != null) tracker.setListener(newDetectionListener);
return tracker;
}
}
Final Step: In your Tracker Activity
initialise detector instance with the callback. This callback can be used to listen the data from first detected Bar/QR Code.
BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(graphicOverlay,
new BarcodeGraphicTracker.NewDetectionListener() {
@Override
public void onNewDetection(Barcode barcode) {
Log.d("Barcode detected! - " + barcode.displayValue);
//To send the result back to the Activity which is waiting for the result
Intent data = new Intent();
data.putExtra(BarcodeObject, barcode);
setResult(CommonStatusCodes.SUCCESS, data);
finish();
}
});
barcodeDetector.setProcessor(new MultiProcessor.Builder<>(barcodeFactory).build());