B4A Library [B4X] Fused Location B4xLibrary

Hey everyone,

I created this B4X library to avoid the different implementations of GPS Locating in B4A and B4i.

In B4A it uses the FusedLocationProvider and in B4i it uses the iLocation Library. The code for the FusedLocationProvider in B4A is taken and changed slighly from this thread:




Implementation in B4A

1) Add the following code to the manifest
Manifest Code:
'Manifest
'=============================================================
'Fused Location Provider
'*************************************************************
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.ACCESS_COARSE_LOCATION)
AddApplicationText(<meta-data
    android:name="com.google.android.gms.version"
    android:value="[USER=21225]@Integer[/USER]/google_play_services_version" />)
'*************************************************************

Edit: [ USER=21225]@Integer[/USER ] is just "at" integer but it is changed automatically.



2) Add the following to the Main Activity
Main Activity Code:
'Main
'=============================================================
'*************************************************************
#AdditionalJar: com.android.support:support-v4
#AdditionalJar: com.google.android.gms:play-services-location
'*************************************************************

Sub Process_Globals
    Dim rp as RuntimePermissions
    Dim fl As FusedLocation
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("Layout1")
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    wait for Activity_PermissionResult(Permission As String, Result As Boolean)
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_COARSE_LOCATION)
    wait for Activity_PermissionResult(Permission As String, Result As Boolean)

    If Result = False Then Activity.Finish

    fl.Initialize("fl", Me)
    fl.StartFLP
End Sub

Public Sub fl_LocationChanged(Location1 As Location)
    Log(Location1.Latitude & "," &  Location1.Longitude)
    fl.StopFLP
End Sub


Implementation in B4i

Add the following to Module Main

Code in Module Main:
'Main
'=============================================================
'*************************************************************
#PlistExtra:<key>NSLocationWhenInUseUsageDescription</key><string>This application is used to display the current navigation data.</string>
#PlistExtra:<key>NSLocationUsageDescription</key><string>This application is used to display the current navigation data.</string>
'*************************************************************
Sub Process_Globals

    Dim fl As FusedLocation
End Sub

Private Sub Application_Start (Nav As NavigationController)
    'SetDebugAutoFlushLogs(True) 'Uncomment if program crashes before all logs are printed.
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
    fl.Initialize("fl", Me)
    fl.StartFLP
End Sub

Public Sub fl_LocationChanged(Location1 As Location)
    Log(Location1.Latitude & "," &  Location1.Longitude)
    fl.StopFLP
End Sub
 

Attachments

  • NHFusedLocation.b4xlib
    1.3 KB · Views: 137
Last edited:

iz0ndg

Active Member
Licensed User
Longtime User
I have an error (In library folder fusedlocationprovider : 1.31)

in the manifest I put :
B4X:
'Manifest
'=============================================================
'Fused Location Provider
'*************************************************************
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.ACCESS_COARSE_LOCATION)
AddApplicationText(<meta-data
    android:name="com.google.android.gms.version"
    android:value="[USER=21225]@Integer[/USER]/google_play_services_version" />)
'*************************************************************

B4X:
Logger connesso a: XEDDU18112008657
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue (activity_permissionresult)
running waiting messages (1)
** Activity (main) Resume **
--------- beginning of crash
java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist.  You must have the following declaration within the <application> element:     <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
    at com.google.android.gms.common.GooglePlayServicesUtilLight.isGooglePlayServicesAvailable(com.google.android.gms:play-services-basement@@17.2.1:17)
    at com.google.android.gms.common.GoogleApiAvailabilityLight.isGooglePlayServicesAvailable(com.google.android.gms:play-services-basement@@17.2.1:4)
    at com.google.android.gms.common.GoogleApiAvailability.isGooglePlayServicesAvailable(com.google.android.gms:play-services-base@@17.2.1:96)
    at com.google.android.gms.common.internal.GoogleApiAvailabilityCache.getClientAvailability(com.google.android.gms:play-services-base@@17.2.1:23)
    at com.google.android.gms.common.api.internal.zaan.zaak(com.google.android.gms:play-services-base@@17.2.1:19)
    at com.google.android.gms.common.api.internal.zaas.run(com.google.android.gms:play-services-base@@17.2.1:6)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at com.google.android.gms.common.util.concurrent.zza.run(com.google.android.gms:play-services-basement@@17.2.1:6)
    at java.lang.Thread.run(Thread.java:784)
 

hatzisn

Well-Known Member
Licensed User
Longtime User
I have an error (In library folder fusedlocationprovider : 1.31)

in the manifest I put :
B4X:
'Manifest
'=============================================================
'Fused Location Provider
'*************************************************************
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.ACCESS_COARSE_LOCATION)
AddApplicationText(<meta-data
    android:name="com.google.android.gms.version"
    android:value="[USER=21225]@Integer[/USER]/google_play_services_version" />)
'*************************************************************

B4X:
Logger connesso a: XEDDU18112008657
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
sending message to waiting queue (activity_permissionresult)
running waiting messages (1)
** Activity (main) Resume **
--------- beginning of crash
java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist.  You must have the following declaration within the <application> element:     <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
    at com.google.android.gms.common.GooglePlayServicesUtilLight.isGooglePlayServicesAvailable(com.google.android.gms:play-services-basement@@17.2.1:17)
    at com.google.android.gms.common.GoogleApiAvailabilityLight.isGooglePlayServicesAvailable(com.google.android.gms:play-services-basement@@17.2.1:4)
    at com.google.android.gms.common.GoogleApiAvailability.isGooglePlayServicesAvailable(com.google.android.gms:play-services-base@@17.2.1:96)
    at com.google.android.gms.common.internal.GoogleApiAvailabilityCache.getClientAvailability(com.google.android.gms:play-services-base@@17.2.1:23)
    at com.google.android.gms.common.api.internal.zaan.zaak(com.google.android.gms:play-services-base@@17.2.1:19)
    at com.google.android.gms.common.api.internal.zaas.run(com.google.android.gms:play-services-base@@17.2.1:6)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at com.google.android.gms.common.util.concurrent.zza.run(com.google.android.gms:play-services-basement@@17.2.1:6)
    at java.lang.Thread.run(Thread.java:784)


Have you removed the [ USER=21225 ] and [ /USER ] and leave just the ' "at" Integer '?
 
Last edited:

iz0ndg

Active Member
Licensed User
Longtime User
Have you removed the [ USER=21225 ] and [ /USER ] and leave just the ' "at" Integer '?
In this case in compilation Windows I have:
B4X:
B4A Versione: 9.80
Java Versione: 11
Analisi del Codice.    (0.00s)
Building folders structure.    (0.02s)
Compilazione del codice.    (0.04s)
Compilazione del codice di layouts    (0.00s)
Organizzazione Librerie.    (0.00s)
    (AndroidX SDK)
Generazione file R.    (0.00s)
Compilazione del codice Java prodotto.    (0.02s)
Conversione byte code - ottimizzazione dex.    (1.95s)
Packaging files.    Error
AndroidManifest.xml:22: error: Error: No resource found that matches the given name (at 'value' with value '@Integer/google_play_services_version').

AAPT path: C:\android\tools\..\build-tools\29.0.1\aapt.exe
Exit code:1
 

hatzisn

Well-Known Member
Licensed User
Longtime User
Open the SDK manager and update the android SDK. Further more change in the configure paths the path to android.jar of the latest android version Android-29
 

iz0ndg

Active Member
Licensed User
Longtime User
I replaced the lines with:
B4X:
'=============================================================
'Fused Location Provider
'*************************************************************
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.ACCESS_COARSE_LOCATION)
'AddApplicationText(<meta-data
'    android:name="com.google.android.gms.version"
'    android:value="@Integer/google_play_services_version" />)
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)
'*************************************************************

In this mode (from another example for FusedLocationProvider) is OK
 

iz0ndg

Active Member
Licensed User
Longtime User
Open the SDK manager and update the android SDK. Further more change in the configure paths the path to android.jar of the latest android version Android-29
The SDK is updated and path for Version of Android is 29
 

hatzisn

Well-Known Member
Licensed User
Longtime User
An update to NHFusedLocation library has been posted in the 1st message.

These are the changes:
B4X:
'It is initialized like this
flp.Initialize("fl", Me)

'And this event is raised
Private Sub fl_LocationChanged(Location1 As Location)

End Sub

'You can change the parent object also
'Usage case you Initialize the NHFusedLocation in Starter
'and in Main you set the following to raise the event above
'in Main
flp.Parent = Me
 

fbritop

Active Member
Licensed User
Longtime User
An improvement that could be attached:

B4X:
Public Sub isAuthorized As Boolean
    #if b4i
    Return FLP.IsAuthorized
    #else if b4a
    Dim rp as RuntimePermissions
    Return rp.Check(rp.PERMISSION_ACCESS_FINE_LOCATION) 
    #end if
End Sub
 
Last edited:
Top