B4A Library Barcode Scanner - 100% embedded within B4A (15 Feb 2016 : New library files in Post #105)

The attached project wraps this Github project. It is a barcode scanner based on the ZXING project. I have successfully scanned the following 1D and 2D barcodes:
1. Code 39
2. Code 93
3. Code 128
4. Two-of-Five Interleaved (TFI)
5. EAN13
6. EAN8
7. PDF417
8. QR Code
9. Aztec Code
10. Codabar

It is 100% embedded within the B4A project via a CustomView. Thus, you can add buttons, background images, background colors, labels, textviews, or whatever you like to the activity via the designer or via code. It does not have all the bells and whistles that the ZXING project offers (i.e ability to set the laser color etc) but it works 100% within B4A. It does not take over control of the B4A activity - set the size (width / height / left / top) of the CustomView in the B4A code and that will be the size of your barcode View Finder. Add buttons to start and stop the scanner. It is as simple as that.

For as long as what the scanner is active it will scan 1D/2D barcodes i.e no need to stop and start the scanner to start scanning a new barcode. Just point the scanner at the next barcode to scan.

I have added the following events to the B4A project:
1. scanresult - here you can get the decoded string/text result when a successful scan occurred
2. scanner_started - this event is raised when the scanner is activated via B4A code
3. scan_error - sorry, but have not seen this event in action yet as I have had no miss scans thus far
4. scanner_stopped - this event is raised when the scanner is stopped.

There are a number of files in the B4A project's Object/res/..... folders that are set to read only. Keep them like that.

There are permissions added to the B4A manifest - make sure you take note of it should you start a new B4A project.

You will need core-3.1.0.jar and android-support-v4.jar to be in your additional library folder. I have zipped them together - you can download them from HERE. Extract them from the zipped file and copy them to your additional library folder.

1.png


2.png


Some sample code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: zxScannerLiveView
    #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.

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 zxslv As zxScannerLiveView
    Private b1 As Button
    Private b2 As Button
    Private l1 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")

    zxslv.Initialize("zxslv")

    Activity.AddView(zxslv, 50%x - 45%y, 5%y, 90%y, 90%y)

    zxslv.HudVisible = True
    zxslv.PlaySound = True
    zxslv.Visible = False

End Sub

Sub Activity_Resume


End Sub

Sub Activity_Pause (UserClosed As Boolean)

    zxslv.Visible = False
    zxslv.stopScanner

End Sub

Sub b1_Click

    zxslv.Visible = True
    zxslv.startScanner

End Sub
Sub b2_Click

    zxslv.Visible = False
    zxslv.stopScanner
    l1.Text = ""

End Sub

Sub zxslv_scanresult

    Log(zxslv.ScanResult)
    l1.Text = zxslv.ScanResult

End Sub

Sub zxslv_scanner_started

    Log("Scanner Started")

End Sub

Sub zxslv_scan_error

    Log("Scan Error")

End Sub

Sub zxslv_scanner_stopped

    Log("Scanner stopped")

End Sub


And this will add a coloured frame around the view finder - making use of panels via B4A code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: zxScannerLiveView
    #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.

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 zxslv As zxScannerLiveView
    Private b1 As Button
    Private b2 As Button
    Private l1 As Label
    Private l2, l3, l4, l5 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")

    zxslv.Initialize("zxslv")
    Dim framecolor As Int = Colors.Red

    l2.Initialize("")
    l3.Initialize("")
    l4.Initialize("")
    l5.Initialize("")

    Activity.AddView(zxslv, 50%x - 45%y, 5%y, 90%y, 90%y)
    Activity.AddView(l2, 50%x - 45%y - 1%y, 4%y, 1%y, 92%y)
    Activity.AddView(l3, 50%x + 45%y, 4%y, 1%y, 92%y)
    Activity.AddView(l4, 50%x - 45%y - 1%y, 4%y, 91%y, 1%y)
    Activity.AddView(l5, 50%x - 45%y - 1%y, 5%y + 90%y, 91%y, 1%y)


    l2.Color = framecolor
    l2.Visible = False

    l3.Color = framecolor
    l3.Visible = False

    l4.Color = framecolor
    l4.Visible = False

    l5.Color = framecolor
    l5.Visible = False

    zxslv.HudVisible = True
    zxslv.PlaySound = True
    zxslv.Visible = False


End Sub

Sub Activity_Resume


End Sub

Sub Activity_Pause (UserClosed As Boolean)

    zxslv.Visible = False
    zxslv.stopScanner

    l2.Visible = False
    l3.Visible = False
    l4.Visible = False
    l5.Visible = False

End Sub

Sub b1_Click

    zxslv.Visible = True
    zxslv.startScanner

    l2.Visible = True
    l3.Visible = True
    l4.Visible = True
    l5.Visible = True

End Sub
Sub b2_Click

    zxslv.Visible = False
    zxslv.stopScanner
    l1.Text = ""

    l2.Visible = False
    l3.Visible = False
    l4.Visible = False
    l5.Visible = False



End Sub

Sub zxslv_scanresult

    Log(zxslv.ScanResult)
    l1.Text = zxslv.ScanResult

End Sub

Sub zxslv_scanner_started

    Log("Scanner Started")

End Sub

Sub zxslv_scan_error

    Log("Scan Error")

End Sub

Sub zxslv_scanner_stopped

    Log("Scanner stopped")

End Sub

It will look like this:

3.png


zxScannerLiveView
Author: Github: Dmitri Livotov, Wrapper: Johan Schoeman
Version: 1



zxScannerLiveView
Events:

  • scan_error ( )
  • scanner_started ( )
  • scanner_stopped ( )
  • scanresult ( )
Fields:
  • BACK As String
  • FRONT As String
  • ba As BA
  • mfrontOrBack As String
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)
  • startScanner
    Starts scanner, using device default camera
  • stopScanner
    Stops currently running scanner
  • toggleFlash
Properties:
  • BackgroudImage As String [write only]
  • Background As Drawable
  • CameraToUse As String [write only]
  • Color As Int [write only]
  • Enabled As Boolean
  • Height As Int
  • HudVisible As Boolean [write only]
  • Left As Int
  • PlaySound As Boolean [write only]
  • SameCodeRescanProtectionTime As Long [write only]
  • ScanResult As String [read 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

  • zxScannerLiveViewLibFiles.zip
    44.9 KB · Views: 3,081
  • b4aZXscannerLiveView.zip
    19 KB · Views: 3,042
Last edited:

Johan Schoeman

Expert
Licensed User
Longtime User
I love this lib, but I have 1 issue.
While I have a button for the flash (on/off), the flash also turns on/off if the scanner area is touched while scanning.
I do not want the user to turn on the torch, unless the "torch"button is selected.
How do I do that
I will have to change the library to accommodate your request. It was like that before but added the functionality to toggle the torch when the scanner is active and touched based on such a request in another scanner that I have posted.
 

rkmoray

Active Member
Licensed User
Longtime User
Any idea when that will happen, or can I use the previous version you were talking about that had that feature?
 

rkmoray

Active Member
Licensed User
Longtime User
1 other question, why are the targeting squares not centered on the ocr(see pic)?
 

Attachments

  • Screenshot_20180321-112439.png
    Screenshot_20180321-112439.png
    208.7 KB · Views: 356

Johan Schoeman

Expert
Licensed User
Longtime User

Johan Schoeman

Expert
Licensed User
Longtime User
I love this lib, but I have 1 issue.
While I have a button for the flash (on/off), the flash also turns on/off if the scanner area is touched while scanning.
I do not want the user to turn on the torch, unless the "torch"button is selected.
How do I do that

The attached library files (V1.04) should sort out the torch when the scanner is active and touched. Add the following to your code before starting the scanner:
B4X:
zxslv.ToggleViewTouchTorch = False    'or True
 

Attachments

  • zxScannerLiveView.xml
    12.2 KB · Views: 508
  • zxScannerLiveView.jar
    56.2 KB · Views: 476

Johan Schoeman

Expert
Licensed User
Longtime User
1 other question, why are the targeting squares not centered on the ocr(see pic)?
Can you upload a small sample project that demonstrates the targeting square being out of position. I don't get that on any of my devices.
 

gelay

Member
Licensed User
Longtime User
Hi Johan

The sample project works fine for me, but when I try it to fit in to my project I've got the error below.
Something???
Thanks
Krisztian

B4A Version: 7.30
Parsing code. (0.01s)
Compiling code. (0.16s)
Compiling layouts code. (0.00s)
Organizing libraries. (0.00s)
Generating R file. (0.68s)
Compiling generated Java code. (2.58s)
Convert byte code - optimized dex. Error
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/BarcodeFormat;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/Binarizer;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/BinaryBitmap;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/ChecksumException;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/DecodeHintType;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/Dimension;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/EncodeHintType;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/FormatException;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/InvertedLuminanceSource;
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Translation has been interrupted
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:689)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:313)
at com.android.dx.command.dexer.Main.run(Main.java:279)
at com.android.dx.command.dexer.Main.main(Main.java:247)
at com.android.dx.command.Main.main(Main.java:106)
Caused by: java.lang.InterruptedException: Too many errors
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:681)
... 4 more
 

gelay

Member
Licensed User
Longtime User
Hi Johan

The sample project works fine for me, but when I try it to fit in to my project I've got the error below.
Something???
Thanks
Krisztian

B4A Version: 7.30
Parsing code. (0.01s)
Compiling code. (0.16s)
Compiling layouts code. (0.00s)
Organizing libraries. (0.00s)
Generating R file. (0.68s)
Compiling generated Java code. (2.58s)
Convert byte code - optimized dex. Error
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/BarcodeFormat;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/Binarizer;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/BinaryBitmap;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/ChecksumException;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/DecodeHintType;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/Dimension;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/EncodeHintType;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/FormatException;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/zxing/InvertedLuminanceSource;
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Translation has been interrupted
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:689)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:313)
at com.android.dx.command.dexer.Main.run(Main.java:279)
at com.android.dx.command.dexer.Main.main(Main.java:247)
at com.android.dx.command.Main.main(Main.java:106)
Caused by: java.lang.InterruptedException: Too many errors
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:681)
... 4 more
It's working now two zxing lib loaded parallel... :)
 

domz

Member
need help please...

first error: support-v4.jar not found ....
so I fix it in xml ...

second error: core-3,0,1.jar not found
I downloaded lib-core-3.1.0.jar in internet ..... I dunno if this is the reason for third error

I change the xml for core-3.1.0 into lib-core-3.1.0


the code runs fine then as I installed and run. the app closed suddenly
then the log says:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/zxing/DecodeHintType;

howcan I fix it?
my phone model is: Redmi Go
 

Tico.13

Member
Hi to all, im using the zxScanner and its working fine, i just need some help stopping the scanner after obtaining the result and having filled an edittext
This is my code in the zxslv_scanresult event:

zxslv_scanresult event:
Sub zxslv_scanresult
    
    Log(zxslv.ScanResult)
    Label1.Text = zxslv.ScanResult
    'zxslv.RemoveView
    'Activity.Finish

End Sub


Best regards
 

Johan Schoeman

Expert
Licensed User
Longtime User
Hi to all, im using the zxScanner and its working fine, i just need some help stopping the scanner after obtaining the result and having filled an edittext
This is my code in the zxslv_scanresult event:

zxslv_scanresult event:
Sub zxslv_scanresult
   
    Log(zxslv.ScanResult)
    Label1.Text = zxslv.ScanResult
    'zxslv.RemoveView
    'Activity.Finish

End Sub


Best regards
Something like this:

B4X:
zxslv.Visible = False
zxslv.stopScanner
 

romario87027

Active Member
Licensed User
Longtime User
I inserted the library in my project, I can't understand why it gives me "Scan Error".
B4a Version 10.70!!
 

Johan Schoeman

Expert
Licensed User
Longtime User
I inserted the library in my project, I can't understand why it gives me "Scan Error".
B4a Version 10.70!!
What is the barcode that gives you the error? Can you post it?
 

Johan Schoeman

Expert
Licensed User
Longtime User

romario87027

Active Member
Licensed User
Longtime User
Have you added RuntimePermission for the camera? What is target SDK you have in your B4A manifest?
this is Manifest:
B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="30"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
'End of default text.
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)
CreateResourceFromFile(Macro, FirebaseAnalytics.Firebase)
CreateResourceFromFile(Macro, FirebaseNotifications.FirebaseNotifications)
AddPermission(android.permission.SYSTEM_ALERT_WINDOW)
AddPermission(android.permission.READ_PHONE_STATE)
AddPermission(android.permission.GET_ACCOUNTS)
SetApplicationAttribute(android:usesCleartextTraffic, "true")

'------------------------------------------
AddManifestText(<uses-feature android:name="android.hardware.telephony" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera.flash" android:required="false" />)
'AddPermission("android.permission.ACCESS_COARSE_LOCATION")
AddPermission("android.permission.INTERNET")
AddPermission("android.permission.ACCESS_FINE_LOCATION")
AddPermission("android.permission.WAKE_LOCK")
AddPermission("android.permission.DEVICE_POWER")
'AddPermission("android.permission.ACCESS_COARSE_UPDATES")
AddPermission("android.permission.READ_PHONE_STATE")
AddPermission("android.permission.VIBRATE")
AddPermission("android.permission.CAMERA")
AddPermission("android.permission.FLASHLIGHT")
AddPermission("android.hardware.camera")
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
 

Johan Schoeman

Expert
Licensed User
Longtime User
this is Manifest:
B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="30"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
'End of default text.
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)
CreateResourceFromFile(Macro, FirebaseAnalytics.Firebase)
CreateResourceFromFile(Macro, FirebaseNotifications.FirebaseNotifications)
AddPermission(android.permission.SYSTEM_ALERT_WINDOW)
AddPermission(android.permission.READ_PHONE_STATE)
AddPermission(android.permission.GET_ACCOUNTS)
SetApplicationAttribute(android:usesCleartextTraffic, "true")

'------------------------------------------
AddManifestText(<uses-feature android:name="android.hardware.telephony" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />)
AddManifestText(<uses-feature android:name="android.hardware.camera.flash" android:required="false" />)
'AddPermission("android.permission.ACCESS_COARSE_LOCATION")
AddPermission("android.permission.INTERNET")
AddPermission("android.permission.ACCESS_FINE_LOCATION")
AddPermission("android.permission.WAKE_LOCK")
AddPermission("android.permission.DEVICE_POWER")
'AddPermission("android.permission.ACCESS_COARSE_UPDATES")
AddPermission("android.permission.READ_PHONE_STATE")
AddPermission("android.permission.VIBRATE")
AddPermission("android.permission.CAMERA")
AddPermission("android.permission.FLASHLIGHT")
AddPermission("android.hardware.camera")
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
Ok. So you have target SDK set to 30. Then you need to add RuntimePermissions to the B4A project code for permission to access the camera. A simple test would be to set the TargetSDK to 22 and see if the camera fires up. You might have to delete the installation of the app on your device before compiling with the SDK in the manifest set to 22.
 
Top