Skip to content

Commit a3b8600

Browse files
authored
Merge pull request #135 from googlesamples/tap-fix
Return tapped (or closest) barcode result to calling Activity.
2 parents 9278a0c + e39a8e6 commit a3b8600

File tree

2 files changed

+50
-33
lines changed

2 files changed

+50
-33
lines changed

visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/BarcodeCaptureActivity.java

+30-20
Original file line numberDiff line numberDiff line change
@@ -325,41 +325,51 @@ private void startCameraSource() throws SecurityException {
325325
}
326326

327327
/**
328-
* onTap is called to capture the oldest barcode currently detected and
329-
* return it to the caller.
328+
* onTap returns the tapped barcode result to the calling Activity.
330329
*
331330
* @param rawX - the raw position of the tap
332331
* @param rawY - the raw position of the tap.
333332
* @return true if the activity is ending.
334333
*/
335334
private boolean onTap(float rawX, float rawY) {
336-
337-
//TODO: use the tap position to select the barcode.
338-
BarcodeGraphic graphic = mGraphicOverlay.getFirstGraphic();
339-
Barcode barcode = null;
340-
if (graphic != null) {
341-
barcode = graphic.getBarcode();
342-
if (barcode != null) {
343-
Intent data = new Intent();
344-
data.putExtra(BarcodeObject, barcode);
345-
setResult(CommonStatusCodes.SUCCESS, data);
346-
finish();
335+
// Find tap point in preview frame coordinates.
336+
int[] location = new int[2];
337+
mGraphicOverlay.getLocationOnScreen(location);
338+
float x = (rawX - location[0]) / mGraphicOverlay.getWidthScaleFactor();
339+
float y = (rawY - location[1]) / mGraphicOverlay.getHeightScaleFactor();
340+
341+
// Find the barcode whose center is closest to the tapped point.
342+
Barcode best = null;
343+
float bestDistance = Float.MAX_VALUE;
344+
for (BarcodeGraphic graphic : mGraphicOverlay.getGraphics()) {
345+
Barcode barcode = graphic.getBarcode();
346+
if (barcode.getBoundingBox().contains((int) x, (int) y)) {
347+
// Exact hit, no need to keep looking.
348+
best = barcode;
349+
break;
347350
}
348-
else {
349-
Log.d(TAG, "barcode data is null");
351+
float dx = x - barcode.getBoundingBox().centerX();
352+
float dy = y - barcode.getBoundingBox().centerY();
353+
float distance = (dx * dx) + (dy * dy); // actually squared distance
354+
if (distance < bestDistance) {
355+
best = barcode;
356+
bestDistance = distance;
350357
}
351358
}
352-
else {
353-
Log.d(TAG,"no barcode detected");
359+
360+
if (best != null) {
361+
Intent data = new Intent();
362+
data.putExtra(BarcodeObject, best);
363+
setResult(CommonStatusCodes.SUCCESS, data);
364+
finish();
365+
return true;
354366
}
355-
return barcode != null;
367+
return false;
356368
}
357369

358370
private class CaptureGestureListener extends GestureDetector.SimpleOnGestureListener {
359-
360371
@Override
361372
public boolean onSingleTapConfirmed(MotionEvent e) {
362-
363373
return onTap(e.getRawX(), e.getRawY()) || super.onSingleTapConfirmed(e);
364374
}
365375
}

visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/GraphicOverlay.java

+20-13
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import com.google.android.gms.vision.CameraSource;
2424

2525
import java.util.HashSet;
26+
import java.util.List;
2627
import java.util.Set;
28+
import java.util.Vector;
2729

2830
/**
2931
* A view which renders a series of custom graphics to be overlayed on top of an associated preview
@@ -51,7 +53,6 @@ public class GraphicOverlay<T extends GraphicOverlay.Graphic> extends View {
5153
private float mHeightScaleFactor = 1.0f;
5254
private int mFacing = CameraSource.CAMERA_FACING_BACK;
5355
private Set<T> mGraphics = new HashSet<>();
54-
private T mFirstGraphic;
5556

5657
/**
5758
* Base class for a custom graphics object to be rendered within the graphic overlay. Subclass
@@ -129,7 +130,6 @@ public GraphicOverlay(Context context, AttributeSet attrs) {
129130
public void clear() {
130131
synchronized (mLock) {
131132
mGraphics.clear();
132-
mFirstGraphic = null;
133133
}
134134
postInvalidate();
135135
}
@@ -140,9 +140,6 @@ public void clear() {
140140
public void add(T graphic) {
141141
synchronized (mLock) {
142142
mGraphics.add(graphic);
143-
if (mFirstGraphic == null) {
144-
mFirstGraphic = graphic;
145-
}
146143
}
147144
postInvalidate();
148145
}
@@ -153,24 +150,34 @@ public void add(T graphic) {
153150
public void remove(T graphic) {
154151
synchronized (mLock) {
155152
mGraphics.remove(graphic);
156-
if (mFirstGraphic != null && mFirstGraphic.equals(graphic)) {
157-
mFirstGraphic = null;
158-
}
159153
}
160154
postInvalidate();
161155
}
162156

163157
/**
164-
* Returns the first (oldest) graphic added. This is used
165-
* to get the barcode that was detected first.
166-
* @return graphic containing the barcode, or null if no barcodes are detected.
158+
* Returns a copy (as a list) of the set of all active graphics.
159+
* @return list of all active graphics.
167160
*/
168-
public T getFirstGraphic() {
161+
public List<T> getGraphics() {
169162
synchronized (mLock) {
170-
return mFirstGraphic;
163+
return new Vector(mGraphics);
171164
}
172165
}
173166

167+
/**
168+
* Returns the horizontal scale factor.
169+
*/
170+
public float getWidthScaleFactor() {
171+
return mWidthScaleFactor;
172+
}
173+
174+
/**
175+
* Returns the vertical scale factor.
176+
*/
177+
public float getHeightScaleFactor() {
178+
return mHeightScaleFactor;
179+
}
180+
174181
/**
175182
* Sets the camera attributes for size and facing direction, which informs how to transform
176183
* image coordinates later.

0 commit comments

Comments
 (0)