Android Question Tweaking the Vision Bar Code Reader


Licensed User
Hello, I have a question about the Vision bar code reader, but first - about me.

I spent hundreds upon hundreds of hours in my teenage years coding in BASIC on the Apple //e, and years ago I purchased VB6 when it was current and wrote about 2 programs over the course of 2 months.

So I have some experience, sort of relevant and irrelevant experience and I was able to successfully start writing apps using B4a, this thing works great! So thank you for this product, it is very impressive. I was able to get most things working without asking any questions so sorry for troubling all of you with this simple one.

My question relates to the bar code scanner using Google Vision- beta version which is found on this thread here -

I am able to successfully change the type to data matrix.
CreateDetector (Array("DATA_MATRIX"))

And it works to scan the barcodes that I need

All I want to do is
#1 load a panel with a couple of buttons ("firstpanel" in the attached project)-
#2 one of which will execute the bar code scanner functionality (btnScanCode). When the scanner detects a bar code it #3 adds the code to a list or array and #4 exits the scanning function back to the first panel that was loaded
#5 the user can then hit another button to view the scanned codes.

I am having problems with #1 since the code is set to initialize the bar code reader and if I change it it fails to initialize properly. Also with #4 for some reason I cannot figure out how to exit the scanner when the code is detected. Can anyone give me some help here?

Project attached -relevant code below.
Sub Activity_Create(FirstTime As Boolean)
'Would like to load firstpanel here instead and call the scanning code if btnScanCode is clicked
    CodeList.Initialize 'initialize the list to store the scanned codes
    If FirstTime Then
        CreateDetector (Array("DATA_MATRIX"))
    End If

End Sub

Private Sub CreateDetector (Codes As List)
    Dim ctxt As JavaObject
    Dim builder As JavaObject
    builder.InitializeNewInstance("com/google/android/gms/vision/barcode/BarcodeDetector.Builder".Replace("/", "."), Array(ctxt))
    Dim barcodeClass As String = "com/google/android/gms/vision/barcode/Barcode".Replace("/", ".")
    Dim barcodeStatic As JavaObject
    Dim format As Int
    For Each formatName As String In Codes
        format = Bit.Or(format, barcodeStatic.GetField(formatName))
    builder.RunMethod("setBarcodeFormats", Array(format))
    detector = builder.RunMethod("build", Null)
    Dim operational As Boolean = detector.RunMethod("isOperational", Null)
    Log("Is detector operational: " & operational)
    SearchForBarcodes = operational
End Sub

Sub Camera1_Preview (data() As Byte)
    If SearchForBarcodes Then
        If DateTime.Now > LastPreview + IntervalBetweenPreviewsMs Then
            'Dim n As Long = DateTime.Now
            Dim frameBuilder As JavaObject
            Dim bb As JavaObject
            bb = bb.InitializeStatic("java.nio.ByteBuffer").RunMethod("wrap", Array(data))
            frameBuilder.InitializeNewInstance("com/google/android/gms/vision/Frame.Builder".Replace("/", "."), Null)
            Dim cs As CameraSize = camEx.GetPreviewSize
            frameBuilder.RunMethod("setImageData", Array(bb, cs.Width, cs.Height,  842094169))
            Dim frame As JavaObject = frameBuilder.RunMethod("build", Null)
            Dim SparseArray As JavaObject = detector.RunMethod("detect", Array(frame))
            LastPreview = DateTime.Now
            For i = 0 To SparseArray.RunMethod("size", Null) - 1
                Dim barcode As JavaObject = SparseArray.RunMethod("valueAt", Array(i))
                Dim raw As String = barcode.GetField("rawValue")
                ToastMessageShow("Found: " & raw, True)
                CodeList.Add(raw)  'Need to go back to the firstpanel from here?
                Dim points() As Object = barcode.GetField("cornerPoints")
                Dim tl As JavaObject = points(0)
'                Dim tr As JavaObject = points(1)
                Dim br As JavaObject = points(2)
'                Dim bl As JavaObject = points(3)
                Dim r As B4XRect
                r.Initialize(tl.GetField("x"), tl.GetField("y"), br.GetField("x"), br.GetField("y"))
                cvs.DrawRect(r, Colors.Red, False, 5dip)
            'Log(DateTime.Now - n)
        End If
    End If
End Sub


  • Camera
    14.5 KB · Views: 232


Licensed User
Hello Erel, thank you.

I have done setting up the camera code as another module "Activity2".
Project attached.

I had to comment out some of the compile options at the top in Activity2.
When I try to call this from the mail program I use the latest recommended CallSubDelayed instead of the older StartActivity-

Sub btnScanCode_Click
    CallSubDelayed(Activity2, "Activity_Create")
End Sub

And to return I use

                CallSubDelayed(Activity, "Activity_Resume")

This does not work, there is a run time error

--------- beginning of system
Is detector operational: true
** Activity (activity2) Resume **
facing: 0, 0
An error occurred:
(Line: 121) End Sub
java.lang.Exception: Sub activity_create signature does not match expected signature.
public static anywheresoftware.b4a.pc.RemoteObject throws java.lang.Exception

No parameters

But when I change to StartActivity

It seems to work.

I think I am making a mistake in the call to CallSubDelayed? What do you think?


  • Camera
    15.3 KB · Views: 222
Upvote 0


Licensed User
Longtime User
You should not start activity_create manually.
Create another sub to call.

Additionally activity_create did expect to get one parameter but you are not giving any parameters.
Use CallSubDelayed2 to give a parameter
Upvote 0