B4A Library [class] Google Code Scanner - no permission, very simple to use, barcode scanning

This solution is based on ML Kit (https://developers.google.com/ml-kit/vision/barcode-scanning/code-scanner).

Instructions:
1. Add to main module:
B4X:
#AdditionalJar: com.google.android.gms:play-services-code-scanner
#MultiDex: True
2. Add to manifest editor:
B4X:
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase) 'add if not already there

'******* google code scanner
AddApplicationText(
<meta-data
      android:name="com.google.mlkit.vision.DEPENDENCIES"
      android:value="barcode_ui"/>
 <activity
            android:name="com.google.mlkit.vision.codescanner.internal.GmsBarcodeScanningDelegateActivity"
            android:exported="false"
            android:screenOrientation="portrait"
           >
  </activity>
)
'*****************

'*********  ML kit **********
AddApplicationText(
 <activity
            android:name="com.google.mlkit.vision.documentscanner.internal.GmsDocumentScanningDelegateActivity"
            android:exported="false"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
             >
        </activity>
         <provider
            android:name="com.google.mlkit.common.internal.MlKitInitProvider"
            android:authorities="${applicationId}.mlkitinitprovider"
            android:exported="false"
            android:initOrder="99" />

        <service
            android:name="com.google.mlkit.common.internal.MlKitComponentDiscoveryService"
            android:directBootAware="true"
            android:exported="false"
             >
            <meta-data
                android:name="com.google.firebase.components:com.google.mlkit.common.internal.CommonComponentRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
        </service>
)
'******************************

Usage:
B4X:
Private Sub Button1_Click
    Dim formats As List = Array(Scanner.FORMAT_ALL_FORMATS) 'For better performance pass the specific formats needed.
    Wait For (Scanner.Scan(formats)) Complete (Result As ScannerResult)
    If Result.Success Then
        Log(Result.Value)
    End If
End Sub

See attached project.
 

Attachments

  • GoogleCodeScanner.zip
    15.4 KB · Views: 293
Last edited:

drgottjr

Expert
Licensed User
Longtime User
mea culpa
 

Ryan Pigeon

Member
This solution is based on ML Kit (https://developers.google.com/ml-kit/vision/barcode-scanning/code-scanner).

Instructions:
1. Add to main module:
B4X:
#AdditionalJar: com.google.android.gms:play-services-code-scanner
#MultiDex: True
2. Add to manifest editor:
B4X:
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase) 'add if not already there

'******* google code scanner
AddApplicationText(
<meta-data
      android:name="com.google.mlkit.vision.DEPENDENCIES"
      android:value="barcode_ui"/>
 <activity
            android:name="com.google.mlkit.vision.codescanner.internal.GmsBarcodeScanningDelegateActivity"
            android:exported="false"
            android:screenOrientation="portrait"
           >
  </activity>
)
'*****************

'*********  ML kit **********
AddApplicationText(
 <activity
            android:name="com.google.mlkit.vision.documentscanner.internal.GmsDocumentScanningDelegateActivity"
            android:exported="false"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
             >
        </activity>
         <provider
            android:name="com.google.mlkit.common.internal.MlKitInitProvider"
            android:authorities="${applicationId}.mlkitinitprovider"
            android:exported="false"
            android:initOrder="99" />

        <service
            android:name="com.google.mlkit.common.internal.MlKitComponentDiscoveryService"
            android:directBootAware="true"
            android:exported="false"
             >
            <meta-data
                android:name="com.google.firebase.components:com.google.mlkit.common.internal.CommonComponentRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
        </service>
)
'******************************

Usage:
B4X:
Private Sub Button1_Click
    Dim formats As List = Array(Scanner.FORMAT_ALL_FORMATS) 'For better performance pass the specific formats needed.
    Wait For (Scanner.Scan(formats)) Complete (Result As ScannerResult)
    If Result.Success Then
        Log(Result.Value)
    End If
End Sub

See attached project.
Error:

** Activity (main) Pause event (activity is not paused). **
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/arch/core/executor/ArchTaskExecutor;
at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.java:322)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:178)
at androidx.activity.ComponentActivity.<init>(ComponentActivity.java:277)
at com.google.mlkit.vision.codescanner.internal.GmsBarcodeScanningDelegateActivity.<init>(com.google.android.gms:play-services-code-scanner@@16.1.0:1)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
at android.app.Instrumentation.newActivity(Instrumentation.java:1378)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4042)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4330)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2693)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:9063)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.ClassNotFoundException: androidx.arch.core.executor.ArchTaskExecutor
... 20 more
 
HI, I have to ask for your help. Your code runs perfectly fine on my side without any errors. However, I don't know why, after triggering Private Sub Button1_Click, the o.RunMethod("isSuccessful", Null) in Scan() always returns False, and the camera does not pop up to scan. Did I do something wrong? Please help me. Thank you very much.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Change the scan 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("task failed")
        Log(o.RunMethod("getException", Null))
    End If
    Return res
End Sub

What do you see in the logs?
 
HI, I have to ask for your help. Your code runs perfectly fine on my side without any errors. However, I don't know why, after triggering Private Sub Button1_Click, the o.RunMethod("isSuccessful", Null) in Scan() always returns False, and the camera does not pop up to scan. Did I do something wrong? Please help me. Thank you very much.
check out modified code by @Johan Schoeman in post #13 in the following thread https://www.b4x.com/android/forum/t...e-scanner-based-on-ml-kit-not-working.161137/
 
HI, thanks for your attention. After switching to your code, the log content is as follows:

--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
** Activity (main) Resume **
task failed
com.google.mlkit.common.MlKitException: Code scanner module is not supported on current Google Play Services version, please upgrade.
task failed
com.google.mlkit.common.MlKitException: Code scanner module is not supported on current Google Play Services version, please upgrade.
task failed
com.google.mlkit.common.MlKitException: Code scanner module is not supported on current Google Play Services version, please upgrade.
Change the scan 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("task failed")
        Log(o.RunMethod("getException", Null))
    End If
    Return res
End Sub

What do you see in the logs?
 
HI, thanks for your attention. The method you mentioned resulted in an error during the Initialize() event of the GoogleCodeScanner module at the statement m.RunMethod("checkModuleInstalled", Array(eventName)). The error message is as follows:

ERROR = com.google.android.gms.common.api.ApiException: 17: API: ModuleInstall.API is not available on this device. Connection failed with: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null} Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.

After this, the program continued and eventually encountered the following error on line 107 of GoogleCodeScanner:


Error occurred on line: 107 (GoogleCodeScanner) java.lang.NullPointerException: null receiver at java.lang.reflect.Field.get(Native Method) at anywheresoftware.b4j.object.JavaObject.InitializeContext(JavaObject.java:57) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:777) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:354) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262) at b4a.example.googlecodescanner._scan(googlecodescanner.java:113) at b4a.example.b4xmainpage$ResumableSub_Button1_Click.resume(b4xmainpage.java:97) at b4a.example.b4xmainpage._button1_click(b4xmainpage.java:66) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732) at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351) at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255) at java.lang.reflect.Method.invoke(Native Method) at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157) at anywheresoftware.b4a.BA.raiseEvent(BA.java:201) at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80) at android.view.View.performClick(View.java:7738) at android.view.View.performClickInternal(View.java:7712) at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0) at android.view.View$PerformClick.run(View.java:30495) at android.os.Handler.handleCallback(Handler.java:971) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loopOnce(Looper.java:206) at android.os.Looper.loop(Looper.java:296) at android.app.ActivityThread.main(ActivityThread.java:9205) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:591) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1027)
 
Top