如何使条码扫描仪只扫描一次(谷歌移动视觉 API)?
Posted
技术标签:
【中文标题】如何使条码扫描仪只扫描一次(谷歌移动视觉 API)?【英文标题】:How to make Barcode Scanner only scan once (Google Mobile Vision API)? 【发布时间】:2018-07-05 07:43:51 【问题描述】:我正在使用谷歌移动视觉 api 开发一个具有条形码扫描仪的应用程序。我应该只能在 ScannerClassy.java 中扫描一次并将结果保存在 MainActivity 中。问题是当我扫描条形码时,它打开 MainActivity.java 5-7 次。我尝试使用 camerasource.release() 但它不起作用。
ScannerClass.java
import com.example.MashapeHello.R;
import com.google.android.gms.vision.Detector;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
public class ScannerClass extends AppCompatActivity implements Detector.Processor
private TextView textView;
private SurfaceView surfaceView;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);
barcodeDetector = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.ALL_FORMATS).build();
barcodeDetector.setProcessor(this);
cameraSource = new CameraSource.Builder(getApplicationContext(), barcodeDetector).
setRequestedPreviewSize(1024,1024).setAutoFocusEnabled(true)
.build();
final Activity activity = this;
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback()
@Override
public void surfaceCreated(SurfaceHolder holder)
try
if(ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(activity, new String[]Manifest.permission.CAMERA,1024);
return;
cameraSource.start(surfaceView.getHolder());
catch (IOException ie)
Log.e("Camera start problem", ie.getMessage());
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
@Override
public void surfaceDestroyed(SurfaceHolder holder)
cameraSource.stop();
);
@Override
public void release()
@Override
public void receiveDetections(Detector.Detections detections)
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0)
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < barcodes.size(); ++i)
sb.append(barcodes.valueAt(i).rawValue).append("\n");
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("barcodevalue", sb.toString());
startActivity(intent);
cameraSource.release();
【问题讨论】:
【参考方案1】:您可以通过创建自己的条形码检测器类来解决此问题,该类在内部使用 BarcodeDetector 类。这是一个简单的例子:
public class LimitToOneBarcodeDetector extends Detector<Barcode>
private BarcodeDetector internalDetector;
public LimitToOneBarcodeDetector(Context context)
this.internalDetector = new BarcodeDetector.Builder(App.getContext())
.setBarcodeFormats(Barcode.ALL_FORMATS)
.build();
@Override
public SparseArray<Barcode> detect(Frame frame)
SparseArray<Barcode> detected = this.internalDetector.detect(frame);
if (detected == null)
// Nothing detected, kick out an empty array
return new SparseArray<>();
if (detected.size() == 0)
// Detected size = 0 , kick out an empty array
return new SparseArray<>();
if (detected.size() > 1)
// Detected more than one barcode, kick out an empty array
return new SparseArray<>();
// If we're here, there is only one barcode, return the array
return detected;
然后您只需在 Activity 中替换此行:
barcodeDetector = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.ALL_FORMATS).build();
有了这个或类似的东西:
barcodeDetector = new LimitToOneBarcodeDetector(this);
【讨论】:
【参考方案2】:这个问题是,你不断用startActivity(intent);
开始新的活动
而不是用检测结果结束当前活动...
最好以startActivityForResult()
开头ScannerClass
并传回所有条形码:
if (barcodes.size() > 0)
cameraSource.release();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < barcodes.size(); ++i)
sb.append(barcodes.valueAt(i).rawValue).append("\n");
Intent data = new Intent();
data.putExtra("barcodes", sb.toString());
this.setResult(AppCompatActivity.RESULT_OK, data);
this.finish();
然后可以在方法MainActivity.onActivityResult()
中处理这些。
【讨论】:
以上是关于如何使条码扫描仪只扫描一次(谷歌移动视觉 API)?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 google vision api 一次扫描 10 张图像 ocr?到目前为止只做了1