B4A Library QRCodeReaderView - QR Code Scanner that is also 100% embedded in B4A (new B4A lib files in post #8)

Here is another scanner that is 100% embedded in B4A. It wraps this Github project and will only scan QR Codes (it uses the ZXING engine for decoding scanned QR Codes). It will keep on reading QR codes for as long as what it finds a valid QR code. It is quite a "speedy" scanner. It does not require any other barcode scanner app to be installed on your device - it is 100% standalone. You can customize your B4A activity / UI by adding buttons, labels, panels, images, etc etc and change colors to your liking - 100% B4A customizable.

Note that a panel is the parent of the custom view but seeing that the original project extends Surface View it will punch a hole in the panel when the scanner starts.

Also note the permissions in the B4A project's manifest file (I know majority are redundant for this project).

You will have to handle consecutive / continuous scans of the same QR code within your B4A code.

Posting the following:
1. B4A project
2. B4A library files (3 x jar and 1 x xml) - copy them to your additional library folder.

EDIT: UPDATED LIBRARY FILES IN POST #6 THAT WILL NOT RAISE AN EVENT IN B4A IF TWO CONSECUTIVE SCANS OF THE SAME QR CODE OCCURS

1.png



Scanner.png



2.png


Some sample code:

B4X:
Region  Project Attributes
    #ApplicationLabel: QRCodeReaderView
    #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 qrcrv As QRCodeReaderView

    Private b1 As Button
    Private b2 As Button
    Private p1 As Panel
    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")

    qrcrv.Visible = False


End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub b1_Click


    qrcrv.Visible = True
    DoEvents
    qrcrv.startScan

End Sub
Sub b2_Click

    qrcrv.stopScan
    DoEvents
    qrcrv.Visible = False

End Sub

Sub qrcrv_result_found(retval As String)

    Log("B4A: " & retval)
    l1.Text = retval

End Sub


The library:

QRCodeReaderView
Author:
Github: David L\u00e1zaro, Wrapped by: Johan Schoeman
Version: 1
QRCodeReaderView
Events:

  • result_found (retval 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)
  • startScan
  • stopScan
Properties:
  • Background As Drawable
  • Color As Int [write only]
  • Enabled As Boolean
  • Height As Int
  • Left As Int
  • 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

  • QRCodeReaderViewLibFiles.zip
    498.1 KB · Views: 3,257
  • b4aQRCodeReaderView.zip
    8.9 KB · Views: 2,831
Last edited:

Douglas Farias

Expert
Licensed User
Longtime User
hi @Johan Schoeman
i m making some tests with this lib.

i have a problem when i use 2 activitys

one the first activity i have use a camex class to take a selfie, and on the second activity i want to use your lib to scan some qr codes.

the problem is this

** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
** Service (starter) Start **
** Activity (main) Pause, UserClosed = false **
** Activity (completacadastro) Create, isFirst = true **
** Activity (completacadastro) Resume **
** Activity (completacadastro) Pause, UserClosed = true **
** Activity (timeline) Create, isFirst = true **
** Activity (timeline) Resume **
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:565)
at android.hardware.Camera.open(Camera.java:405)
at com.google.zxing.client.android.camera.open.GingerbreadOpenCameraInterface.open(GingerbreadOpenCameraInterface.java:58)
at com.google.zxing.client.android.camera.open.CameraManager.openDriver(CameraManager.java:81)
at com.dlazaro66.qrcodereaderview.QRCodeReaderView.surfaceCreated(QRCodeReaderView.java:165)
at android.view.SurfaceView.updateWindow(SurfaceView.java:709)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:208)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1018)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2308)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1301)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7016)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
at android.view.Choreographer.doCallbacks(Choreographer.java:590)
at android.view.Choreographer.doFrame(Choreographer.java:560)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6946)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

i m calling the camex.release, i really dont know why the errors continue

you know how solve this?
this erros show when i open the activity with your lib.

thx
 

Johan Schoeman

Expert
Licensed User
Longtime User
In CameraEx - try and use
B4X:
camEx.CloseNow

and not...
B4X:
camEx.Release

...before starting the QR Code activity. Have tried it and it works.

Try with the attached library files and sample project.
 

Attachments

  • QRCodeReaderViewLibFiles18012017.zip
    32.4 KB · Views: 399
  • b4aCameraExQRReaderView.zip
    12.4 KB · Views: 381
Last edited:

rbghongade

Active Member
Licensed User
Longtime User
Dear friends,
Is it possible to wrap a similar library for B4J to be used with Raspberry pi?
 

luke2012

Well-Known Member
Licensed User
Longtime User
Hi All,
I'm new to QR codes :)
This QR code library allow to read all the data associated to any kind of QR codes?

My users need is to "save" the QRCODE (related to a specific product like pc or smartphone) within a database.
So the user can scan the QR code and I can got an alfanumeric unique code associated with the QR code and save it to the db ?
 

DonManfred

Expert
Licensed User
Longtime User
This QR code library allow to read all the data associated to any kind of QR codes?
It just "scans the QR-Code and returns the content as String.
That´s it. It is up to you to save this code to your database, do online-search using okhttputils or whatever you want to do with the scanned String.
 

luke2012

Well-Known Member
Licensed User
Longtime User
It just "scans the QR-Code and returns the content as String.
That´s it. It is up to you to save this code to your database, do online-search using okhttputils or whatever you want to do with the scanned String.

Thanks for your reply @DonManfred :)
Is there a B4i version of this library ?
 

Johan Schoeman

Expert
Licensed User
Longtime User
This is an update of the library based on the request that was posted here. Have added a method to the library
B4X:
    private boolean scannow = false;
    public void setScanNow(boolean scannow) {
        this.scannow = scannow;
    }

Call from B4A:
B4X:
qrcrv.ScanNow = True

See the attached sample project. I have removed the tone generator from the library and have added it via inline Java code. Have also added a checkbox that will set the boolean variable in the wrapper in order to scan / not scan. How you use it is up to you to allow / disallow the scan result to be returned via the event.

Posting:
1. Sample project
2. B4A library files

Sample code:
B4X:
#Region  Project Attributes
    #ApplicationLabel: QRCodeReaderView
    #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.
   
    Dim nativeMe As JavaObject

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 qrcrv As QRCodeReaderView
   
   
    Private b1 As Button
    Private b2 As Button
    Private p1 As Panel
    Private l1 As Label
    Private oldString As String = ""
   
    Private b3 As Button
   

    Private cb1 As CheckBox
   
   
   
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")
    nativeMe.InitializeContext
   
   
    qrcrv.Visible = False

    'Keep the order of the next 4 lines. CAMERA_BACK and CAMERA_FRONT will only contain correct values once qrcrv.BackFacingCamera and qrcrv.FrontFacingCamera has
    'been executed else they will have default values of -1
    Log(qrcrv.BackFacingCamera)    'see the popup help when entering this method - check if there is a back facing camera and return the ID of the camera
    Log(qrcrv.FrontFacingCamera)   'see the popup help when entering this method - check if there is a front facing camera and retutn the ID of the camera
   
    Log(qrcrv.CAMERA_BACK)         'see the popup help when entering this method
    Log(qrcrv.CAMERA_FRONT)           'see the popup help when entering this method
   
    'now you can use
    qrcrv.CameraId = qrcrv.CAMERA_BACK   'or qrcrv.CameraId = qrcrv.CAMERA_FRONT
   
    'qrcrv.CameraDegrees = 270  'set this to 0, 90, 180, 270
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub b1_Click
   

    qrcrv.Visible = True
    DoEvents
    qrcrv.startScan
     
End Sub

Sub b2_Click
   
    qrcrv.stopScan
    DoEvents
    qrcrv.Visible = False


End Sub

Sub qrcrv_result_found(retval As String)
    If oldString <> retval Then
      oldString = retval
      Log("B4A: " & oldString)
      l1.Text = oldString   
      nativeMe.RunMethod("playTone", Null)
     
    End If
   
End Sub

Sub b3_Click
   
    If (qrcrv.isFlashOn = True) Then
      qrcrv.setFlashOff
    Else
      qrcrv.setFlashOn
    End If 
   
End Sub

Sub cb1_CheckedChange(Checked As Boolean)
   
    If cb1.Checked = True Then
        qrcrv.ScanNow = True
    Else
        qrcrv.ScanNow = False
    End If
   
End Sub

#if Java

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

You will also need the JavaObject library (internal library) to be enabled for the inline Java code to work.


Checkbox not set and no scan result will be returned
1.png



Checkbox set and scanned result will be returned to the B4A app via the event that will be raised
2.png
 

Attachments

  • b4aQRCodeReaderView.zip
    10.3 KB · Views: 352
  • b4aLibFiles.zip
    32.2 KB · Views: 378

Johan Schoeman

Expert
Licensed User
Longtime User
Can I have too.... please
Just uncomment this line in my last post and see what degrees setting works for you.

'qrcrv.CameraDegrees = 270 'set this to 0, 90, 180, 270
 

Tareq Khan

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

Private qrcrv As QRCodeReaderView

Private b1 As Button
Private b2 As Button
Private p1 As Panel
Private l1 As Label
End Sub

Hello everyone,

It's showing as "undeclared variable 'qrcrv' is used before assigned any value".
 

Johan Schoeman

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

Private qrcrv As QRCodeReaderView

Private b1 As Button
Private b2 As Button
Private p1 As Panel
Private l1 As Label
End Sub

Hello everyone,

It's showing as "undeclared variable 'qrcrv' is used before assigned any value".
Is the message appearing when you use my original project or your own project that you have started from scratch?
 

rkmoray

Active Member
Licensed User
Longtime User
I have changed my qr lib from zx to this library.
Everything seemed to go great, but when I start the scanner,I get the following error.
Since the scanner worked with the previous library, I don't think permissions i the issue
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:519)
at android.hardware.Camera.open(Camera.java:364)
at com.google.zxing.client.android.camera.open.GingerbreadOpenCameraInterface.open(GingerbreadOpenCameraInterface.java:58)
at com.google.zxing.client.android.camera.open.CameraManager.openDriver(CameraManager.java:81)
at com.dlazaro66.qrcodereaderview.QRCodeReaderView.surfaceCreated(QRCodeReaderView.java:165)
at android.view.SurfaceView.updateWindow(SurfaceView.java:656)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:172)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1013)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2555)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1550)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7189)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)
at android.view.Choreographer.doCallbacks(Choreographer.java:734)
at android.view.Choreographer.doFrame(Choreographer.java:670)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
 

rkmoray

Active Member
Licensed User
Longtime User
An update to my previous post regarding unable to connect to camera.
When I changed the "android:targetSdkVersion" setting in the manifest from 26 to 17 (I have not tried other versions) that solved my issue.
 

Johan Schoeman

Expert
Licensed User
Longtime User
An update to my previous post regarding unable to connect to camera.
When I changed the "android:targetSdkVersion" setting in the manifest from 26 to 17 (I have not tried other versions) that solved my issue.
Yes, I have noticed it the other day. Seems like it is happy if you set the targetSDKVersion up to 22.
 

biometrics

Active Member
Licensed User
Longtime User
If you target SDK 26 in your manifest (think I had to for Google Maps) then add the RuntimePermissions library and add this to your code:

B4X:
Sub Process_Globals
   Private libRuntimePermissions As RuntimePermissions
End Sub

Sub Activity_Create(FirstTime As Boolean)
   libRuntimePermissions.CheckAndRequest(libRuntimePermissions.PERMISSION_CAMERA)
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
End Sub
 

Beja

Expert
Licensed User
Longtime User
Thanks for this wonderful and extremely useful library.
I don't know why the prevention of duplicate scanning..in typical use many people would scan the same item a number of
times.. e.g. if a store customer bought 3 or more pieces of the same item with the same qrcode or barcode. cashiers
do not calculate, they simply scan multiple times.
 
Top