如何让条形码扫描器仅扫描一次(Google移动视觉API)?

4

我正在开发一个应用程序,其中使用了Google移动视觉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
你可以通过创建自己的条形码检测器类来解决这个问题,该类在内部使用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);

0

问题在于,您一直使用 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()中处理这些内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接