android - 出现2个代码时,Google Vision崩溃

标签 android crash qr-code barcode-scanner google-vision

我在应用程序中使用google vision读取条形码和二维码。这很好用,但是当扫描的表面彼此相邻有2个代码时会崩溃,如下图所示。

enter image description here

即使对代码进行了单独扫描,即使对它们进行了正确扫描,也会发生这种情况。有谁知道如何阻止这种情况的发生?

以下是管理代码扫描 Activity 的代码:

public class ScanningActivity extends AppCompatActivity {

    SurfaceView cameraPreview;
    BarcodeDetector barcodeDetector;
    CameraSource cameraSource;
    final Integer requestCameraPermissionID = 1001;

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

        final int height = getSurfaceViewHeight();
        final int width = getSurfaceViewWidth();

        cameraPreview = findViewById(R.id.surfaceview_scanner);

        barcodeDetector = new BarcodeDetector.Builder(AddScanningActivity.this)
                .setBarcodeFormats(Barcode.ALL_FORMATS)
                .build();
        cameraSource = new CameraSource.Builder(AddScanningActivity.this, barcodeDetector)
                .setAutoFocusEnabled(true)
                .setRequestedPreviewSize(width, height)
                .build();
        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) {
                    Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(VIBRATOR_SERVICE);
                    vibrator.vibrate(100);

                    Handler handler = new Handler(Looper.getMainLooper());
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            cameraSource.release();
                        }
                    });
                }
            }
        });
        cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                            ActivityCompat.requestPermissions(AddScanningActivity.this,
                                    new String[]{Manifest.permission.CAMERA}, requestCameraPermissionID);
                            return;
                        }
                        try {
                            cameraSource.start(cameraPreview.getHolder());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }, 100);
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

            }

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

    private Integer getSurfaceViewHeight() {
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        Integer screenHeight = size.y;

        Rect rectangle = new Rect();
        Window window = getWindow();
        window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
        final int statusBarHeight = rectangle.top;

        int[] attrs = new int[]{R.attr.actionBarSize};
        TypedArray ta = this.obtainStyledAttributes(attrs);
        final int actionBarHeight = ta.getDimensionPixelSize(0, -1);
        ta.recycle();
        return screenHeight - statusBarHeight - actionBarHeight;
    }

    private Integer getSurfaceViewWidth() {
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size.x;
    }
}

最佳答案

问题是在释放cameraSource之前,第二次调用了receiveDetections方法。然后第二次调用它,该方法尝试再次释放cameraSource,但是它不再可用,从而导致错误。下面是工作代码,只有一个小的简单更改,即使用 bool(boolean) 值“codeDetected”:

public class AddScanningActivity extends AppCompatActivity {

    SurfaceView cameraPreview;
    BarcodeDetector barcodeDetector;
    CameraSource cameraSource;
    final Integer requestCameraPermissionID = 1001;
    Boolean codeDetected = false;

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

        final int height = getSurfaceViewHeight();
        final int width = getSurfaceViewWidth();

        cameraPreview = findViewById(R.id.surfaceview_scanner);

        barcodeDetector = new BarcodeDetector.Builder(AddScanningActivity.this)
                .setBarcodeFormats(Barcode.ALL_FORMATS)
                .build();
        cameraSource = new CameraSource.Builder(AddScanningActivity.this, barcodeDetector)
                .setAutoFocusEnabled(true)
                .setRequestedPreviewSize(width, height)
                .build();
        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 && !codeDetected) {
                        codeDetected = true;
                        Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(VIBRATOR_SERVICE);
                        vibrator.vibrate(100);

                        Handler handler = new Handler(Looper.getMainLooper());
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                cameraSource.release();
                            }
                        });
                    }
            }
        });
        cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                            ActivityCompat.requestPermissions(AddScanningActivity.this,
                                    new String[]{Manifest.permission.CAMERA}, requestCameraPermissionID);
                            return;
                        }
                        try {
                            cameraSource.start(cameraPreview.getHolder());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }, 100);
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

            }

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

    private Integer getSurfaceViewHeight() {
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        Integer screenHeight = size.y;

        Rect rectangle = new Rect();
        Window window = getWindow();
        window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
        final int statusBarHeight = rectangle.top;

        int[] attrs = new int[] {R.attr.actionBarSize};
        TypedArray ta = this.obtainStyledAttributes(attrs);
        final int actionBarHeight = ta.getDimensionPixelSize(0, -1);
        ta.recycle();
        return screenHeight - statusBarHeight - actionBarHeight;
    }

    private Integer getSurfaceViewWidth() {
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size.x;
    }
}

关于android - 出现2个代码时,Google Vision崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48400312/

相关文章:

android - 抽屉布局打开时主要布局内容仍然可见

android - Crashlytics 报告上传因 java.lang.OutOfMemoryError 而崩溃

c# - 程序在启动后几乎立即崩溃

ios - Xamarin Forms App 在 iOS 上以 Release模式崩溃,但在 Debug模式下工作

android - 使用 Android 阅读低对比度 (3D) 打印的二维码

java - Android Vision Barcode API - 使用二进制数据读取自定义二维码

android - SD卡图像的相对路径

java - 在 Bundle 测试中设置 EditText 不起作用

java - 如何在 Nativescript 中使用接口(interface)类型参数调用 Java 方法(自定义类)

ios - 如何检查扫描的二维码是否包含除数字之外的任何内容