无法使用 Google 移动视觉 API 检测数据矩阵格式

Unable to detect data-matrix format with Google mobile vision API

大家好,我遇到了 Google 移动视觉 API 问题,尤其是数据矩阵格式问题。

我几乎可以扫描所有条形码格式,但是当我想扫描数据矩阵时,事情变得更难了。我只能检测到十分之一,很尴尬。

我遵循了文档并添加了如下检测格式:

我的 Activity 看起来像这样(拍摄:Google vision Android Github

public class QrScanActivity extends AppCompatActivity implements BarcodeTracker.BarcodeTrackerListener {

private static final String TAG = QrScanActivity.class.getSimpleName();

// permission request codes need to be < 256
private static final int RC_HANDLE_CAMERA_PERM = 2;

public static final String BARCODE_OBJECT = "Barcode";

private CameraSource _cameraSource;
private CameraSourcePreview _preview;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_qrscan);
    _preview = this.findViewById(R.id.preview);


    // Check for the camera permission before accessing the camera.  If the
    // permission is not granted yet, request permission.
    int rc = ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
    if (rc == PackageManager.PERMISSION_GRANTED) {
        createCameraSource(true);
    } else {
        requestCameraPermission();
    }

}

/**
 * Handles the requesting of the camera permission.  This includes
 * showing a "Snackbar" message of why the permission is needed then
 * sending the request.
 */
private void requestCameraPermission() {
    Log.w(TAG, "Camera permission is not granted. Requesting permission");

    final String[] permissions = new String[]{Manifest.permission.CAMERA};

    if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.CAMERA)) {
        ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
        return;
    }

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ActivityCompat.requestPermissions(QrScanActivity.this, permissions,
                    RC_HANDLE_CAMERA_PERM);
        }
    };

}

/**
 * Creates and starts the camera.  Note that this uses a higher resolution in comparison
 * to other detection examples to enable the barcode detector to detect small barcodes
 * at long distances.
 * <p>
 * Suppressing InlinedApi since there is a check that the minimum version is met before using
 * the constant.
 */
@SuppressLint("InlinedApi")
private void createCameraSource(boolean autoFocus) {
    Context context = getApplicationContext();

    // A barcode detector is created to track barcodes.  An associated multi-processor instance
    // is set to receive the barcode detection results, track the barcodes, and maintain
    // graphics for each barcode on screen.  The factory is used by the multi-processor to
    // create a separate tracker instance for each barcode.
    BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).setBarcodeFormats(Barcode.QR_CODE | Barcode.DATA_MATRIX | Barcode.AZTEC | Barcode.PDF417 | Barcode.CODE_39 |
            Barcode.EAN_8 | Barcode.EAN_13 | Barcode.UPC_A | Barcode.UPC_E | Barcode.CODE_93 | Barcode.CODE_128 | Barcode.ITF | Barcode.CODABAR).build();
    BarcodeTracker tracker = new BarcodeTracker(this);
    barcodeDetector.setProcessor(
            new FirstItemProcessor(barcodeDetector, tracker));

    if (!barcodeDetector.isOperational()) {
        // Note: The first time that an app using the barcode or face API is installed on a
        // device, GMS will download a native libraries to the device in order to do detection.
        // Usually this completes before the app is run for the first time.  But if that
        // download has not yet completed, then the above call will not detect any barcodes
        // and/or faces.
        //
        // isOperational() can be used to check if the required native libraries are currently
        // available.  The detectors will automatically become operational once the library
        // downloads complete on device.
        Log.w(TAG, "Detector dependencies are not yet available.");

        // Check for low storage.  If there is low storage, the native library will not be
        // downloaded, so detection will not become operational.
        IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
        boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null;

        if (hasLowStorage) {
            Toast.makeText(this, "low storage", Toast.LENGTH_LONG).show();
            Log.w(TAG, "low storage error");
        }
    }

    // Creates and starts the camera.  Note that this uses a higher resolution in comparison
    // to other detection examples to enable the barcode detector to detect small barcodes
    // at long distances.
    CameraSource.Builder builder = new CameraSource.Builder(getApplicationContext(), barcodeDetector)
            .setFacing(CameraSource.CAMERA_FACING_BACK)
            //.setRequestedPreviewSize(getWindow().getDecorView().getHeight(), getWindow().getDecorView().getWidth())
            .setRequestedFps(30.0f);

    builder = builder.setAutoFocusEnabled(autoFocus);

    _cameraSource = builder.build();
}

/**
 * Restarts the camera.
 */
@Override
protected void onResume() {
    super.onResume();
    startCameraSource();
    ((TracksApplication) getApplication()).set_currentClass(getClass().getSimpleName());
}

/**
 * Stops the camera.
 */
@Override
protected void onPause() {
    super.onPause();
    if (_preview != null) {
        _preview.stop();
    }
}

/**
 * Releases the resources associated with the camera source, the associated detectors, and the
 * rest of the processing pipeline.
 */
@Override
protected void onDestroy() {
    super.onDestroy();
    if (_preview != null) {
        _preview.release();
    }
}

/**
 * Callback for the result from requesting permissions. This method
 * is invoked for every call on {@link #requestPermissions(String[], int)}.
 * <p>
 * <strong>Note:</strong> It is possible that the permissions request interaction
 * with the user is interrupted. In this case you will receive empty permissions
 * and results arrays which should be treated as a cancellation.
 * </p>
 *
 * @param requestCode  The request code passed in {@link #requestPermissions(String[], int)}.
 * @param permissions  The requested permissions. Never null.
 * @param grantResults The grant results for the corresponding permissions
 *                     which is either {@link PackageManager#PERMISSION_GRANTED}
 *                     or {@link PackageManager#PERMISSION_DENIED}. Never null.
 * @see #requestPermissions(String[], int)
 */
@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode != RC_HANDLE_CAMERA_PERM) {
        Log.d(TAG, "Got unexpected permission result: " + requestCode);
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        return;
    }

    if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        Log.d(TAG, "Camera permission granted - initialize the camera source");
        // we have permission, so create the camerasourc
        createCameraSource(true);
        return;
    }

    Log.e(TAG, "Permission not granted: results len = " + grantResults.length +
            " Result code = " + (grantResults.length > 0 ? grantResults[0] : "(empty)"));

}

/**
 * Starts or restarts the camera source, if it exists.  If the camera source doesn't exist yet
 * (e.g., because onResume was called before the camera source was created), this will be called
 * again when the camera source is created.
 */
private void startCameraSource() throws SecurityException {

    if (_cameraSource != null) {
        try {
            _preview.start(_cameraSource);
        } catch (IOException e) {
            Log.e(TAG, "Unable to start camera source.", e);
            _cameraSource.release();
            _cameraSource = null;
        }
    }
}

@Override
public void onBarcodeDetected(Barcode barcode) {
    Intent data = new Intent();
    data.putExtra(BARCODE_OBJECT, barcode);
    setResult(CommonStatusCodes.SUCCESS, data);
    finish();
}
}

我不知道哪里出了问题,如果有人有想法...

问题是"solved",我收到的数据矩阵似乎有问题。 因为我试图用 IOS 设备或​​ Google Play 商店应用程序等多个扫描仪扫描那些东西,所以它们也无法识别。