B4A Library 1D and 2D Barcode Scanner with ZXING - another Barcode Scanner that is 100% embedded in B4A

The attached project wraps the ZXING part of this Github project. I have not tested all the barcode formats but it should scan the following types:

BarcodeFormat.UPC_A
BarcodeFormat.UPC_E
BarcodeFormat.EAN_13
BarcodeFormat.EAN_8
BarcodeFormat.RSS_14
BarcodeFormat.CODE_39
BarcodeFormat.CODE_93
BarcodeFormat.CODE_128
BarcodeFormat.ITF
BarcodeFormat.CODABAR
BarcodeFormat.QR_CODE
BarcodeFormat.DATA_MATRIX
BarcodeFormat.PDF_417

Please take note of the xml files in the /Objects/res/layout and Objects/res/values folders of the B4A project should you start a new project from scratch.

Posting the following:
1. B4A project demonstrating the Barcode Scanner
2. B4A library files - copy them to your additional library folder
3. You also need android-support.v4.jar and core-3.2.1.jar to be in your additional library folder. I have zipped them together and you can download them from this link:
https://www.dropbox.com/s/h9ts6cjfoo5et6h/core-3.2.1.zip?dl=0

You can use it in portrait mode and landscape mode by changing the B4A project's attribute and the code in the Designer:
#SupportedOrientations: portrait

B4X:
zx1.Left = 2%x
zx1.Top = 5%y
zx1.Width = 96%x
zx1.Height = 80%y

b1.Left = 2%x
b1.Top = zx1.Bottom + 2%y
b1.Width = 15%x
b1.Height = 10%y

b2.Left = 45%x
b2.Top = zx1.Bottom + 2%y
b2.Width = 15%x
b2.Height = 10%y

b3.Left = 83%x
b3.Top = zx1.Bottom + 2%y
b3.Width = 15%x
b3.Height = 10%y

1.png



2.png

Sample code:
B4X:
#Region  Project Attributes
    #ApplicationLabel: ZxingBarcodeScanner
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#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 zx1 As ZxingBarcodeScanner
    Private b1 As Button
    Private b2 As Button
    Private b3 As Button
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")

    zx1.LaserColor = Colors.Yellow
    zx1.MaskColor = Colors.ARGB(150, 0, 0, 200)
    zx1.BorderColor = Colors.Magenta
    zx1.BorderStrokeWidth = 5
    zx1.BorderLineLength = 40
    zx1.Visible = False

End Sub

Sub Activity_Resume


End Sub

Sub Activity_Pause (UserClosed As Boolean)
    zx1.Visible = False
    zx1.stopScanner

End Sub


Sub b1_Click

    zx1.toggleFlash

End Sub

Sub b2_Click

    zx1.Visible = True
    zx1.startScanner

End Sub

Sub b3_Click

    zx1.Visible = False
    zx1.stopScanner

End Sub

Sub zx1_scan_result (scantext As String, scanformat As String)

    Log ("B4A scan text = " & scantext)
    Log ("B4A scan format = " & scanformat)


End Sub

The library:

ZxingBarcodeScanner
Author:
Github: Dushyanth Maguluru, Wrapped by: Johan Schoeman
Version: 1
ZxingBarcodeScanner
Events:

  • scan_result (scantext As String, scanformat As String)
Fields:
  • ba As BA
Methods:
  • BringToFront
  • DesignerCreateView (base As PanelWrapper, lw As LabelWrapper, props As Map)
  • Initialize (EventName As String)
  • Invalidate
  • Invalidate2 (arg0 As Rect)
  • Invalidate3 (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
  • IsInitialized As Boolean
  • RemoveView
  • RequestFocus As Boolean
  • SendToBack
  • SetBackgroundImage (arg0 As Bitmap)
  • SetColorAnimated (arg0 As Int, arg1 As Int, arg2 As Int)
  • SetLayout (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int)
  • SetLayoutAnimated (arg0 As Int, arg1 As Int, arg2 As Int, arg3 As Int, arg4 As Int)
  • SetVisibleAnimated (arg0 As Int, arg1 As Boolean)
  • handleResult (rawResult As Result)
  • startScanner
  • stopScanner
  • toggleFlash
Permissions:
  • android.permission.CAMERA
  • android.permission.FLASHLIGHT
Properties:
  • Background As Drawable
  • BorderColor As Int [write only]
  • BorderLineLength As Int [write only]
  • BorderStrokeWidth As Int [write only]
  • Color As Int [write only]
  • Enabled As Boolean
  • Height As Int
  • LaserColor As Int [write only]
  • Left As Int
  • MaskColor As Int [write only]
  • Tag As Object
  • Top As Int
  • Visible As Boolean
  • Width As Int
You can download and test any posting of mine in this thread but if you want to use it then you need to
 

Attachments

  • ZxingBarcodeScannerLibFiles.zip
    22.5 KB · Views: 2,576
  • b4aZxingBarcodeScanner.zip
    9.9 KB · Views: 2,445
Last edited:

Johan Schoeman

Expert
Licensed User
Longtime User

figorra

Member
Licensed User
Longtime User
@JackKirk

Hi!!!

I have a code, that need sugestion.

When I read de barcode, the code read and read 2 or 3 times in 1 second.

I have a code with vibration, then I read send a vibration, I see the code pass 2 or 3 times before left focus de barcode for vibration sens.

Can we have any parameter to set how many time need to pass generate the next read?

Best regards

THX
 

DonManfred

Expert
Licensed User
Longtime User
The library jar does not contain a 64 bit native .so file. If you want to upload a app to google playstore and google is telling you that it is not 64 bit compliant.

Solution:
1. replace the library jar with the one from this archive
https://www.dropbox.com/s/3ucz6un8ix1hv9b/ZbarBarcodeScannerLibFiles.zip?dl=0
2. Try again. Make sure to reload the librarytab....

You now should be able to send your app to google play; the file here is 64 bit compliant.
 

Situ LLC

Active Member
Licensed User
Johan,

Excellent library, thank you very much for your post, two questions I want to know if you can.

1- how can I activate the sound property in the zx1_scan_result event.
2- how can I edit the wrapper in android studio.

Best regards
 

Johan Schoeman

Expert
Licensed User
Longtime User
Johan,

Excellent library, thank you very much for your post, two questions I want to know if you can.

1- how can I activate the sound property in the zx1_scan_result event.
2- how can I edit the wrapper in android studio.

Best regards
Hi

(2) - no idea. I don't use Android Studio. I do all editing with Notepad++ and compile it with Simple Library Compiler (SLC)
(1) - The below code will beep upon a successful scan (using inline Java)

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

#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.
   
    Private nativeMe As JavaObject
    Dim rp As RuntimePermissions

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 zx1 As ZxingBarcodeScanner
    Private b1 As Button
    Private b2 As Button
    Private b3 As Button
   
    Private l1 As Label
   
    Dim flag As Int = 0
    Dim runningavg As Int = 127
   
    Private l2 As Label
    Private l3 As Label
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")
   
    Dim Result As Boolean = True
    If Not(rp.Check(rp.PERMISSION_CAMERA)) Then
        rp.CheckAndRequest(rp.PERMISSION_CAMERA)
        Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    End If
    If Result Then
   
        nativeMe.InitializeContext
       
        l3.Text = ""
        zx1.LaserColor = Colors.Yellow
        zx1.MaskColor = Colors.ARGB(150, 0, 0, 200)
        zx1.BorderColor = Colors.Magenta
        zx1.BorderStrokeWidth = 5
        zx1.BorderLineLength = 40
       
        zx1.AutoFocusInterval = 500
        zx1.AutoFocus = True
        zx1.FocusMode = zx1.FOCUS_MODE_AUTO
       
       
        zx1.Visible = False
       
    Else
        ToastMessageShow("Permission not granted", True)
        Return
    End If

End Sub

Sub Activity_Resume
   

End Sub

Sub Activity_Pause (UserClosed As Boolean)
    zx1.Visible = False
    zx1.stopScanner

End Sub


Sub b1_Click
   
    zx1.toggleFlash
   
End Sub

Sub b2_Click
 
    zx1.Visible = True
    zx1.startScanner
    zx1.TurnFlashOn
    Log(zx1.isFlashOn)
 
End Sub

Sub b3_Click
   
    zx1.Visible = False
    zx1.stopScanner
    l1.Text = ""
    l2.Text = ""
   
End Sub

Sub zx1_scan_result (scantext As String, scanformat As String)
   
    nativeMe.RunMethod("playTone", Null)
    Dim tim As Long = 100
    nativeMe.RunMethod("vibrateOnce", Array(tim))
    Log ("B4A scan text = " & scantext)
    Log ("B4A scan format = " & scanformat)
    Log("isFlashOn = " & zx1.isFlashOn)
    l2.Text = scantext & " (type = " & scanformat & ")"
   
End Sub


Sub zx1_brightness_changed (bright As Int )                        'ADDED 6 MARCH 2016
'    Log("bright = " & bright)                                      'this is the average brightness of the frame that was captured for possible barcode extraction
    flag = flag + 1
    l1.Text = "Brigtness = " & bright
    If flag = 30 Then                                              'I only want to use the average brightness of every 30th frame to calculate a running brigtness average
        flag = 0                                                   'reset the count to zero for the next 30 frames
        If bright < 150 Then                                       'discard excessive high brigness values
            runningavg = (runningavg + bright) / 2
'            Log("runningavg brightness = " & runningavg)
            If runningavg < 70 Then
                If Not(zx1.isFlashOn) Then zx1.TurnFlashOn
            Else if runningavg > 115 Then
                If zx1.isFlashOn Then zx1.TurnFlashOff
            End If  
        End If  
    End If  
    l3.Text = "isFlashOn = " & zx1.isFlashOn
   
End Sub  


#If Java

import android.os.Vibrator;
import android.content.Context;

import android.media.ToneGenerator;
import android.media.AudioManager;

/**
*Vibrate with a given pattern.
*Pass in an array of Longs that are the durations for which to turn on or off the vibrator in milliseconds.
*The first value indicates the number of milliseconds to wait before turning the vibrator on. The next
*value indicates the number of milliseconds for which to keep the vibrator on before turning it off.
*Subsequent values alternate between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
*Parameters:
*pattern ---> an array of longs of times for which to turn the vibrator on or off.
*repeat ---> the index into pattern at which to repeat, or -1 if you don't want to repeat.
*
*You need to add the following to the manifest file of the B4A project:
*AddPermission("android.permission.VIBRATE")
*/
public void vibratePattern(long[] pattern, int repeat) {
   
  Vibrator v = (Vibrator) BA.applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
  if (v.hasVibrator()) {
    v.vibrate(pattern, repeat);
  }
}

/**
*Cancel vibration (in case of method vibratePattern being active)
*You need to add the following to the manifest file of the B4A project:
*AddPermission("android.permission.VIBRATE")
*
*/
public void vibrateCancel(int dummy) {
   
  Vibrator v = (Vibrator) BA.applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
  if (v.hasVibrator()) {
     v.cancel();
  }
}

/**
*Vibrate continuously for the specified number of milliseconds
*You need to add the following to the manifest file of the B4A project:
*AddPermission("android.permission.VIBRATE")
*/
public void vibrateOnce(long duration) {
   
  Vibrator v = (Vibrator) BA.applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
  if (v.hasVibrator()) {
     v.vibrate(duration);
  }
}


import android.media.ToneGenerator;
import android.media.AudioManager;

  public void playTone() {
      final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
      tg.startTone(ToneGenerator.TONE_PROP_BEEP);
  }    

#End If
 

Johan Schoeman

Expert
Licensed User
Longtime User
Hello Johan,

I was comparing the efficiency of reader between barcode reader libs. Apparently the zxing and manateeworks sdk works very well.

But I realized that manateeworks and others good libs use the zoom on preview start camera. Apparently this can make difference for fast reader.

Is there a way to include options to configure the camera preview in this lib? I´d like to do some tests to try improve the reader.

tks,

Leandro
Try with the attached B4A sample project and library files (V1.03)
Use the Z+ and Z- buttons to zoom in/out
My device reports the zoom as going from 0 to 99.

Sample code (see code and new methods added in b4_Click and b5_Click (there is some debugging logs in the library that will log maximum zoom and current zoom values):
B4X:
#Region  Project Attributes
    #ApplicationLabel: ZxingBarcodeScanner
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: landscape
    #CanInstallToExternalStorage: False
#End Region

#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.
    
    Private nativeMe As JavaObject
    Dim rp As RuntimePermissions

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 zx1 As ZxingBarcodeScanner
    Private b1 As Button
    Private b2 As Button
    Private b3 As Button
    
    Private l1 As Label
    
    Dim flag As Int = 0
    Dim runningavg As Int = 127
    
    Private l2 As Label
    Private l3 As Label
    Private b4 As Button
    Private b5 As Button
    
    Dim scanStarted As Boolean = False
    
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")

    Dim Result As Boolean = True
    If Not(rp.Check(rp.PERMISSION_CAMERA)) Then
        rp.CheckAndRequest(rp.PERMISSION_CAMERA)
        Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    End If
    If Result Then
    
        nativeMe.InitializeContext
        
        l3.Text = ""
        zx1.LaserColor = Colors.Yellow
        zx1.MaskColor = Colors.ARGB(150, 0, 0, 200)
        zx1.BorderColor = Colors.Magenta
        zx1.BorderStrokeWidth = 5
        zx1.BorderLineLength = 40
        
        zx1.AutoFocusInterval = 500
        zx1.AutoFocus = True
        zx1.FocusMode = zx1.FOCUS_MODE_AUTO
        
        
        zx1.Visible = False
        
    Else
        ToastMessageShow("Permission not granted", True)
        Return
    End If

End Sub

Sub Activity_Resume
    
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    
    zx1.Visible = False
    zx1.stopScanner

End Sub


Sub b1_Click
    
    zx1.toggleFlash
    
End Sub

Sub b2_Click
  
    zx1.Visible = True
    zx1.startScanner
    zx1.TurnFlashOn
    scanStarted = True
    Log(zx1.isFlashOn)
  
End Sub

Sub b3_Click
    
    scanStarted = False
    zx1.Visible = False
    zx1.stopScanner
    l1.Text = ""
    l2.Text = ""

End Sub

Sub b4_Click
    
    Dim zoomInValue As Int = 5                     'positive values -> zoon in
    If scanStarted Then
        If zx1.CurrentZoomValue <= (zx1.MaxZoomValue - zoomInValue) Then
            zx1.zoomIn(zoomInValue)
        Else
            zx1.zoomIn(zx1.MaxZoomValue - zx1.CurrentZoomValue)
        End If
    End If
    
End Sub

Sub b5_Click
    
    Dim zoomInValue As Int = -5                     'negative values -> zoom out
    If scanStarted Then
        If zx1.CurrentZoomValue > (-1* zoomInValue) Then
            zx1.zoomIn(zoomInValue)
        Else
            zx1.zoomIn(0 - zx1.CurrentZoomValue)
        End If
    End If
    
End Sub

Sub zx1_scan_result (scantext As String, scanformat As String)
    
    nativeMe.RunMethod("playTone", Null)
    Dim tim As Long = 100
    nativeMe.RunMethod("vibrateOnce", Array(tim))
    Log ("B4A scan text = " & scantext)
    Log ("B4A scan format = " & scanformat)
    Log("isFlashOn = " & zx1.isFlashOn)
    l2.Text = scantext & " (type = " & scanformat & ")"
    
End Sub


Sub zx1_brightness_changed (bright As Int )                        'ADDED 6 MARCH 2016
'    Log("bright = " & bright)                                      'this is the average brightness of the frame that was captured for possible barcode extraction
    flag = flag + 1
    l1.Text = "Brigtness = " & bright
    If flag = 30 Then                                              'I only want to use the average brightness of every 30th frame to calculate a running brigtness average
        flag = 0                                                   'reset the count to zero for the next 30 frames
        If bright < 150 Then                                       'discard excessive high brigness values
            runningavg = (runningavg + bright) / 2
'            Log("runningavg brightness = " & runningavg)
            If runningavg < 70 Then
                If Not(zx1.isFlashOn) Then zx1.TurnFlashOn
            Else if runningavg > 115 Then
                If zx1.isFlashOn Then zx1.TurnFlashOff
            End If   
        End If   
    End If   
    l3.Text = "isFlashOn = " & zx1.isFlashOn
    
End Sub   

#If Java

import android.os.Vibrator;
import android.content.Context;

import android.media.ToneGenerator;
import android.media.AudioManager;

/**
*Vibrate with a given pattern.
*Pass in an array of Longs that are the durations for which to turn on or off the vibrator in milliseconds.
*The first value indicates the number of milliseconds to wait before turning the vibrator on. The next
*value indicates the number of milliseconds for which to keep the vibrator on before turning it off.
*Subsequent values alternate between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
*Parameters:
*pattern ---> an array of longs of times for which to turn the vibrator on or off.
*repeat ---> the index into pattern at which to repeat, or -1 if you don't want to repeat.
*
*You need to add the following to the manifest file of the B4A project:
*AddPermission("android.permission.VIBRATE")
*/
public void vibratePattern(long[] pattern, int repeat) {
    
  Vibrator v = (Vibrator) BA.applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
  if (v.hasVibrator()) {
    v.vibrate(pattern, repeat);
  }
}

/**
*Cancel vibration (in case of method vibratePattern being active)
*You need to add the following to the manifest file of the B4A project:
*AddPermission("android.permission.VIBRATE")
*
*/
public void vibrateCancel(int dummy) {
    
  Vibrator v = (Vibrator) BA.applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
  if (v.hasVibrator()) {
     v.cancel();
  }
}

/**
*Vibrate continuously for the specified number of milliseconds
*You need to add the following to the manifest file of the B4A project:
*AddPermission("android.permission.VIBRATE")
*/
public void vibrateOnce(long duration) {
    
  Vibrator v = (Vibrator) BA.applicationContext.getSystemService(Context.VIBRATOR_SERVICE);
  if (v.hasVibrator()) {
     v.vibrate(duration);
  }
}


  public void playTone() {
      final ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
      tg.startTone(ToneGenerator.TONE_PROP_BEEP);
  }     

#End If



5_05042020.png
 

Attachments

  • ZxingBarcodeScannerLibFilesV1.03.zip
    30.5 KB · Views: 551
  • b4aZxingBarcodeScanner05042020.zip
    12.1 KB · Views: 543

Situ LLC

Active Member
Licensed User
Hi johan,

Do you have the possibility to share the java code of the library?

Regards
 

Johan Schoeman

Expert
Licensed User
Longtime User

Attachments

  • src.zip
    19.5 KB · Views: 443

Situ LLC

Active Member
Licensed User
Thanks Johan
 

Johan Schoeman

Expert
Licensed User
Longtime User
@Johan Schoeman
Hello I am using your library.
When scanning and accessing the information, an android notification sound is heard.
I will cancel it and activate my own wav file.

Can you help?
Thanks.
Comment out this line in the B4A code

nativeMe.RunMethod("playTone", Null)
 

Xfood

Expert
Licensed User
Hi, I'm looking for a good bookstore for reading EAN code, I tried several, this and what I think has all the features, except for the fact that in vertical mode the room does not fit the reserved space, I am attaching the Imagine. There is a way to fix it, it would be great
thank you all
1616882639818.png
 
Top