How to get detected barcode/QR automatically
Asked Answered
T

2

5

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.

Takeover answered 27/10, 2015 at 14:58 Comment(0)
H
8

UPDATE!

For future readers you can use this project, which includes a full screen preview on almost all devices as well. The previous answer was not a solid implementation but more of a quick solution. The github repository contains all the changes and check the changelog as well.

  1. MainAcitivity.java
  2. BarcodeCaptureActivity.java
  3. CameraSource.java
  4. BarcodeGraphicTracker.java
Howdah answered 31/10, 2015 at 10:51 Comment(8)
Thank you, I'll give it a try.Takeover
@Takeover dont forget to upvote good answers. (specially meaningful if the individual has few rep points)Robledo
Don't worry guys, I have this page still opened in my browser, just don't have enought time to try it. :-( I'll do it asap.Takeover
It works, I've done it and am using it.. (and added relevant code in case you need to know how to startActivityForResult and get the relevant result.)Robledo
Tested and works! Thank you very much. Answer is upvoted and approved now!Takeover
what is ActivitySource?Causalgia
@gaurav A class, that approach is way out of date and also wasn't the best of implementations. You might want to check out the my repository here same as that given above Github ProjectHowdah
A class that only contains a static reference of an activity used as an interface. And then logging info/debug stuff as error. This code belongs to the 7th circle of hellRayon
A
15

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());
Antiseptic answered 22/2, 2016 at 21:14 Comment(4)
Works like a charm!! This way is better than accepted answer.Peder
This post also utilizes a similar method (an activity callback) for those who want additional reference on the idea: #32021693 I also agree that this method is better than creating a static reference to your activity.Damalas
Correct and recommended style. Works like a charm! Thanks. Suggestion: Correctly order the 3 examples above, easier to implement for beginners.Endogenous
Appreciate it. Works perfectly.Radiothorium
H
8

UPDATE!

For future readers you can use this project, which includes a full screen preview on almost all devices as well. The previous answer was not a solid implementation but more of a quick solution. The github repository contains all the changes and check the changelog as well.

  1. MainAcitivity.java
  2. BarcodeCaptureActivity.java
  3. CameraSource.java
  4. BarcodeGraphicTracker.java
Howdah answered 31/10, 2015 at 10:51 Comment(8)
Thank you, I'll give it a try.Takeover
@Takeover dont forget to upvote good answers. (specially meaningful if the individual has few rep points)Robledo
Don't worry guys, I have this page still opened in my browser, just don't have enought time to try it. :-( I'll do it asap.Takeover
It works, I've done it and am using it.. (and added relevant code in case you need to know how to startActivityForResult and get the relevant result.)Robledo
Tested and works! Thank you very much. Answer is upvoted and approved now!Takeover
what is ActivitySource?Causalgia
@gaurav A class, that approach is way out of date and also wasn't the best of implementations. You might want to check out the my repository here same as that given above Github ProjectHowdah
A class that only contains a static reference of an activity used as an interface. And then logging info/debug stuff as error. This code belongs to the 7th circle of hellRayon

© 2022 - 2024 — McMap. All rights reserved.