B4A Library QR Droid Zapper

The request was raised here. Attached a shortcut wrap for this. Posting the following:
1. B4A library files - extract them from the zipped file and copy them to your additional libs folder
2. DemoRes.zip - extract the folder and then copy the folder with its contents to be on the same folder level as that of the B4A project's /Files and /Object folders
3. Sample B4A project

You will need an initial internet connection. When you start the B4A app it will prompt you to download QR Droid. Once downloaded you need to install the downloaded APK - check for the APK in your device's /Files/Download folder.

Once the APK has been installed you can disable your internet connection. Start the B4A app and click on the button "Start Scanner". The scanner should start up.

I have only done a shortcut wrap for the scanner. Not for anything else that QR Droid provides for.

Take note of the B4A manifest file!

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="5" android:targetSdkVersion="19"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.

AddApplicationText(<activity android:name="la.droid.qr.services.Services"
                  android:label="@string/app_name"
                  android:configChanges="keyboardHidden|orientation">

        </activity>
      
        <activity android:name="la.droid.qr.services.Scan"
                  android:label="@string/scan"
                  android:configChanges="keyboardHidden|orientation">

        </activity>
      
        <activity android:name="la.droid.qr.services.Encode"
                  android:label="@string/encode"
                  android:configChanges="keyboardHidden|orientation">

        </activity>
      
        <activity android:name="la.droid.qr.services.Decode"
                  android:label="@string/decode"
                  android:configChanges="keyboardHidden|orientation">

        </activity>)

I have not yet added any code to bring scanned results back to B4A (via event(s)) but can do so should anyone wish to make use of this.

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

#AdditionalRes: ..\DemoRes

#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 qrds As QrDroidService

    Private Button1 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")
  
    qrds.Initialize("")

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub Button1_Click
  
    qrds.startQrDroidService
  
End Sub
 

Attachments

  • b4aQrDroidService.zip
    8 KB · Views: 323
  • b4aLibFiles.zip
    16.9 KB · Views: 305
  • DemoRes.zip
    20.7 KB · Views: 281
Last edited:

akb

Member
Licensed User
Longtime User
Johan Schoeman, you are an absolute legend!
I followed your instructions and it works perfectly.
Is there any way to make it go straight to the camera when the button is pressed and then return the result straight back to the B4A app?
I need to get the number of button presses down to one - the B4A app's button only.
 

DonManfred

Expert
Licensed User
Longtime User
Is there any way to make it go straight to the camera when the button is pressed and then return the result straight back to the B4A app?
I don´t think so as this feature is not provided by the Intents QRDroid "understand"
If you want to make something "by one button" you need to build this solution by yourself.
The "Api" QrDroid provides is limited.

QRDroidZapper is just a wrap around the possible Intents QrDroid speaks. I don´t think Johan can do anything about this.
 

Johan Schoeman

Expert
Licensed User
Longtime User
Johan Schoeman, you are an absolute legend!
I followed your instructions and it works perfectly.
Is there any way to make it go straight to the camera when the button is pressed and then return the result straight back to the B4A app?
I need to get the number of button presses down to one - the B4A app's button only.
I think there is.....will see what I can figure out. Same approach as the Zxing (Icefairy project that I have modified) could probably work.
 

Johan Schoeman

Expert
Licensed User
Longtime User
Johan Schoeman, you are an absolute legend!
I followed your instructions and it works perfectly.
Is there any way to make it go straight to the camera when the button is pressed and then return the result straight back to the B4A app?
I need to get the number of button presses down to one - the B4A app's button only.
Try with the attached:
1. Extract and copy the B4A lib files to your additional libs folder.
2. Do the same with DemoRes.zip as what I have described in post #1 of this thread
3. Replace the B4A project with the attached B4A project
4. The B4A manifest (already in the new attached B4A project) stays as is i.e as in post #1

It will start the scanner immediately when the button in B4A is clicked. Upon a successful scan it will immediately return to B4A, raise an event in the B4A project and report the result of the scan in the B4A Log (i.e a String is returned to B4A):

B4X:
Sub qrds_scan_result(result As String)
   
    Log("In B4A and result = " & result)
   
End Sub

I need to figure out how to handle the back button when the scanner is active but a code has not been scanned....
 

Attachments

  • b4aQrDroidService.zip
    8 KB · Views: 285
  • b4aLibFiles.zip
    17.1 KB · Views: 275
  • DemoRes.zip
    20.7 KB · Views: 291

Johan Schoeman

Expert
Licensed User
Longtime User
Use the attached lib files with the B4A project in post #5. It will return to B4A when the back button is pressed (when the scanner is active) and no scan has occurred as yet.
 

Attachments

  • QrDroidService.xml
    1.1 KB · Views: 270
  • QrDroidService.jar
    18.6 KB · Views: 270
  • Like
Reactions: akb

akb

Member
Licensed User
Longtime User
You are a genius! I could never have worked that out by myself. This works perfectly!! Thank you so much.
 

akb

Member
Licensed User
Longtime User
I have integrated Johan's great QR Driod work into my project and all seemed to be working OK until I started field testing. What I found was that if I scanned numerous QRCodes one after the other then QRDroid would stop scanning. If I increase the wait time between scans then it would become more reliable. The trouble is that I need to scan as quickly as possible. I have tried setting the wait time between scans to one second and it might scan 30 or 40 QR codes before getting stuck again. I suspect what is happening is that the QrDroidService is occasionally being called again before the previous instance has fully completed. Is there some way to test if the previous call has finished before I call it again?

Hopefully the following code will make it clearer:
B4X:
#Region  Project Attributes
    #ApplicationLabel: b4aQrDroidService
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#AdditionalRes: ..\DemoRes

#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.
    Public TimerGetAnotherQRCode As Timer 'Turn this timer on the scan another QR Code

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 qrds As QrDroidService

    Private Button1 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")
    
    TimerGetAnotherQRCode.Initialize("TimerGetAnotherQRCode",1000)
    TimerGetAnotherQRCode.Enabled=False

    qrds.Initialize("qrds")

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub Button1_Click
    
    Log("Calling qrds.startQrDroidService")
    qrds.startQrDroidService
'    Log ("waiting for qrds.startQrDroidService...")
'    wait for qrds.startQrDroidService_Ready
'    Log("***************Out of qrds.startQrDroidService")
    
End Sub

Sub qrds_scan_result(result As String)
    
    'Msgbox("In B4A and result = " & result,"")
    Log("In B4A and result = " & result)
    
    'Scan next QR Code
    TimerGetAnotherQRCode.Enabled=True

End Sub

Sub TimerGetAnotherQRCode_Tick
    TimerGetAnotherQRCode.Enabled=False
    'qrds.startQrDroidService
    Button1_Click
End Sub

If I increase the timer on line 37 then the program becomes more reliable but too slow between scans.

If I decrease the timer on line 37 then the program becomes less reliable and the scanner stops working sooner. e.g. if I set it to 100ms then I will only get 1 or 2 scans before the scanning stops working.
 
Top