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.
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!!