Android: AlertDialog.builder 在条形码扫描仪出现两次

Android: AlertDialog.builder at Barcode Scanner appears twice

我想在成功扫描并获取条码数据后显示AlertDialog。然后当我点击 AlertDialog 上的 OK 按钮时,它会继续再次扫描条形码。除了 AlertDialog 以外,其他都工作正常,数据被扫描并且 AlertDialog 也被显示,但它显示了它的两倍。我只想显示一个。

工作流程是先createCameraSource(),然后扫描条码,然后显示AlertDialog函数dialogRack(String ..),然后再次打开相机openCameraAgain(),扫描条码和显示名为 dialogItem(String ..)AlertDialog 函数。 AlertDialog 出现两次发生在 openCameraAgain() 函数

之后

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();
}

AlertDialog 两次,因为您需要在单击 alertDialog 时关闭 dialogItem 对话框 ok button.Otherwise 您单击 ok 按钮的次数不会达到 AlertDialog.

所以在 DialogItem 上点击 OK

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 {
  //CANCEL YOUR ALERT DIALOG HERE BEFORE OPENCAMERA 
                        arrayListSerialNumber.add(itemNumber);
                        adapter.notifyDataSetChanged();
                        openCameraAgain();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }).create().show();

}

好吧,我使用 static 创建 AlertDialog 解决了我的问题。

static AlertDialog dialog;
static AlertDialog.Builder alertDialog;

显示对话框函数,创建对话框并显示

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

并确保您的 dialog 在点击后被关闭,您可以使用如下 if-else 语句,

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