How to fix Google code scanner throwing "MlKitException: Failed to scan code"
Asked Answered
F

3

12

I have followed the tutorial here and got it work just fine. Then later, using the same code, I am getting this exception every time I try to open the QR code scanner:

com.google.mlkit.common.MlKitException: Failed to scan code.

I don't even leave my app, the exception is instantaneous.

It really bothers me on how this was working before and now it just doesn't work anymore.

Frug answered 21/4, 2023 at 16:50 Comment(2)
We do not recommend this lib in prod, very unreliable, we must stop using it immediatelly, it failures on many different devices (Google code scanner "Failed to scan code." or scanner unavailable). Google has reported bug but did not solve it issuetracker.google.com/issues/261579118Bosh
The best I could get was the answer I posted hereFrug
W
3

I post my solution to these problem. This solve problem to barcore scann error:

Found in this guide: https://developers.google.com/android/guides/module-install-apis?hl=es-419

public void onScanButtonClicked() {

    GmsBarcodeScannerOptions.Builder optionsBuilder = new GmsBarcodeScannerOptions.Builder();
    if (allowManualInput) {
        optionsBuilder.allowManualInput();
    }
    if (enableAutoZoom) {
        optionsBuilder.enableAutoZoom();
    }

    ModuleInstallClient moduleInstallClient = ModuleInstall.getClient(getContext());

    OptionalModuleApi optionalModuleApi = GmsBarcodeScanning.getClient(getContext());
    moduleInstallClient
            .areModulesAvailable(optionalModuleApi)
            .addOnSuccessListener(
                    response -> {
                        if (response.areModulesAvailable()) {
                            // Modules are present on the device...
                            barcodeResultView.setText("Modules are present on the device");
                            GmsBarcodeScanner gmsBarcodeScanner = GmsBarcodeScanning.getClient(getContext(), optionsBuilder.build());
                            gmsBarcodeScanner
                                    .startScan()
                                    .addOnSuccessListener(barcode -> barcodeResultView.setText(getSuccessfulMessage(barcode)))
                                    .addOnFailureListener(
                                            e -> barcodeResultView.setText(getErrorMessage(e)))
                                    .addOnCanceledListener(
                                            () -> barcodeResultView.setText(getString(R.string.error_scanner_cancelled)));
                        } else {
                            // Modules are not present on the device...
                            barcodeResultView.setText("Modules are not present on the device");
                            moduleInstall();
                        }
                    })
            .addOnFailureListener(
                    e -> {
                        // Handle failure…
                        barcodeResultView.setText("Handle failure…");
                    });
}

final class ModuleInstallProgressListener implements InstallStatusListener {
    @Override
    public void onInstallStatusUpdated(ModuleInstallStatusUpdate update) {
        ModuleInstallStatusUpdate.ProgressInfo progressInfo = update.getProgressInfo();
        // Progress info is only set when modules are in the progress of downloading.
        if (progressInfo != null) {
            int progress =
                    (int) (progressInfo.getBytesDownloaded() * 100 / progressInfo.getTotalBytesToDownload());
            // Set the progress for the progress bar.
            progressBar.setProgress(progress);
        }
        // Handle failure status maybe…

        // Unregister listener when there are no more install status updates.
        if (isTerminateState(update.getInstallState())) {

            moduleInstallClient.unregisterListener(this);
        }
    }

    public boolean isTerminateState(@ModuleInstallStatusUpdate.InstallState int state) {
        return state == STATE_CANCELED || state == STATE_COMPLETED || state == STATE_FAILED;
    }
}

private void moduleInstall(){
    InstallStatusListener listener = new ModuleInstallProgressListener();

    OptionalModuleApi optionalModuleApi = GmsBarcodeScanning.getClient(getContext());
    ModuleInstallRequest moduleInstallRequest =
            ModuleInstallRequest.newBuilder()
                    .addApi(optionalModuleApi)
                    // Add more API if you would like to request multiple optional modules
                    //.addApi(...)
                    // Set the listener if you need to monitor the download progress
                    .setListener(listener)
                    .build();

    moduleInstallClient.installModules(moduleInstallRequest)
            .addOnSuccessListener(
                    response -> {
                        if (response.areModulesAlreadyInstalled()) {
                            // Modules are already installed when the request is sent.
                            barcodeResultView.setText("Modules are already installed when the request is sent.");
                        }
                    })
            .addOnFailureListener(
                    e -> {
                        // Handle failure...
                        barcodeResultView.setText(getErrorMessage(e));
                    });

}
Worldlywise answered 31/8, 2023 at 1:58 Comment(0)
F
2

Despite following the docs, which mention that the ModuleInstallClient API is optinal, I made the exception go away using this API, waiting for the module to be installed.

I didn't receive any exceptions saying the module couldn't be used, because it wasn't installed yet (which I did receive on my first use of the lib), so I still am not sure why this was happening.

If you are facing this, follow this tutorial and only access the barcode scanner after the modules have been downloaded.

PS: This probably won't happen in production, because there the Play Store would install the module during the app's install automatically, as I configured in the Manifest.

Frug answered 21/4, 2023 at 18:32 Comment(1)
This probably won't happen in production, because there the Play Store would install the module during the app's install automatically, as I configured in the Manifest. Unfortunately this does not work (issue: issuetracker.google.com/issues/298066135 ). So each user will firstly end with MlKitException=CODE_SCANNER_UNAVAILABLE and later it will maybe work (maybe because of another issue issuetracker.google.com/issues/261579118 MlKitException=INTERNAL ).Bosh
B
1

I had the same problem. It seems to be some google bug which sometimes happen. In my case google code scanner was working one day but on the next day does not without any code change. I just deleted data of Google Play services app. After that I got error CODE_SCANNER_UNAVAILABLE (Required code scanner module is not available yet) see https://developers.google.com/android/reference/com/google/mlkit/common/MlKitException and this means that just wait a few seconds and try again and google code scanner will work - this is just in local development when app is not installed via play store. In usual case google installs code scanner with app if you have <meta-data android:name="com.google.mlkit.vision.DEPENDENCIES" android:value="barcode_ui" /> in AndroidManifest.xml.

Great to debug is android app in play store https://play.google.com/store/apps/details?id=com.khandev.qrcodescanner which uses google code scanner library. You can test that when you delete play services data and install that app from play store and open it after several second later google code scanner is working so lib was pre-installed with app before first app use.

So implement manual downloading by this doc https://developers.google.com/android/guides/module-install-apis is useless. In local dev after first use you will got CODE_SCANNER_UNAVAILABLE and later it will work whe google downloads it.

UPDATE 1: we do not recommend this lib in prod, very unreliable, we must stop using it immediatelly, it failures on many different devices (Google code scanner "Failed to scan code."). Google has reported bug but did not solve it https://issuetracker.google.com/issues/261579118

UPDATE 2: this lib is really unusable for 4 reasons:

1.) Issue https://issuetracker.google.com/issues/261579118 ignored by Google.

2.) When you get lucky and google code scanner works for you (maybe because you must delete Google Play services data which is not acceptable solution because you will lost payment card and many other google related stuff) it will stop working after several days again: I/System.out: GOOGLE CODE SCANNER: MlKitException: code: 13; constant: INTERNAL; message: Failed to scan code.

3.) Doc ( https://developers.google.com/ml-kit/vision/barcode-scanning/code-scanner#configure_your_app ) says when you add <meta-data android:name="com.google.mlkit.vision.DEPENDENCIES" android:value="barcode_ui" /> into AndroidManifest.xml google play store will install lib within the app. It is not true. I have tested it: installed app from play store, opened app at home screen and wait many minutes (to give google chance to download and install library) but in about 10 minutes later I navigated in app to screen when google code scanner is used and I got error CODE_SCANNER_UNAVAILABLE ( https://developers.google.com/android/reference/com/google/mlkit/common/MlKitException#CODE_SCANNER_UNAVAILABLE ) so google did not prepared it at all! Google starts downloading and installing code scanner now after first use NOT AFTER APP INSTALL as said in doc, so it is not acceptable for user to say to him to wait several seconds or minutes (depending on connection speed) and try again. I do not wish to download it manually using many additional Java/Kotlin lines of code when it should work out of the box by doc.

4.) Google in https://developers.google.com/ml-kit/vision/barcode-scanning/code-scanner approved with a benefit that your app does not need camera permission but does not say important thing that app Google Play services must have this permission. Android does not show standard dialog to grant it just show long text warning that app needs permission and user must grant it manually what could be really difficult for many users because Google Play services app is system app and on some devices (Blackberry and maybe other) is not easy find it and grant permission.

Bosh answered 8/8, 2023 at 13:51 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.