B4A Library ZXingLib by icefairy333 - modified by Johan Schoeman (Scan QR Codes and other 1D/2D Barcodes)

ScannerActive.png


See the attached project (with library files in the /files folder of the project). This is based on the original work of @icefairy333. I have modified @icefairy333's library so that it can do the following:

1. Set the color of the border of the framing rectangle from B4A code
2. Set the color of the laser from B4A code
3. Set the color of the mask around the framing rectangle from B4A code
4. Set the color of the result points from B4A code
5. Set the color of the final panel being displayed before control is being returned to the B4A project from B4A code
6. Ability to switch on/off the torch when making use of the back camera scanner by means of the volume up/down buttons. Use the volume up/down buttons to toggle the torch on/off when the scanner is active.

a. It retains the Portrait /Landscape option as per @icefairy333 's version 1.5 posted in post #1 of his original post.
b. It retains use of the front / back camera (not sure if it supports all types of devices)

See post #5 for changes that might be required to the Manifest of the project.

Edit: Posting JohanIceFairyZxingWidthMod.zip that will allow you to change the width / height of the ViewFinder. New library files are in the /files folder of the attached project. Replace the old lib files with the new ones.

Edit: Posting JohanIceFairyZxingWidthModAndTextMod.zip that will allow you also add text to the mask around the viewfinder of the scanner.

Edit: Posting JohanIceFairyZxingWidthTextBitmap.zip that will allow you to also add a bitmap to the mask around the viewfinder of the scanner.

Edit: Posting JohanIcefairyZxingWidthTextBitmapTouchTorch.zip that retains all previously added functionality but you can now also switch on/off the flash when using the back camera by either using the volume up/down buttons or just touch the screen while the scanner is active.

Edit: attached file src.zip contains the java source code. It can be compiled into a B4A library with Simple Library Compiler (SLC) as is, provided you set up the directory structure correctly and you set up SLC correctly. See elsewhere in this thread how to do it.

Edit: Attached JohanIcefairyZxingTimeout.zip with all the previously added functionality but adding an option to specify a timeout duration. Default timeout duration is 15 seconds (should you not specify any timeout duration). Also posting src_2.zip with the amended java source code

eg of Button1_Click for project in JohanIcefairyZxingTimeout.zip
B4X:
Sub Button1_Click
  zx.isportrait = True
  zx.useFrontCam = False

  'set the timeoutDuration to a very high value (such as 2000000000) if you dont want it to time out
  '2000000000 = 63 years+
  zx.timeoutDuration = 30

  'change these factors between 0 and 1 to change the size of the viewfinder rectangle
  'the library will limit the minimum size to 240 x 240 pixels and the maximum to (screen width) x   (screen height) pixels
  zx.theViewFinderXfactor = 0.7
  zx.theViewFinderYfactor = 0.5

  zx.theFrameColor = Colors.Blue
  zx.theLaserColor = Colors.Yellow
  zx.theMaskColor = Colors.argb(95, 0, 0, 255)
  zx.theResultColor = Colors.Green
  zx.theResultPointColor = Colors.Red

  'set the prompt messages
  zx.theTopPromptMessage = "This was done......"
  zx.theTopPromptTextSize = 5%y'text size in pixels
  zx.topPromptColor = Colors.Red
  zx.topPromptDistanceFromTop = 1%y'pixel distance from top

  zx.theBottomPromptMessage = "Just for fun......"
  zx.theBottomPromptTextSize = 5%y'text size in pixels
  zx.bottomPromptColor = Colors.Blue
  zx.bottomPromptDistanceFromBottom = 5%y'pixel distance from top

  'add a bitmap
  zx.theBitMap = bm
  zx.theBitMapLeft = 40%x
  zx.theBitMapTop = 10%y
  zx.theBitMapWidth = 20%x
  zx.theBitMapHeight = 20%x

  zx.BeginScan("myzx")
End Sub

Enjoy!
 

Attachments

  • JohanIcefairyZxing.zip
    416.8 KB · Views: 1,024
  • JohanIcefairyZxingWidthMod.zip
    417.5 KB · Views: 602
  • JohanIcefairyZxingWidthModAndTextMod.zip
    418.4 KB · Views: 559
  • JohanIcefairyZxingWidthTextBitmap.zip
    421 KB · Views: 531
  • JohanIcefairyZxingWidthTextBitmapTouchTorch.zip
    421.5 KB · Views: 611
  • JohanIcefairyZxingTimeout.zip
    421.5 KB · Views: 618
  • b4aZXINGusingVer1.05.zip
    12.2 KB · Views: 339
  • JhsIceZxing1Ver1.05.zip
    444.1 KB · Views: 340
  • JhsIceZxing1Ver1.06.zip
    444.1 KB · Views: 770
Last edited:

Johan Schoeman

Expert
Licensed User
Hi!
This library worked flawlessly on my phone previously, but now (i think after Android 6.0.1 update) it exits from the app immediately after scan. It doesn't fire xxx_result. I don't see any relation with the torch. I have a Note4, but it's also doesn't work on a fresh updated S7. I'm using it in portrait mode, if it counts.
Please help.
Thanks!
Attached is V1.02 of the library files. It should hopefully sort out the problem. Seems as if the intent object was getting too big (the size of the byte[] array when using high definition cameras) and then the intent fails due to its size. Have bypassed the issue by creating a public static variable in class CaptureActivity that I can then access from within the wrapper. Looks like it solved the issue.
 

Attachments

  • JhsIceZxing1.xml
    13.5 KB · Views: 212
  • JhsIceZxing1.jar
    481.3 KB · Views: 232
Last edited:

Johan Schoeman

Expert
Licensed User
Hi Johan, thanks for sharing this great lib, i have same issue as @kokiky above.

I have 2 device with different functionality, first one is Zebra MC36 (Android 4.4) its a android base barcode reader and Infinix Note 4 (Android 7) as my daily personal phone. I have create my own app and been installed on both device. With MC36 the lib works well without a problem but not in Note 4.

The problem is, after scan the barcode the screen goes blank without returning a result, the app just freeze and i should end task the app.
I use the lib from post #83

Since i don't need landscape mode or torch functionality, my goals just read the barcode value and show it at textbox for further action.

Thanks
See post #122 - lib files there should solve the problem
 

ivan.tellez

Active Member
Licensed User
You really are great!

Seems as if the intent object was getting too big

If the Bitmap is not used in the app, can we get a better performance avoiding this bitmap at all? somenting like a new option to prevent this bitmap be created in the memory:

B4X:
zx.ReturnBitmap = False

Same event signature, just returning a Null Bitmap



Also, can you add to the lib the new macro functionality for B4A 8.0+ ?

To use in the Manifest editor something like

B4X:
CreateResourceFromFile(Macro, JhsIceZxing1.CatureLandscape)
CreateResourceFromFile(Macro, JhsIceZxing1.CaturePortrait)

instead of:

B4X:
AddApplicationText(<activity android:name="ice.zxing.CaptureActivity"
            android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden">
        </activity>)

AddApplicationText(<activity android:name="ice.zxing.CaptureActivity"
            android:screenOrientation="portrait" android:configChanges="orientation|keyboardHidden"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden">
        </activity>)

You just have to put the attached files (remove the .txt) on the root of the jar


I'm currently using the ZXing Glass Library, works ok and has the Create2DCode, I cant use both at the same time. But if you add the Create2DCode function, this lib could replace almos all other libs ?

B4X:
public Bitmap Create2DCode(String str) throws WriterException, UnsupportedEncodingException {
    BitMatrix matrix = new MultiFormatWriter().encode(new String(str.getBytes("GBK"),"ISO-8859-1"),BarcodeFormat.QR_CODE, 300, 300);
    int width = matrix.getWidth();
    int height = matrix.getHeight();
    int[] pixels = new int[width * height];
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            if(matrix.get(x, y)){
                pixels[y * width + x] = 0xff000000;
            }
        }
    }
    Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    bmp.setPixels(pixels, 0, width, 0, 0, width, height);
    return bmp;
}

And a recomendation, Can you update post #1 when you post a new update?


Thanks
 

Attachments

  • CatureLandscape.b4x_excluded.txt
    286 bytes · Views: 111
  • CaturePortrait.b4x_excluded.txt
    285 bytes · Views: 97
Last edited:

Johan Schoeman

Expert
Licensed User
You really are great!



If the Bitmap is not used in the app, can we get a better performance avoiding this bitmap at all? somenting like a new option to prevent this bitmap be created in the memory:

B4X:
zx.ReturnBitmap = False

Same event signature, just returning a Null Bitmap



Also, can you add to the lib the new macro functionality for B4A 8.0+ ?

To use in the Manifest editor something like

B4X:
CreateResourceFromFile(Macro, JhsIceZxing1.CatureLandscape)
CreateResourceFromFile(Macro, JhsIceZxing1.CaturePortrait)

instead of:

B4X:
AddApplicationText(<activity android:name="ice.zxing.CaptureActivity"
            android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden">
        </activity>)

AddApplicationText(<activity android:name="ice.zxing.CaptureActivity"
            android:screenOrientation="portrait" android:configChanges="orientation|keyboardHidden"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden">
        </activity>)

You just have to put the attached files (remove the .txt) on the root of the jar


I'm currently using the ZXing Glass Library, works ok and has the Create2DCode, I cant use both at the same time. But if you add the Create2DCode function, this lib could replace almos all other libs ?

B4X:
public Bitmap Create2DCode(String str) throws WriterException, UnsupportedEncodingException {
    BitMatrix matrix = new MultiFormatWriter().encode(new String(str.getBytes("GBK"),"ISO-8859-1"),BarcodeFormat.QR_CODE, 300, 300);
    int width = matrix.getWidth();
    int height = matrix.getHeight();
    int[] pixels = new int[width * height];
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            if(matrix.get(x, y)){
                pixels[y * width + x] = 0xff000000;
            }
        }
    }
    Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    bmp.setPixels(pixels, 0, width, 0, 0, width, height);
    return bmp;
}

And a recomendation, Can you update post #1 when you post a new update?


Thanks

All of your requests included in the new files in post #1 of this thread.
New lib files = JhsIceZxing1Ver1.05.zip
Sample B4A project = b4aZXINGusingVer1.05.zip
Library (JhsIceZxing1) should show as V1.05 in the IDE
You can create QR Code, Aztec Codes, and DataMatrix.

It is set for target SDK 26
See the manifest for:
B4X:
CreateResourceFromFile(Macro, JhsIceZxing1.CaturePortrait)

1.png


Sample B4A code:
B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: b4aZXING
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

'Activity module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim rp As RuntimePermissions               'ADDED 2 June 2018

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 zx As JhsIceZxing1
    Private Button1 As Button
    
    
    
    Dim bm As Bitmap
    
    Dim ImageView1 As ImageView
    Private ImageView2 As ImageView
    Private ImageView3 As ImageView
    Private ImageView4 As ImageView
    Dim cnt As Int
    Private ImageView5 As ImageView

End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("main")
'    check
    bm.Initialize(File.DirAssets,"B4A.png")
    ImageView1.Color = Colors.Transparent
    ImageView2.Color = Colors.Transparent
    ImageView3.Color = Colors.Transparent
    ImageView4.Color = Colors.Transparent
    cnt = 1
    
    ImageView5.Gravity = Gravity.FILL                                                                  'ADDED 2 June 2018
    
    'use zx.CreateQRCode or zx.CreateDataMatrixCode or zx.CreateAztecCode
    zx.CODE_BACK_COLOR = Colors.Yellow                                                                 'ADDED 2 June 2018
    zx.CODE_FORE_COLOR = Colors.blue                                                                   'ADDED 2 June 2018
    bm = zx.CreateQRCode("Hello B4A - testing creation of 2D codes. It seems to be working well")      'ADDED 2 June 2018
    
    ImageView5.Bitmap = bm                                                                             'ADDED 2 June 2018


End Sub
 Sub Button1_Click
    Dim Result As Boolean = True                                                                       'ADDED 2 June 2018
    If Not(rp.Check(rp.PERMISSION_CAMERA)) Then                                                        'ADDED 2 June 2018
        rp.CheckAndRequest(rp.PERMISSION_CAMERA)                                                       'ADDED 2 June 2018
        Wait For Activity_PermissionResult (Permission As String, Result As Boolean)                   'ADDED 2 June 2018
    End If                                                                                             'ADDED 2 June 2018
    If Result Then                                                                                     'ADDED 2 June 2018
    '    ImageView1.Background = Null
        
        zx.isportrait = True
        zx.displayOrientation = 90     '90 is the default value that was set in the library. It works for most devices
                                       'although for eg the Nexus 5 will show an upside down preview with this setting.
                                       'I guess zx.displayOrientation = 270 will fix it for the Nexus 5 when used in portrait mode.
        zx.useFrontCam = False
        'set the timeoutDuration to a very high value (such as 2000000000) if you dont want it to time out
        '2000000000 = 63 years
        zx.timeoutDuration = 30
        
        
        'change these factors between 0 and 1 to change the size of the viewfinder rectangle
        'the library will limit the minimum size to 240 x 240 pixels and the maximum to (screen width) x (screen height) pixels

        zx.theViewFinderXfactor = 0.7      'portrait
        zx.theViewFinderYfactor = 0.5      'portrait
        
    '    zx.theViewFinderXfactor = 0.5      'landscape
    '    zx.theViewFinderYfactor = 0.5      'landscape
        
        zx.theFrameColor = Colors.Blue
        zx.theLaserColor = Colors.Yellow
        
        zx.moveLaser = True
        
        zx.theMaskColor = Colors.argb(100, 0, 0, 100)
        zx.theResultColor = Colors.Green
        zx.theResultPointColor = Colors.Red
        
        'set the prompt messages
        zx.theTopPromptMessage = "This was done......"
        zx.theTopPromptTextSize = 5%y                            'text size in pixels
        zx.topPromptColor = Colors.Green
        zx.topPromptDistanceFromTop = 1%y                        'pixel distance from top
        zx.textSkewnessTop = 0.0
        
        
        zx.theBottomPromptMessage = "Just for fun......"
        zx.theBottomPromptTextSize = 5%y                         'text size in pixels
        zx.bottomPromptColor = Colors.Green
        zx.bottomPromptDistanceFromBottom = 5%y                  'pixel distance from top
        zx.textSkewnessBottom = 0.0
        
        'add a bitmap - portrait
        zx.theBitMap = bm
        zx.theBitmapPosition(40%x,10%y,20%x,20%x)
        
        'add a bitmap - landscape
    '    zx.theBitMap = bm
    '    zx.theBitmapPosition(5%x,5%x,20%y,20%y)   

        zx.mustBeep = False
        zx.mustVibrate = True
        
        'START OF ADDED 7 NOVEMBER 2015:
    '   Specify the bar code formats to scan
    '   If not specified then all code formats will be scanned
    '   Specify one of the following: PRODUCT_FORMATS, ONE_D_FORMATS, QR_CODE_FORMATS, DATA_MATRIX_FORMATS, AZTEC_FORMATS, PDF_417_FORMATS, TWO_D_FORMATS
    '   PRODUCT_FORMATS are the following: UPC A, UPC E, EAN 13, EAN 8, RSS 14
    '   ONE_D_FORMATS are all the PRODUCT FORMATS plus the following: CODE 39, CODE 93, CODE 128, ITF
    '   TWO_D_FORMATS are the following: QR CODE, DATA MATRIX, AZTEC CODE, PDF 417

        'COMMENT THE BELOW LINE OR USE zx.ScanMode = "" to scan all the 1D and 2D type barcodes that this version of the ZXING library supports
        'zx.ScanMode = zx.FORMATS_TWO_D                 
        'END OF ADDED 7 NOVEMBER 2015
        zx.scanInvertedCodes = True
        
        zx.ReturnBitmap = True                                                                       'ADDED 2 June 2018
        zx.BeginScan("myzx")   
    End If   
      
    
End Sub

Sub myzx_result(atype As String, Value As String, image As Bitmap)
    If image <> Null Then                    'ADDED 2 June 2018 ---> when zx.ReturnBitmap = False a null bitmap will be returned
        If cnt = 1 Then
            ImageView1.Bitmap = image
            ImageView1.Gravity = Gravity.FILL
          
            cnt = cnt + 1
          
        Else If cnt = 2 Then
            ImageView2.Bitmap = image
            ImageView2.Gravity = Gravity.FILL
            cnt = cnt + 1
        Else If cnt = 3 Then
            ImageView3.Bitmap = image
            ImageView3.Gravity = Gravity.FILL
            cnt = cnt + 1
        Else If cnt = 4 Then
            ImageView4.Bitmap = image
            ImageView4.Gravity = Gravity.FILL
            cnt = cnt + 1
        Else If cnt > 4 Then
            ImageView1.Bitmap = Null
            ImageView1.Bitmap = ImageView2.Bitmap
            ImageView2.Bitmap = Null
            ImageView2.Bitmap = ImageView3.Bitmap
            ImageView3.Bitmap = Null
            ImageView3.Bitmap = ImageView4.Bitmap
            ImageView4.Bitmap = Null
            ImageView4.Bitmap = image
            ImageView1.Gravity = Gravity.FILL
            cnt = cnt + 1
        End If

        Log(cnt)
    End If   
    
    Log("type:" & atype &  " Value:" & Value)
    Msgbox(Value,"type:" & atype)   

End Sub
Sub myzx_timedout(timedOut As Boolean)
    Log("timedOut " & timedOut)

End Sub

Sub myzx_usercancelled(userCancelled As Boolean)
    Log("userCancelled " & userCancelled)
End Sub

Sub Activity_Resume
    

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

ivan.tellez

Active Member
Licensed User
You are really amazing, now you can say that this is THE barcode Library. It is working great.

However, there is a little issue. I already was ussing the RuntimePermissions, but the first time i try the new lib, it dint work, CheckAndRequest allways returned false. Until i noticied that you remove all the permissions in the lib, so as erel said "You can only request permissions that were declared in the manifest file (this is usually taken care by the compiler)." I add the "AddPermission(android.permission.CAMERA)" to the manifest and it worked.

So, according what @Erel said, the lib should declare all the permissions, so the compiler adds them to the manifest when compiling. You can test this deleting ALL the manually added AddPermission, in the manifest and adding the permissions to the Library (android.permission.CAMERA, android.permission.VIBRATE and android.permission.FLASHLIGHT)

Also according to Erel's tutorial Runtime Permissions, The Check function should not be used on activities, so, its a better practice to only use CheckAndRequest

B4X:
Sub DoScan
    rp.CheckAndRequest(rp.PERMISSION_CAMERA)
End Sub

Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = rp.PERMISSION_CAMERA Then
        If Result = True Then
            ShowBarcodeReaderCodeHere
        Else
            xui.MsgboxAsync("You have to grant permision...", "Permision not granted")
        End If
    End If
End Sub

(Maybe @Erel could give us some insights on this)
 

DonManfred

Expert
Licensed User
However, there is a little issue
Please note that @Johan Schoeman did wrote the Lib in 2015. Way long before Runtimepermissions. It is btw one of the first Libs Johan published i think.
Also note that you can add the Permissions to the Librarys XML File so B4A can "see" them.
 
Last edited:

ivan.tellez

Active Member
Licensed User
Please note that @Johan Schoeman did wrote the Lib in 2015. Way long before Runtimepermissions. It is btw one of the first Libs Johan published i think.
Also note that you can add the Permissions to the Librarys XML File so B4A can "see" them.

Please note that Johan Schoeman wrote the last version of the Lib a couple days ago, targgeting SDK 26.
Also note that altought is posible to modify the Librarys XML or the apps manifest, being an active Library, Im just telling best practices to improve it.
 

Johan Schoeman

Expert
Licensed User
Please note that Johan Schoeman wrote the last version of the Lib a couple days ago, targgeting SDK 26.
Also note that altought is posible to modify the Librarys XML or the apps manifest, being an active Library, Im just telling best practices to improve it.
Try with JhsIceZxing1Ver1.06 that I have posted in post #1 of this thread - have added the permissions back to the library). It should show as V1.06 in the libs tab of the IDE

B4X:
@Permissions(values={"android.permission.CAMERA","android.hardware.camera","android.hardware.camera.autofocus","android.permission.VIBRATE","android.permission.FLASHLIGHT"})
 

ivan.tellez

Active Member
Licensed User
Great!

Now the lib is SDK 26 compatible and B4A 8+ Ready.

The permissions are added by the compliler again, That and the macro, you just need 1 line in the manifest (B4A 8+)

Congrats!

I think Im going to use this on a future release of my app. Ill let you now.


P.S. Consider removing the first line on post 1, coud mislead users.
 

Attachments

  • Permissions.png
    Permissions.png
    10.2 KB · Views: 135

Alvsky

Member
Licensed User
Hi,
great lib for my project but I ran into a UI problem which I can not solve.

Is it possible to add a CANCEL button to the scanner.
The only way to cancel the scan now is the system back button, but it is not so intuitive.
 

Christian García S.

Active Member
Licensed User
Hello,

Thanks for this great library, maybe you can help me with something.

I am trying to put the capture screen inside Tabstrip, when I clicked in button all is in full screen mode, can I put inside of some layout with other controls ???

I tried with remove in manifestor -> android:theme="@android:style/Theme.NoTitleBar.Fullscreen", but only keep bar on the top.

I need put control inside tab of tabstrip where is the button "Iniciar" like attached image.

Thanks for your help.

Christian
 

Attachments

  • qrcode.jpeg
    qrcode.jpeg
    59.6 KB · Views: 108

Johan Schoeman

Expert
Licensed User
The library is not wrapping a view. The UI is hard coded in the library. I have just added additional features to @icefairy333 original posting. Search the forum for a scanner that wraps a view that allows you to have "complete" control of the UI.
 

joe.dai

Member
Hello
i use JohanIcefairyZxing.zip sample test this great library
but i use <uses-sdk android:minSdkVersion =“ 5” android:targetSdkVersion =“ 26” /> is not work , not open scanner show Black screen
change JhsIceZxing1Ver1.06 library not work too

help me , thank you
 

Attachments

  • 111.png
    111.png
    83.6 KB · Views: 93
Last edited:

joe.dai

Member
That´s the wrong solution.

To upload the app on Playstore it is mandatory to define targetsdk (set to 28). I would start with adding the correct permissions and implement runtimepermissions.

Hello DonManfred

Can you guide me to add those permissions?
I am currently unable to solve such a problem
thank you very much
 
Top