Android Question Suddenly google code scanner (based on ML kit) not working

The ML kit based Google Scanner was working but no longer works. I haven't changed any thing in code. When the 'button' is tapped, brief black screen appears and app goes back to main page. No discernible error is shown. How to rectify it? This is the log: Is it got something to do with 'Transport backend 'cct' is not registered' ? Also what are all those strange com.hunantv.imgo.activity, com.tencent.qqlive, com.qiyi.video, com.hunantv.imgo.activity.inter, com.tencent.qqlivei18n, com.iqiyi.i18n, tv.danmaku.bili] ?
 
Fresh download and running of code too doesn't work. The complete log is below:

 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
com.hunantv.imgo.activity, com.tencent.qqlive, com.qiyi.video, com.hunantv.imgo.activity.inter, com.tencent.qqlivei18n, com.iqiyi.i18n, tv.danmaku.bili
You are seeing the system logs. It includes the output of all apps.

Change the scan method code to:
B4X:
Public Sub Scan (Formats As List) As ResumableSub
    Dim builder As JavaObject
    builder.InitializeNewInstance("com/google/mlkit/vision/codescanner/GmsBarcodeScannerOptions.Builder".Replace("/", "."), Null)
    Dim f(Formats.Size - 1) As Int
    For i = 1 To Formats.Size - 1
        f(i - 1) = Formats.Get(i)
    Next
    builder.RunMethod("setBarcodeFormats", Array(Formats.Get(0), f))
'    builder.RunMethod("enableAutoZoom", Null)
    Dim options As JavaObject = builder.RunMethod("build", Null)
    Dim scanning As JavaObject
    Dim ctxt As JavaObject
    ctxt.InitializeContext
    Dim scanner As JavaObject = scanning.InitializeStatic("com/google/mlkit/vision/codescanner/GmsBarcodeScanning".Replace("/", ".")).RunMethod("getClient", Array(ctxt, options))
    Dim o As JavaObject = scanner.RunMethod("startScan", Null)
    Do While o.RunMethod("isComplete", Null).As(Boolean) = False
        Sleep(50)
    Loop
    Dim res As ScannerResult
    res.Initialize
    If o.RunMethod("isSuccessful", Null) Then
        res.Success = True
        res.Barcode = o.RunMethod("getResult", Null)
        res.Value = res.Barcode.RunMethod("getRawValue", Null)
    Else
        Log("error: " & o.RunMethod("getException", Null))
    End If
    Return res
End Sub

Post the filtered logs.
 
Upvote 0
Thanks for looking into the issue. The filtered Log after changing code:

 
Upvote 0
Upvote 0
If you have another device to test then try it.

Deleting Google Play Services cache might help. Also try to restart the device.
Interestingly, it works in older phone! First time it shows error as it apparently downloads 'Barcode UI module' and then it starts working.
Log:
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
Looks like a bug in the SDK itself. Try to change the package name and see if it starts working.
@Erel, I know that this is an old thread but nevertheless - might be a solution for the problem.

I have had the same problem and have tried everything from uninstalling the app, change the package name, clear the Google Play Services cache, change barcode_ui to barcode in the manifest, restart device, etc but just could not get the scanner to start. Always gave the error "failed to scan code" (...or something like that). I came across some Java code on the web and added it as inline Java code that are called from the Initialize method in the B4A class GoogleCodeScanner. The inline Java code apparently requests GPS for an urgent install of the dependency.

My hack of it is VERY UNTIDY but it did the trick. After days of trying everything else the scanner is now working on first run of the B4A project. Perhaps you can add it to your class via Java Object or fix up my hack of the inline Java Code.

Project attached.

My hack:

Initialize of class GoogleCodeScanner:
Public Sub Initialize
    Dim m As JavaObject
    m = Me
    m.RunMethod("onScanButtonClicked", Null)

My hack of the inline Java Code:

Force an install via inline Java code:
#if Java

BA ba;

import com.google.android.gms.common.moduleinstall.InstallStatusListener;
import com.google.android.gms.common.moduleinstall.ModuleInstallStatusUpdate;
import com.google.android.gms.common.moduleinstall.ModuleInstallClient;
import com.google.android.gms.common.moduleinstall.ModuleInstall;
import com.google.android.gms.common.moduleinstall.ModuleInstallRequest;
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions;
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning;
import com.google.mlkit.vision.codescanner.GmsBarcodeScanner;
import com.google.android.gms.common.api.OptionalModuleApi;

import com.google.android.gms.tasks.Task;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

ModuleInstallClient moduleInstallClient;

public void onScanButtonClicked() {

    GmsBarcodeScannerOptions.Builder optionsBuilder = new GmsBarcodeScannerOptions.Builder();

    moduleInstallClient = ModuleInstall.getClient(ba.applicationContext);

    OptionalModuleApi optionalModuleApi = GmsBarcodeScanning.getClient(ba.applicationContext);
    moduleInstallClient
            .areModulesAvailable(optionalModuleApi);
 
    moduleInstall();
}

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.
            BA.Log("" + 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  true;    //state == STATE_CANCELED || state == STATE_COMPLETED || state == STATE_FAILED;
    }
}

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

    OptionalModuleApi optionalModuleApi = GmsBarcodeScanning.getClient(ba.applicationContext);
    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.
                            BA.Log("Modules are already installed when the request is sent.");
                        }
                    })
            .addOnFailureListener(
                    e -> {
                        // Handle failure...
                        BA.Log("" + e);
                    })*/;

}
#End If
 

Attachments

  • BarcodeScannerModified.zip
    12.7 KB · Views: 117
Last edited:
Upvote 0
I get this error after tapping the button. Could you please figure out why this happens?:
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
As suggested by @Johan Schoeman in PM, I updated to latest b4a and now the fix works with the phone which showed error earlier. Thanks a lot!
An absolutely NASTY HACK by me of some good code but it forced the scanner on my device to start working after days of trying various options. I had it working before and was surprised that it also suddenly stopped working. Will monitor its "availability" over the next few days/weeks to see if it "disappears" again subsequent to it working now again - as what has been reported by numerous developers on the web.
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
I have "fixed" the inline Java code to do away with Lamda expressions and converted it to non-Lamda inline Java Code.
Have also added 2 x Events to the inline java code that will be raised in the B4A class - you can add additional Events everywhere where there are BA.Log(...) in the inline Java code. Eg:

Add Events:
Public Sub gcs_module_installed (installed As String)
 
    Log("Back in B4A : " & installed)

End Sub

public Sub gcs_modules_present_on_device (present As String)
 
    Log("Back in B4A : " & present)
 
End Sub

The GoogleCodeScanner class in the B4A project now looks as follows:

B4A GoogleCodeScanner class:
'version: 1.00
Sub Class_Globals
    Public Const FORMAT_ALL_FORMATS = 0, FORMAT_AZTEC = 4096, FORMAT_CODABAR = 8, FORMAT_CODE_128 = 1, FORMAT_CODE_39 = 2, FORMAT_CODE_93 = 4 As Int
    Public Const FORMAT_DATA_MATRIX = 16, FORMAT_EAN_13 = 32, FORMAT_EAN_8 = 64, FORMAT_ITF = 128, FORMAT_PDF417 = 2048, FORMAT_QR_CODE = 256 As Int
    Public Const FORMAT_UPC_A = 512, FORMAT_UPC_E = 1024 As Int
    Type ScannerResult (Success As Boolean, Value As String, Barcode As JavaObject)
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    Dim m As JavaObject
    m = Me
    Dim eventName As String = "gcs"
    m.RunMethod("checkModuleIntalled", Array(eventName))

End Sub

Public Sub Scan (Formats As List) As ResumableSub
    Dim builder As JavaObject
    builder.InitializeNewInstance("com/google/mlkit/vision/codescanner/GmsBarcodeScannerOptions.Builder".Replace("/", "."), Null)
    Dim f(Formats.Size - 1) As Int
    For i = 1 To Formats.Size - 1
        f(i - 1) = Formats.Get(i)
    Next
    builder.RunMethod("setBarcodeFormats", Array(Formats.Get(0), f))
    builder.RunMethod("enableAutoZoom", Null)
'    builder.RunMethod("allowManualInput", Null)
    Dim options As JavaObject = builder.RunMethod("build", Null)
    Dim scanning As JavaObject
    Dim ctxt As JavaObject
    ctxt.InitializeContext
    Dim scanner As JavaObject = scanning.InitializeStatic("com/google/mlkit/vision/codescanner/GmsBarcodeScanning".Replace("/", ".")).RunMethod("getClient", Array(ctxt, options))
    Dim o As JavaObject = scanner.RunMethod("startScan", Null)
    Do While o.RunMethod("isComplete", Null).As(Boolean) = False
        Sleep(50)
    Loop
    Dim res As ScannerResult
    res.Initialize
    If o.RunMethod("isSuccessful", Null) Then
        res.Success = True
        res.Barcode = o.RunMethod("getResult", Null)
        res.Value = res.Barcode.RunMethod("getRawValue", Null)
    Else
        Log("error: " & o.RunMethod("getException", Null))
    End If
    Return res
End Sub


Public Sub gcs_module_installed (installed As String)
 
    Log("Back in B4A : " & installed)

End Sub

public Sub gcs_modules_present_on_device (present As String)
 
    Log("Back in B4A : " & present)
 
End Sub


#if Java

import com.google.android.gms.common.moduleinstall.InstallStatusListener;
import com.google.android.gms.common.moduleinstall.ModuleInstallStatusUpdate;
import com.google.android.gms.common.moduleinstall.ModuleInstallClient;
import com.google.android.gms.common.moduleinstall.ModuleInstall;
import com.google.android.gms.common.moduleinstall.ModuleInstallRequest;
import com.google.android.gms.common.moduleinstall.ModuleInstallResponse;
import com.google.android.gms.common.moduleinstall.ModuleAvailabilityResponse;
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions;
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning;
import com.google.mlkit.vision.codescanner.GmsBarcodeScanner;
import com.google.android.gms.common.api.OptionalModuleApi;

import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.Events;

import com.google.android.gms.tasks.Task;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

import androidx.annotation.NonNull;

ModuleInstallClient moduleInstallClient;

private BA ba;
private String eventName = "";

//https://stackoverflow.com/questions/76075230/how-to-fix-google-code-scanner-throwing-mlkitexception-failed-to-scan-code
// ORIGINAL

public void checkModuleIntalled(String eventName) {

      this.eventName = eventName;
//    GmsBarcodeScannerOptions.Builder optionsBuilder = new GmsBarcodeScannerOptions.Builder();
//    WE DON'T NEED A MANUAL INPUT
//    if (allowManualInput) {
//        optionsBuilder.allowManualInput();
//   }
//    THIS IS ALREADY COVERED BY @EREL's JavaObject CODE
//    if (enableAutoZoom) {
//        optionsBuilder.enableAutoZoom();
//    }

    ModuleInstallClient moduleInstallClient = ModuleInstall.getClient(ba.applicationContext);

    OptionalModuleApi optionalModuleApi = GmsBarcodeScanning.getClient(ba.applicationContext);
    moduleInstallClient
            .areModulesAvailable(optionalModuleApi)
            .addOnSuccessListener(new OnSuccessListener<ModuleAvailabilityResponse>()  {
                    @Override
                    public void onSuccess(@NonNull ModuleAvailabilityResponse response) {
                       if (response.areModulesAvailable()) {        
                          // Modules are present on the device...
                          //BA.Log("Modules are present on the device");
                         
                          if (ba.subExists(eventName + "_modules_present_on_device")) {
                            ba.raiseEvent2(ba, false, eventName + "_modules_present_on_device", true, new Object[]{"Modules are present on the device"});
                          }                        
                                     
                            //THE BELOW "STARTSCAN()" CODE IS HANDLED BY @EREL's JavaObject Code
                            //GmsBarcodeScanner gmsBarcodeScanner = GmsBarcodeScanning.getClient(ba.applicationContext, 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...
                            BA.Log("Modules are not present on the device");
                            moduleInstall();
                        }
                    }
             })
            .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        BA.Log("ERROR = " + e);
                    }
                });
}

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.
            BA.Log("Progress = " + 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 == ModuleInstallStatusUpdate.InstallState.STATE_CANCELED || state == ModuleInstallStatusUpdate.InstallState.STATE_COMPLETED || state == ModuleInstallStatusUpdate.InstallState.STATE_FAILED;
    }
}

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

    OptionalModuleApi optionalModuleApi = GmsBarcodeScanning.getClient(ba.applicationContext);
    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(new OnSuccessListener<ModuleInstallResponse>() {
                    @Override
                    public void onSuccess(@NonNull ModuleInstallResponse response) {
                        if (response.areModulesAlreadyInstalled()) {
                            // Modules are already installed when the request is sent.
                         
                      if (ba.subExists(eventName + "_module_installed")) {
                        ba.raiseEvent2(ba, false, eventName + "_module_installed", true, new Object[]{"Modules are already installed when the request was sent"});
                      }
                   
                      //BA.Log("Modules are already installed when the request was sent.");
                        } else {
                            // Modules are Not present on the device...
                            BA.Log("Modules are not present on the device");
                            moduleInstall();
                        }
                    }
                })
            .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        BA.Log("ERROR = " + e);
                    }
                });

}

#End If

Sample project is attached - it will force a download of the dependencies as it seems to be unreliable when making it dependent on the Manifest entry only:
Unreliable Manifest entry:
AddApplicationText(
<meta-data
      android:name="com.google.mlkit.vision.DEPENDENCIES"
      android:value="barcode_ui"/>
 

Attachments

  • BarcodeScannerModifiedFixedILJ.zip
    13.7 KB · Views: 125
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…