如何使条形码扫描仪仅扫描一次(Google Mobile Vision API)?

时间:2018-01-25 23:08:11

标签: java android barcode google-vision

我正在使用谷歌移动视觉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();


        }
    }
}

2 个答案:

答案 0 :(得分:0)

您可以通过创建自己的内部使用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;
}

然后,您只需在“活动”中替换此行:

barcodeDetector = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.ALL_FORMATS).build();

使用此选项或类似选项:

barcodeDetector = new LimitToOneBarcodeDetector(this);

答案 1 :(得分:0)

此问题是,您继续通过startActivity(intent);开始新活动

不是用检测结果来完成当前活动...

ScannerClass开始startActivityForResult(),然后传回所有条形码:

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()中对其进行处理。