How to set Google Vision QR Scanner to detect only one value?

☆樱花仙子☆ 提交于 2020-01-06 08:33:21

问题


I have implemented a QR scanner(QRScanner class) using Google Vision API. Once a value is detected it is passed to another activity(Info class) using Intents. The problem is that once a QR code is scanned the Info class gets opened several times.I want to limit the QRScanner class to get only one QR value and Info classed to be opened only once.

QRScanner Class

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qr_scanner);

cameraPreview = (SurfaceView) findViewById(R.id.camera_surface);
qrResult = (TextView) findViewById(R.id.scannerResult);
setupCamera();
}

private void setupCamera() {

BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.QR_CODE).build();
final CameraSource cameraSource = new CameraSource.Builder(this, barcodeDetector)
        .setAutoFocusEnabled(true)
        .setRequestedPreviewSize(1600, 1024)
        .build();

cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        if (ActivityCompat.checkSelfPermission(QrScanner.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        try {
            cameraSource.start(cameraPreview.getHolder());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        cameraSource.stop();
    }
});


barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
    @Override
    public void release() {

    }

    @Override
    public void receiveDetections(Detector.Detections<Barcode> detections) {

        final SparseArray<Barcode> qrCodes = detections.getDetectedItems();

        if(qrCodes.size()>0)
        {
            qrResult.post(new Runnable() {
                @Override
                public void run() {

                    qrResult.setText(qrCodes.valueAt(0).displayValue);
                    Intent intent = new Intent(QrScanner.this,Info.class);
                    intent.putExtra(QR_CODE,qrCodes.valueAt(0).displayValue);
                    startActivity(intent);
                }
            });
        }
    }
});
}

Info Class

Intent intent = getIntent();
QRCODE = (String) intent.getStringExtra(QrScanner.QR_CODE);

DB = FirebaseDatabase.getInstance();
ref = DB.getReference().child("Animals").child(QRCODE);
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

        String DBAnimalClass = dataSnapshot.child("class").getValue().toString();
        String DBAnimalFamily = dataSnapshot.child("family").getValue().toString();
        String DBAnimalOrder = dataSnapshot.child("order").getValue().toString();

    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {

    }
});

Currently once a QR is detected the Info class gets called several times. I want the QRScanner to get only one value and Info class to get called only once.


回答1:


You camera is detecting QRCode continuously that'y your activity opens multiple times . So you need to stop camera when you detect anything successfully.

 if(qrCodes.size()>0)
        {

            cameraSource.stop(); // ADD THIS. THIS WILL STOP CAMERA
            qrResult.post(new Runnable() {
                @Override
                public void run() {

                    qrResult.setText(qrCodes.valueAt(0).displayValue);
                    Intent intent = new Intent(QrScanner.this,Info.class);
                    intent.putExtra(QR_CODE,qrCodes.valueAt(0).displayValue);
                    startActivity(intent);
                }
            });
        }



回答2:


I think you need to collect data and pass it outside of inner class.

Example:

@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
    final SparseArray<Barcode> qrCodes = detections.getDetectedItems();
    final String qrData = "";
    if(qrCodes.size()>0){
        qrResult.post(new Runnable() {
            @Override
            public void run() {
                qrData = qrCodes.valueAt(0).displayValue;
            }
        });
    }
    qrResult.setText(qrData);
    goToPage(qrData);
}


private void goToPage (String qrData) {
    Intent intent = new Intent(QrScanner.this,IDNA.Info.class);
    intent.putExtra(QR_CODE,qrData);
    startActivity(intent);
}



回答3:


Use this library MobileVisionBarcodeScanner

You can Enable and Disable the Multiple scanning .setSupportMultipleScan(true/false)

and stop scanning using

barcodeCapture.stopScanning();

lots more features there.




回答4:


After some research I found out how to fix this. However after coming back to this activity by pressing the back button from the activity loaded through intent, the scanner wont work anymore therefore the onCreate() method should be reloaded.

working code

if(qrCodes.size()>0)
    {

        barcodeDetector.release(); //stops the scanner from reading multiple values
        qrResult.post(new Runnable() {
            @Override
            public void run() {

                qrResult.setText(qrCodes.valueAt(0).displayValue);
                Intent intent = new Intent(QrScanner.this,Info.class);
                intent.putExtra(QR_CODE,qrCodes.valueAt(0).displayValue);
                startActivity(intent);
            }
        });
    }

The reason cameraSource.stop() won't work is explained in this link; https://stackoverflow.com/a/41024780/6737536

hope it helps!!



来源:https://stackoverflow.com/questions/54683291/how-to-set-google-vision-qr-scanner-to-detect-only-one-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!