B4A Library Android Vision Barcode Scanner (Scan QR Codes and other 1D & 2D barcodes)

Johan Schoeman

Expert
Licensed User
It seems to be BARCODE season....This is a (partial) wrap for this Github project. It also uses the Google Mobile Vision API to scan the codes. It also incorporates the Tracking functionality (I have not quite figured out what color "outlined" barcode is actually the one that will be returned to B4A when it is tapped/touched).

Posting the following:
1. B4A project - best to use it in the two activities as per the attached B4A sample project. (b4aAndroidVisionMaster.zip
2. The B4A library files (b4aAndroidVisionMasterLibFiles.zip)
3. The java code as it stands at present (TheJavaCode.zip)
4. A link to all the other jars that will be required - download them from here and copy them to your additional library folder - https://www.dropbox.com/s/se5x5znl1tgpv6r/OtherLibFiles.zip?dl=0
5. resourceInAddLibFolder.zip - extract it and copy the resource folder to your additional library folder
6. resource.zip - extract it and copy the resource folder to the same folder level that of the /Files and /Objects folders of the B4A project.

Touch/tap a highlighted barcode when the scanner is active to return the barcode format and content/value to the B4A project.

Please note: This is by no means perfect and I therefore leave you with the Java Code to change it to whatever might suite you - but it is working as it is at present.

You can also try the Google Mobile Vision Face Detector that I have posted HERE

You can download and test any posting of mine in this thread but if you want to use it then you need to

Sample Code (Main Activity):
B4X:
#Region  Project Attributes
    #ApplicationLabel: AndroidVisionMaster
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#AdditionalRes: ..\resource

#AdditionalRes: C:\Users\----------2\Documents\Basic 4 Android\JOHAN APPS\JHS LIBS\resource\b4a_appcompat, de.amberhome.objects.appcompat
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\android\support\v7\appcompat\res, android.support.v7.appcompat
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\android\support\design\res, android.support.design

#ExcludeClasses: .games, .drive, .ads, .fitness, .wearable, .measurement, .cast, .auth, .nearby
#ExcludeClasses: .tagmanager, .analytics, .wallet, .plus, .gcm, .maps, .panorama

#Extends: android.support.v7.app.AppCompatActivity


#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private Button1 As Button

    Private Label1 As Label
    Private Label2 As Label
    Private Label4 As Label
    Private Label3 As Label
    Dim settings(2) As Boolean

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:

    Activity.LoadLayout("main")
    Label1.Text = ""
    Label2.Text = ""
    Label3.Text = "Flash Disabled"
    Label4.Text = "Auto Focus Enabled"
    settings(0) = False
    settings(1) = True

End Sub

Sub Activity_Resume



End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub Button1_Click

  CallSubDelayed2(Main_Scanner, "StartScan", settings)

End Sub

Sub GetResult(retval() As String)

    Log("back in main : format = " & retval(0))
    Log("back in main : data = " & retval(1))

    Label1.Text = "Barcode Format : " & retval(0)
    Label2.Text = "Barcode Data : " & retval(1)

End Sub

Sub Label3_Click

    If Label3.Text = "Flash Disabled" Then
      Label3.Text = "Flash Enabled"
      Label3.Color = Colors.Red
      settings(0) = True
    Else
        Label3.Color = 0xff008000
        Label3.Text = "Flash Disabled"
        settings(0) = False
    End If

End Sub

Sub Label4_Click

    If Label4.Text = "Auto Focus Disabled" Then
      Label4.Text = "Auto Focus Enabled"
      Label4.Color = Colors.Red
      settings(1) = True
    Else
        Label4.Color = 0xff008000
        Label4.Text = "Auto Focus Disabled"
        settings(1) = False
    End If


End Sub
Sample code (Main_Scanner Activity):
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

        Dim myscan As AndroidVisionMaster

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("main2")
    myscan.Initialize("scanner")




End Sub

Sub Activity_Resume



End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub StartScan(settings() As Boolean)

    If settings(0) = True Then myscan.FlashOn = True
    If settings(0) = False Then myscan.FlashOn = False

    If settings(1) = True Then myscan.AutoFocus = True
    If settings(1) = False Then myscan.AutoFocus = False

    myscan.beginScan



End Sub

Sub ToggleFlash_Click


End Sub

Sub scanner_scan_result(data As String, format As Int)


    Dim fmt As String = ""
    Select format
        Case 0
            fmt = "ALL_FORMATS"
        Case 1
            fmt = "CODE_128"
        Case 2
            fmt = " CODE_39"
        Case 4
            fmt = "CODE_93"
        Case 8
            fmt = "CODABAR"
        Case 16
            fmt = "DATA_MATRIX"
        Case 32
            fmt = "EAN_13"
        Case 64
            fmt = "EAN_8"
        Case 128
            fmt = "ITF"
        Case 256
            fmt = "QR_CODE"
        Case 512
            fmt = "UPC_A"
        Case 1024
            fmt = "UPC_E"
        Case 2048
            fmt = "= PDF417"
        Case 4096
            fmt = "AZTEC"
          
    End Select

    Dim retval(2) As String
    retval(0) = fmt
    retval(1) = data

    CallSubDelayed2(Main, "GetResult", retval)

    Log("Format : " & fmt)
    Log("Data : " & data)

    Activity.Finish

End Sub
Important: Take note of all the files in the B4A project's /Objects/res/blabla folders. Make sure they are set to READ ONLY before you compile the project for the first time

Also important to note the B4A project's Manifest Files

And equally important to set your paths correctly (the below only applicable to my folder setup):
B4X:
#End Region

#AdditionalRes: ..\resource

#AdditionalRes: C:\Users\----------2\Documents\Basic 4 Android\JOHAN APPS\JHS LIBS\resource\b4a_appcompat, de.amberhome.objects.appcompat
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\android\support\v7\appcompat\res, android.support.v7.appcompat
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\android\support\design\res, android.support.design

#ExcludeClasses: .games, .drive, .ads, .fitness, .wearable, .measurement, .cast, .auth, .nearby
#ExcludeClasses: .tagmanager, .analytics, .wallet, .plus, .gcm, .maps, .panorama

#Extends: android.support.v7.app.AppCompatActivity

#Region  Activity Attributes
Library as it stands at present:

AndroidVisionMaster
Author:
Github: Clayton Wilkinson, Wrapped by: Johan Schoeman
Version: 1
  • AndroidVisionMaster
    Events:
    • scan_result (data As String, format As Int)
    Methods:
    • BeginScan
    • Initialize (paramString As String)
    • IsInitialized As Boolean
    • onClick (v As View)
      Called when a view has been clicked.
      v: The view that was clicked.
    Permissions:
    • android.hardware.camera
    • android.hardware.camera.autofocus
    • android.permission.CAMERA
    • android.permission.FLASHLIGHT
    • android.permission.VIBRATE
    • android.permission.WRITE_EXTERNAL_STORAGE
    Properties:
    • AutoFocus As Boolean [write only]
    • FlashOn As Boolean [write only]




B4A PROJECT STARTED
start.png


ENABLE THE FLASH LIGHT WHEN THE SCANNER BECOMES ACTIVE
Flash Enabled.png



FLASH AND AUTO FOCUS ENABLED WHEN THE SCANNER BECOMES ACTIVE
flash and autofocus enabled.png



SCANNER STARTED AND MULTI TRACKING OCCURRING
multitracking.png



AFTER A HIGHLIGHTED BARCODE HAS BEEN TOUCHED/TAPPED
hightlighted barcode tapped touched.png


Will help with the B4A setup but any further changes to the library will be up to you....
 

Attachments

Last edited:

Johan Schoeman

Expert
Licensed User
Attached is new B4A library files that will allow you to set the text size as well as the border width of the tracker. The attached B4A project will hopefully also sort out the "two activities" coordination. Read and follow post #1 for the basic setup but use the attached B4A project and attached (new) B4A library files.

Main Activity:
B4X:
#Region  Project Attributes
    #ApplicationLabel: AndroidVisionMaster
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#AdditionalRes: ..\resource

#AdditionalRes: C:\Users\----------2\Documents\Basic 4 Android\JOHAN APPS\JHS LIBS\resource\b4a_appcompat, de.amberhome.objects.appcompat
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\android\support\v7\appcompat\res, android.support.v7.appcompat
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
#AdditionalRes: C:\ANDRIOD_SDK_TOOLS\extras\android\support\design\res, android.support.design

#ExcludeClasses: .games, .drive, .ads, .fitness, .wearable, .measurement, .cast, .auth, .nearby
#ExcludeClasses: .tagmanager, .analytics, .wallet, .plus, .gcm, .maps, .panorama

#Extends: android.support.v7.app.AppCompatActivity


#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
   
    Dim nativeMe As JavaObject
    Dim HasAnyActivityPaused As Boolean = False

   
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private Button1 As Button
   
    Private Label1 As Label
    Private Label2 As Label
    Private Label4 As Label
    Private Label3 As Label   
    Dim settings(2) As Boolean
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
   
    Activity.LoadLayout("main")
    Label1.Text = ""
    Label2.Text = ""
    Label3.Text = "Flash Disabled"
    Label4.Text = "Auto Focus Enabled"
   
    nativeMe.InitializeContext
    Log("ID of Front Facing Camera = " & nativeMe.RunMethod("getFrontFacingCamera", Null))
    Log("ID of Back Facing Camera = " & nativeMe.RunMethod("getBackFacingCamera", Null))
    Log("Device has a flash = " & nativeMe.RunMethod("hasFlash", Null))
   
    If nativeMe.RunMethod("hasFlash", Null) = False Then
        Label3.Visible = False                                'hide the label to select the flash with
    End If
   
    settings(0) = False                                       'do not switch on the Torch when the scanner starts
    settings(1) = True                                        'use Auto Focus once the scanner started
   
End Sub

Sub Activity_Resume
   
    HasAnyActivityPaused = False
   
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Button1_Click
   
  CallSubDelayed2(Main_Scanner, "StartScan", settings)

End Sub

Sub GetResult(retval() As String)                             'This is called by activity Main_Scanner (with the result of the scan)
   
    HasAnyActivityPaused = False

    Log("back in main : format = " & retval(0))
    Log("back in main : data = " & retval(1))
   
    Label1.Text = "Barcode Format : " & retval(0)
    Label2.Text = "Barcode Data : " & retval(1)
   
End Sub

Sub Label3_Click
   
    If Label3.Text = "Flash Disabled" Then
      Label3.Text = "Flash Enabled"
      Label3.Color = Colors.Red
      settings(0) = True
    Else
        Label3.Color = 0xff008000 
        Label3.Text = "Flash Disabled"
        settings(0) = False
    End If 
   
End Sub

Sub Label4_Click

    If Label4.Text = "Auto Focus Disabled" Then
      Label4.Text = "Auto Focus Enabled"
      Label4.Color = Colors.Red
      settings(1) = True
    Else
        Label4.Color = 0xff008000
        Label4.Text = "Auto Focus Disabled"
        settings(1) = False
    End If     
   
End Sub

#If Java

import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.CameraInfo;
import android.content.pm.PackageManager;
import android.content.Context;


    public int CAMERA_FRONT = -1;
    public int CAMERA_BACK = -1;   
    private boolean hasflash = false;

    public int getFrontFacingCamera() {
        int cameraId = -1;
        // Search for the front facing camera
        // get the number of cameras       
        int numberOfCameras = Camera.getNumberOfCameras();
        // for every camera check       
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                cameraId = i;
                break;
            }
        }
        CAMERA_FRONT = cameraId;
        return cameraId;
    }

    /**
     * Get the ID of the back facing camera
     * If the device has a front and back camera then the ID = 0
     * If the device has a back facing camera only then the ID = 0
     * It will return the ID as -1 if there is no back facing camera
     */
    public int getBackFacingCamera() {
        int cameraId = -1;
        // Search for the back facing camera
        // get the number of cameras
        int numberOfCameras = Camera.getNumberOfCameras();
        // for every camera check
        for (int i = 0; i < numberOfCameras; i++) {
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
                cameraId = i;
                break;
            }
        }
        CAMERA_BACK = cameraId;
        return cameraId;
    }   
   
    public boolean hasFlash() {
        /*
         * First check if device is supporting a flashlight or not
         */
        hasflash = BA.applicationContext.getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
        
         return hasflash;
    }   

#End If
Main_Scanner activity:
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.


End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
   
        Dim myscan As AndroidVisionMaster
       

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:

        If Main.HasAnyActivityPaused = False Then
           Activity.LoadLayout("main2")
       
          myscan.Initialize("scanner")
       
          myscan.TrackingColors = Array As Int(Colors.Yellow, Colors.Red, Colors.White)    'specify only 3 colors for the barcode tracking frames
          myscan.OverlayBorderWidth = 2.0                                                  'the width of the tracking frames
          myscan.OverlayTextSize = 17                                                      'the text size of the barcode tracking
        Else
            Activity.Finish 
        End If
   
End Sub

Sub Activity_Resume
   
   
End Sub

Sub Activity_Pause (UserClosed As Boolean)
   
Main.HasAnyActivityPaused = True


End Sub

Sub StartScan(settings() As Boolean)
   
    If settings(0) = True Then myscan.FlashOn = True
    If settings(0) = False Then myscan.FlashOn = False
   
    If settings(1) = True Then myscan.AutoFocus = True
    If settings(1) = False Then myscan.AutoFocus = False   
   
    myscan.beginScan

End Sub

Sub scanner_scan_result(data As String, format As Int)             'this event is raised by the library when a scan occured
                                                                   'it returns the barcode type (as an Int) and barcode content (as a String)
    Dim fmt As String = ""
    Select format
        Case 0                                                     'use the value of "format" to determine the type of barcode scannned
            fmt = "ALL_FORMATS"
        Case 1
            fmt = "CODE_128"
        Case 2
            fmt = " CODE_39"
        Case 4
            fmt = "CODE_93"
        Case 8
            fmt = "CODABAR"
        Case 16
            fmt = "DATA_MATRIX"
        Case 32
            fmt = "EAN_13"
        Case 64
            fmt = "EAN_8"
        Case 128
            fmt = "ITF"
        Case 256
            fmt = "QR_CODE"
        Case 512
            fmt = "UPC_A"
        Case 1024
            fmt = "UPC_E"
        Case 2048
            fmt = "= PDF417"
        Case 4096
            fmt = "AZTEC"
               
    End Select
   
    Dim retval(2) As String
    retval(0) = fmt
    retval(1) = data

    CallSubDelayed2(Main, "GetResult", retval)                'pass the scanned result back to the Main activity.

    Log("Format : " & fmt)
    Log("Data : " & data)
   
    Activity.Finish                                           'kill this activity so that the Main activity is displayed

End Sub
 

Attachments

Johan Schoeman

Expert
Licensed User
hi @Johan Schoeman
i tested you lib and i cant make work the auto focus on Samsung Galaxy J2

Another way to make auto focus works?

I have no error with your another libs like this
https://www.b4x.com/android/forum/t...er-that-is-100-embedded-in-b4a.63794/#content
Try with the attached B4A library files - not sure if it will solve the problem as I don't have a similar device to test it with. I have changed the default focus mode in the attached library files.
 

Attachments

Last edited:

Johan Schoeman

Expert
Licensed User

Johan Schoeman

Expert
Licensed User
DONARÍA pero no logro hacerlo funcionar....
Read post #1 carefully - there are some paths in the B4A project that you need to set to match your own setup on your PC/laptop. There is also a link to the other jar files that you require. It should work....
 

dfrutos

Member
Licensed User
Hello:

I have this problem :

"ERROR: resource directory 'C:\Program Files (x86)\Anywhere Software\Basic4android\Libraries\extras\google\google_play_services\libproject\b4a_appcompat' does not exist"

Where is the b4a_appcompat library?
 

Micholl

Member
Licensed User
Hello Johan,
is it possible to acquire a list of currently recognised barcodes with their type and payload?

Thank you,

Micholl
 

Johan Schoeman

Expert
Licensed User
Hello Johan,
is it possible to acquire a list of currently recognised barcodes with their type and payload?

Thank you,

Micholl
Almost 2 years since I have done this. Will have to revisit it. Will see if I can get to it sometime soon.
 

Micholl

Member
Licensed User
Johan, I know, thank you very much for your help!
I think you are the "Barcode-Master" :) . I'm not able to build a new library from scratch
and I have simply not found a alternative working solution for this in B4A :-(.
 

Johan Schoeman

Expert
Licensed User
Johan, I know, thank you very much for your help!
I think you are the "Barcode-Master" :) . I'm not able to build a new library from scratch
and I have simply not found a alternative working solution for this in B4A :-(.
I have posted a project yesterday (in this thread) but have deleted it again. I have done the initial testing on a KitKat device and it worked 100% but subsequent to posting it I tested it on a Android 7 device and for some reason it does not want to connect to the camera and therefore I have deleted the posting. So, need revisit it to try and figure out what is the issue when trying to connect to the camera on Android 7 devices.

The APK is here if you want to test it - as said, it wotks on KitKat but not on Android 7.0

https://drive.google.com/open?id=1JBGFBmivJExwInG5TjgfCiFhI-2JQ-nt
 

Micholl

Member
Licensed User
Hello Johan,

first of all thank you for your effort and support :) helping me.

The APK is here if you want to test it - as said, it wotks on KitKat but not on Android 7.0
I can confirm that the app is running on my Meizu m3 note, which is Android 5.1, but not on my Mi Mix 2,
what is Android 7.1.1. There I get direct at startup the error "java.lang.RuntimeException: Fail to connect to camera service".

In detail:
B4X:
java.lang.RuntimeException: Fail to connect to camera service
    at android.hardware.Camera.<init>(Camera.java:579)
    at android.hardware.Camera.open(Camera.java:404)
    at com.google.android.gms.samples.vision.barcodereader.ui.camera.CameraSource.createCamera(CameraSource.java:764)
    at com.google.android.gms.samples.vision.barcodereader.ui.camera.CameraSource.start(CameraSource.java:378)
    at com.google.android.gms.samples.vision.barcodereader.ui.camera.CameraSourcePreview.startIfReady(CameraSourcePreview.java:92)
    at com.google.android.gms.samples.vision.barcodereader.ui.camera.CameraSourcePreview.access$200(CameraSourcePreview.java:33)
    at com.google.android.gms.samples.vision.barcodereader.ui.camera.CameraSourcePreview$SurfaceCallback.surfaceCreated(CameraSourcePreview.java:115)
    at android.view.SurfaceView.updateWindow(SurfaceView.java:634)
    at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:162)
    at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2266)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1315)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6430)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:876)
    at android.view.Choreographer.doCallbacks(Choreographer.java:688)
    at android.view.Choreographer.doFrame(Choreographer.java:623)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:862)
    at android.os.Handler.handleCallback(Handler.java:754)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:163)
    at android.app.ActivityThread.main(ActivityThread.java:6365)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:791)
I'm not sure that it runs correctly (or as it is supposed to work) on my Meizu m3 note.
On start From xml and pause are checked and the barcode recognition is not working.
When I activate e.g. rect, multiple, draw text, uncheck From xml I have to switch
front cam - press Refresh - back to rear cam - press Refresh - to activate the barcode
recognition. I seem to have to change the camera, otherwise it will not work.

Can I see in the app which barcodes are currently recognised as a list?

It would be great if you could find a solution and we can get this working.

:D Micholl
 

Micholl

Member
Licensed User
Hello Johan,
did you have the time to look at the matter again?
I would be really grateful if you could find a solution.
Thank you!

:( Micholl
 

Micholl

Member
Licensed User
Thank you, Erel :). I haven't noticed that before.
Will test the library / example and see.
 

Micholl

Member
Licensed User
I have tested your suggestion. Very good, but unfortunately :( an important point is missing.
During the scanning process in the camera preview it is necessary to have the recognised
barcodes marked - otherwise you have no optical control which barcodes are fetched.
I had already feared that.
Is there a way to identify / markup recognised barcodes in the preview?

Thank you.
 
Top