B4A Library FusedLocationProviderGMS (Latest)

This is a new FusedLocationProviderGMS library that is based on the latest version of Google Mobile Services (GMS). Unlike the old version of the FusedLocationProvider library, this version uses the FusedLocationProviderClient class in place of the deprecated FusedLocationProvider class. The FusedLocationProviderClient class is based on asynchronous methods, while the old version uses synchronized methods that are deprecated.

The principle of using the library is very similar to the older version, and the difference is that the result for each request to read the current location or the last known location is asynchronous and when the procedure is finished, the defined event will be fired. If you need a synchronized method, use the WaitFor command.

It is also necessary to add the following line to the manifest to be able to use GMS FusedLocation:
Add to Manifest:
AddApplicationText(<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />)

Example:
B4X:
Sub Process_Globals
    Dim Fused As FusedLocationProviderClient
End Sub

Sub DefineFused
    Fused.Initialize("Fused")
    Fused.GetLocationAvailability  'Determine if Location services are available
    Wait For Fused_LocationAvailabilityRequestCompleted (Available As Boolean)
        If Available Then
            Fused.GetLastLocation
            Wait For Fused_LocationRequestCompleted (Result As LocationResult)      
            If Result.Status=LocationResult.STATUS_SUCCESSFUL Then
                Dim Loc As LocationF = Result.Location
                Log(Loc.Latitude)
                'Do other things with result...
            Else
                Log(Result.ErrorMessage)
            End If
            Dim LocationRequest1 As LocationRequest
            LocationRequest1.Initialize(1000) 'Refresh interval is 1000 miliseconds
            LocationRequest1.SetMinUpdateIntervalMillis(100) 'Minimum refresh interval is 100 miliseconds
            LocationRequest1.SetPriority(Priority.PRIORITY_HIGH_ACCURACY) 'Request high accuracy location
            LocationRequest1.SetMinUpdateDistanceMeters(0) 'Minimum distance on wich will fire location change event
            LocationRequest1.SetGranularity(Granularity.GRANULARITY_FINE)
            Fused.RequestLocationUpdates(LocationRequest1) 'Set location request to FusedLocationProviderClient
        End If
End Sub

Sub Fused_LocationChanged(mLocation As LocationF)
    'LocationF is equivalent for Location in GPS library but with more methods and properties'
End Sub

If this libraries makes your work easier and saves time in creating your application, please make a donation.
 

Attachments

  • FusedLocationProviderGMS.zip
    21 KB · Views: 33
Last edited:

brunnlechner

Member
Licensed User
Longtime User
Hello,
thanks for the libary.
When I add the library to my project I get problems with external storage, do you have an explanation how this is possible?
If I uncheck FusedLocationProvid, external storage works perfectly.

Thanks very much
Franz

Error External Storage and FusedLocationProviderGMS library:
content://com.android.externalstorage.documents/tree/primary%3AGps%20(1)
Error occurred on line: 149 (ExternalStorage)
java.lang.ClassNotFoundException: androidx$documentfile$provider$DocumentFile
    at anywheresoftware.b4j.object.JavaObject.getCorrectClassName(JavaObject.java:289)
    at anywheresoftware.b4j.object.JavaObject.InitializeStatic(JavaObject.java:75)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4j.object.JavaObject$1.invoke(JavaObject.java:238)
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    at $Proxy2.ResultArrived(Unknown Source)
    at anywheresoftware.b4a.BA$4.run(BA.java:593)
    at anywheresoftware.b4a.BA.setActivityPaused(BA.java:467)
    at brunnlechner.gps.zeiterfassung.main$ResumeMessage.run(main.java:319)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7839)
 
Last edited:

Ivica Golubovic

Active Member
Licensed User
Hello,
thanks for the libary.
When I add the library to my project I get problems with external storage, do you have an explanation how this is possible?
If I uncheck FusedLocationProvid, external storage works perfectly.

Thanks very much
Franz

Error External Storage and FusedLocationProviderGMS library:
content://com.android.externalstorage.documents/tree/primary%3AGps%20(1)
Error occurred on line: 149 (ExternalStorage)
java.lang.ClassNotFoundException: androidx$documentfile$provider$DocumentFile
    at anywheresoftware.b4j.object.JavaObject.getCorrectClassName(JavaObject.java:289)
    at anywheresoftware.b4j.object.JavaObject.InitializeStatic(JavaObject.java:75)
    at brunnlechner.gps.zeiterfassung.externalstorage._getpickeddir(externalstorage.java:445)
    at brunnlechner.gps.zeiterfassung.externalstorage._setpickeddir(externalstorage.java:518)
    at brunnlechner.gps.zeiterfassung.externalstorage._ion_event(externalstorage.java:500)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4j.object.JavaObject$1.invoke(JavaObject.java:238)
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    at $Proxy2.ResultArrived(Unknown Source)
    at anywheresoftware.b4a.BA$4.run(BA.java:593)
    at anywheresoftware.b4a.BA.setActivityPaused(BA.java:467)
    at brunnlechner.gps.zeiterfassung.main$ResumeMessage.run(main.java:319)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7839)
Error:
java.lang.ClassNotFoundException: androidx$documentfile$provider$DocumentFile

From the line above it appears that a certain class from the androidx package is missing. I can't be sure why this happens when FusedLocation is activated. The FusedLocation library (wrapper) uses com.google.android.gms:play-services-location and does not use the AndroidX package (at least not directly in wrapper). Therefore, there is no close connection between the FusedLocation library and ExternaStorage, that is, the FusedLocation library does not use ExternalStorage in its work.

If you are able, it would be good if you could send me an example project so that I could try to find the connection between these two libraries.
 

amorosik

Expert
Licensed User
Does position reading using the FusedLocationProviderGMS library work even if the smartphone has the GPS service turned off?
 

carlos7000

Well-Known Member
Licensed User
Longtime User
Hello,

I wrote this code, and it wasn't difficult to make it work. However, even though it functions, I'm unsure if I did it correctly.

I have several doubts that I can't currently resolve on my own since I don't have B4A installed on this computer.

My doubts are as follows:

  1. Can I place this code in a Service? If so, how would I do it?
  2. Is it okay to place the DefineFused function in Activity_Resume? Or from where should I call the function?
  3. When the application goes into pause, should it be paused? Is it necessary to do so?
I appreciate any help you can provide to clarify these doubts.

Regards,


B4X:
#Region  Project Attributes
    #ApplicationLabel: GpsGsm Test
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
    #BridgeLogger: True
#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.
    Private xui As XUI
    
    Dim Fused As FusedLocationProviderClient
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    
    Dim A1 As LocationF
    
    Private LabelDistancia As Label
    Private LabelLat As Label
    Private LabelLon As Label
    Private LabelBearing As Label
    Private LabelBearingTo As Label
    Private LabelBearingAccuracyDegrees As Label
    Private LabelProvider As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Dim rp As RuntimePermissions
    
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    
    Activity.LoadLayout("Layout")
End Sub

Sub Activity_Resume
    A1.Initialize
    A1.Latitude = 4.703274
    A1.Longitude = -74.130271
    
    DefineFused

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub DefineFused
    Fused.Initialize("Fused")
    Fused.GetLocationAvailability  'Determine if Location services are available
    Wait For Fused_LocationAvailabilityRequestCompleted (Available As Boolean)
    If Available Then
        Fused.GetLastLocation
        Wait For Fused_LocationRequestCompleted (Result As LocationResult)
        If Result.Status=LocationResult.STATUS_SUCCESSFUL Then
            Dim Loc As LocationF = Result.Location
            Log(Loc.Latitude)
            'Do other things with result...
        Else
            Log(Result.ErrorMessage)
        End If
        Dim LocationRequest1 As LocationRequest
        LocationRequest1.Initialize(1000) 'Refresh interval is 1000 miliseconds
        LocationRequest1.SetMinUpdateIntervalMillis(100) 'Minimum refresh interval is 100 miliseconds
        LocationRequest1.SetPriority(Priority.PRIORITY_HIGH_ACCURACY) 'Request high accuracy location
        LocationRequest1.SetMinUpdateDistanceMeters(0) 'Minimum distance on wich will fire location change event
        LocationRequest1.SetGranularity(Granularity.GRANULARITY_FINE)
        Fused.RequestLocationUpdates(LocationRequest1) 'Set location request to FusedLocationProviderClient
    End If
End Sub

Sub Fused_LocationChanged(mLocation As LocationF)
    'LocationF is equivalent for Location in GPS library but with more methods and properties'

    LabelDistancia.Text = NumFormat6(mLocation.DistanceTo(A1), 0)

    LabelLat.Text = NumFormat6(mLocation.Latitude, 6)
    LabelLon.Text = NumFormat6(mLocation.Longitude, 6)
    LabelBearing.Text = mLocation.Bearing
    LabelBearingAccuracyDegrees.Text = mLocation.BearingAccuracyDegrees
    LabelBearingTo.Text = NumFormat6(mLocation.BearingTo(A1), 2)
    LabelProvider.Text = mLocation.Provider
End Sub

Sub NumFormat6(Num As Double, Decimales As Int) As String
    Return(NumberFormat2(Num, 1, Decimales, Decimales, False))
End Sub
 

Ivica Golubovic

Active Member
Licensed User
Hello,

I wrote this code, and it wasn't difficult to make it work. However, even though it functions, I'm unsure if I did it correctly.

I have several doubts that I can't currently resolve on my own since I don't have B4A installed on this computer.

My doubts are as follows:

  1. Can I place this code in a Service? If so, how would I do it?
  2. Is it okay to place the DefineFused function in Activity_Resume? Or from where should I call the function?
  3. When the application goes into pause, should it be paused? Is it necessary to do so?
I appreciate any help you can provide to clarify these doubts.

Regards,


B4X:
#Region  Project Attributes
    #ApplicationLabel: GpsGsm Test
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
    #BridgeLogger: True
#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.
    Private xui As XUI
  
    Dim Fused As FusedLocationProviderClient
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
  
    Dim A1 As LocationF
  
    Private LabelDistancia As Label
    Private LabelLat As Label
    Private LabelLon As Label
    Private LabelBearing As Label
    Private LabelBearingTo As Label
    Private LabelBearingAccuracyDegrees As Label
    Private LabelProvider As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Dim rp As RuntimePermissions
  
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
  
    Activity.LoadLayout("Layout")
End Sub

Sub Activity_Resume
    A1.Initialize
    A1.Latitude = 4.703274
    A1.Longitude = -74.130271
  
    DefineFused

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub DefineFused
    Fused.Initialize("Fused")
    Fused.GetLocationAvailability  'Determine if Location services are available
    Wait For Fused_LocationAvailabilityRequestCompleted (Available As Boolean)
    If Available Then
        Fused.GetLastLocation
        Wait For Fused_LocationRequestCompleted (Result As LocationResult)
        If Result.Status=LocationResult.STATUS_SUCCESSFUL Then
            Dim Loc As LocationF = Result.Location
            Log(Loc.Latitude)
            'Do other things with result...
        Else
            Log(Result.ErrorMessage)
        End If
        Dim LocationRequest1 As LocationRequest
        LocationRequest1.Initialize(1000) 'Refresh interval is 1000 miliseconds
        LocationRequest1.SetMinUpdateIntervalMillis(100) 'Minimum refresh interval is 100 miliseconds
        LocationRequest1.SetPriority(Priority.PRIORITY_HIGH_ACCURACY) 'Request high accuracy location
        LocationRequest1.SetMinUpdateDistanceMeters(0) 'Minimum distance on wich will fire location change event
        LocationRequest1.SetGranularity(Granularity.GRANULARITY_FINE)
        Fused.RequestLocationUpdates(LocationRequest1) 'Set location request to FusedLocationProviderClient
    End If
End Sub

Sub Fused_LocationChanged(mLocation As LocationF)
    'LocationF is equivalent for Location in GPS library but with more methods and properties'

    LabelDistancia.Text = NumFormat6(mLocation.DistanceTo(A1), 0)

    LabelLat.Text = NumFormat6(mLocation.Latitude, 6)
    LabelLon.Text = NumFormat6(mLocation.Longitude, 6)
    LabelBearing.Text = mLocation.Bearing
    LabelBearingAccuracyDegrees.Text = mLocation.BearingAccuracyDegrees
    LabelBearingTo.Text = NumFormat6(mLocation.BearingTo(A1), 2)
    LabelProvider.Text = mLocation.Provider
End Sub

Sub NumFormat6(Num As Double, Decimales As Int) As String
    Return(NumberFormat2(Num, 1, Decimales, Decimales, False))
End Sub
1. Of course it can be used in services, you call DefineFused in Service_Created. In that case, all events will be called in the Service. However, if your application does not require a background location, then it is not necessary to use the Service. In any case, FusedLocation uses the new thread regardless of whether it is initialized from Activity or Service.
2. It can be defined in Activity_Resume, but in that case it is necessary to put "If IsInitialized=False Then..." query so that a new instance is not initialized every time Resume is activated, which can cause problems.
3. If you do not need background location, then it is recommended to pause and start again when the application resumes.

And yes, a little tip, use B4XPages instead of Activities, don't waste your time and resources.
 
Last edited:

carlos7000

Well-Known Member
Licensed User
Longtime User
Could you change the name of the library from FusedLocationProvider to FusedLocationProviderGMS? The name of the file is FusedLocationProviderGMS, but in the library manager the name of FusedLocationProviderGMS is FusedLocationProvider, which leads to errors.

4857733.png


I guess the suggestion will be to remove the other library. Unfortunately, due to compatibility with other projects, some of us will have to continue using the FusedLocationProvider library, while little by little we update the projects that use the old library.

Why can't I see the version number?
 

Ivica Golubovic

Active Member
Licensed User
Could you change the name of the library from FusedLocationProvider to FusedLocationProviderGMS? The name of the file is FusedLocationProviderGMS, but in the library manager the name of FusedLocationProviderGMS is FusedLocationProvider, which leads to errors.

View attachment 143548

I guess the suggestion will be to remove the other library. Unfortunately, due to compatibility with other projects, some of us will have to continue using the FusedLocationProvider library, while little by little we update the projects that use the old library.

Why can't I see the version number?
FusedLocationProvider is an old library, FusedLocationProviderGMS is new and there is no interractions between them.

Also, there is no cinflict with classes in both libraries (i have both too)
 

carlos7000

Well-Known Member
Licensed User
Longtime User
FusedLocationProvider is an old library, FusedLocationProviderGMS is new and there is no interractions between them.

Also, there is no cinflict with classes in both libraries (i have both too)

I know that. What I request is because in the library manager, the two libraries have the same name.
 

Ivica Golubovic

Active Member
Licensed User
Because sometimes this message appears.

View attachment 143786
Yes, it will happen sometimes on some devices when it is not possible to determine the last known location. The problem can be solved with the "If Loc.IsInitialized" query.
I have seen that the FusedLocationProviderClient class has the SetMockLocation and SetMockMode functions or methods. Is it possible to use FusedLocationProviderClient to create a MockProvider application?
I don't know, I didn't test those methods, I just wrapped them.

Sorry for the late replies, I took a summer break for myself.
 
Top