Search code examples
androidbarcode-scanner

Android: AlertDialog.builder at Barcode Scanner appears twice


I want to display the AlertDialog once I successfully scan and get the barcode data. Then when I click on OK button on AlertDialog, it will continue to scan the barcode again. All are working fine except the AlertDialog, the data is scanned and the AlertDialog is displayed as well but it displays twice of it. I only want to display one.

The working flow is first createCameraSource(), then scan a barcode and then display AlertDialog function named dialogRack(String ..), then open camera again openCameraAgain() and scan a barcode and display the AlertDialog, function named dialogItem(String ..). AlertDialog appears twice happen on after openCameraAgain() function

createCameraSource()

private void createCameraSource() {
    barcodeDetector = new BarcodeDetector.Builder(this)
            .setBarcodeFormats(Barcode.ALL_FORMATS)
            .build();
    surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(@NonNull SurfaceHolder holder) {
            if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                int width = surfaceView.getWidth();
                int height = surfaceView.getHeight();
                cameraSource = new CameraSource.Builder(ScanActivity.this, barcodeDetector)
                        .setRequestedPreviewSize(height, width)
                        .setAutoFocusEnabled(true)
                        .build();
                try {
                    cameraSource.start(surfaceView.getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                ActivityCompat.requestPermissions(ScanActivity.this, new
                        String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); //CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE
            }
        }

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

        @Override
        public void surfaceDestroyed(@NonNull 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> barcodes = detections.getDetectedItems();
            if (barcodes.size() != 0 && !decoded) {
                decoded = true;
                try {
                    intentData = URLDecoder.decode(barcodes.valueAt(0).displayValue, "UTF-8");
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            cameraSource.stop();
                            barcodeDetector.release();
                            dialogRack(intentData);
                        }
                    });
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            } //End of if
        }
    });
} // End of createCameraSource function

dialogRack(final String rackNumber)

private void dialogRack(final String rackNumber) {
    Log.i("Alert Dialog", "Alert Dialog created for Rack Scanned");
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(ScanActivity.this);
    alertDialog.setTitle("Rack")
            .setMessage("Rack Number : " + rackNumber)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    tvRack.setText(rackNumber);
                    openCameraAgain();
                }
            }).create().show();
}

openCameraAgain()

private void openCameraAgain(){
    Log.i("Camera Scan", "openCamera() start");
    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    try {
        cameraSource.start(surfaceView.getHolder());
    } catch (IOException e) {
        e.printStackTrace();
    }
    barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
        @Override
        public void release() { }

        @Override
        public void receiveDetections(Detector.Detections<Barcode> detections) {
            //Start scanning for item
            final SparseArray<Barcode> itemBarCode = detections.getDetectedItems();
            if (itemBarCode.size() != 0) {
                try {
                    intentData = URLDecoder.decode(itemBarCode.valueAt(0).displayValue, "UTF-8");
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            cameraSource.stop();
                            barcodeDetector.release();
                            Log.i("Camera Close", "Camera Source Stop, Barcode Detector Off");
                            dialogItem(intentData);
                        }
                    });
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            } //End of if
        }
    });
}

dialogItem(final String itemNumber)

private void dialogItem(final String itemNumber){
    Log.i("Alert Dialog", "Alert Dialog created for Item Scanned");
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(ScanActivity.this);
    alertDialog.setTitle("Item")
            .setMessage("Scanned Item Number : " + itemNumber)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    try {
                        arrayListSerialNumber.add(itemNumber);
                        adapter.notifyDataSetChanged();
                        openCameraAgain();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }).create().show();
}

Solution

  • Well, I solved my issue using static for creating AlertDialog.

    static AlertDialog dialog;
    static AlertDialog.Builder alertDialog;
    

    the display dialog function, create the dialog and show

    private void dialogRack(final String rackNumber) {
        alertDialog = new AlertDialog.Builder(ScanActivity.this);
        alertDialog.setTitle("Title")
                .setMessage("Message")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                       // onClick Function
                    }
                });
        dialog = alertDialog.create();
        dialog.show();
    } //end of dialogRack
    

    and to ensure your dialog is dismiss after click, you could use the if-else statement as below,

    if(dialog != null && dialog.isShowing()){
      //Action or wait for dismiss
    }else{
      //Dialog is closed
    }