B4A Library FusedLocationProvider

FusedLocationProvider is Android's latest attempt to improve the location services available to your applications.

Official documentation can be found here: https://developer.android.com/google/play-services/location.html.

This library depends on the Google Play Services library, android-support-v4 library and the GPS library.
The GPS library is required in order to use it's Location object.

FusedLocationProvider
Events:

  • ConnectionFailed (ConnectionResult1 As Int)
  • ConnectionSuccess
  • ConnectionSuspended (SuspendedCause1 As Int)
  • LocationChanged (Location1 As Location)
  • LocationSettingsChecked (LocationSettingsResult1 As LocationSettingsResult)
Fields:
  • ConnectionResult As ConnectionResult
    Contains the various ConnectionResult constants.
  • SuspendedCause As SuspendedCause
    Contains the various SuspendedCause constants.
Methods:
  • CheckLocationSettings (LocationSettingsRequest1 As LocationSettingsRequest)
    Checks if the relevant system settings are enabled on the device to carry out the desired location requests.
    Raises the event:
    LocationSettingsChecked(LocationSettingsResult1 As LocationSettingsResult)
  • Connect
    Attempt to connect to the Location Services.
    Will raise either event:
    ConnectionFailed(ConnectionResult1 As Int)
    ConnectionSuccess
  • Disconnect
    Disconnect from the Location Services.
  • GetLastKnownLocation As Location
    Returns the best most recent location currently available.
    Can only be called if the FusedLocationProvider is connected.
    The returned Location object will not be initialized if no last known location is available.
  • Initialize (EventName As String)
    Initialize the FusedLocationProvider object.
  • IsConnected As Boolean
    Returns whether the FusedLocationProvider is connected to the Location Services.
  • IsConnecting As Boolean
    Returns whether the FusedLocationProvider is trying to connect to the Location Services.
  • IsInitialized As Boolean
  • RemoveLocationUpdates
    Remove all requests for location updates.
  • RequestLocationUpdates (LocationRequest1 As LocationRequest)
    Request for location updates.
    The LocationRequest object defines the criteria for which location updates are requested.

This is the main library object.
You call the FusedLocationProvider Initialize method and then it's Connect method.
It will then raise the ConnectionFailed event or the ConnectionSuccess event.
Assuming the ConnectionSuccess event is raised you can now call:
  • GetLastKnownLocation As Location
  • RequestLocationUpdates (LocationRequest1 As LocationRequest)

So you could connect, get the last known location and then disconnect.
There is no requirement to request location updates.
This is a quick and simple way to get the device location.

Or you could connect then initialize and configure a LocationRequest object and then request location updates.
The LocationRequest object has various methods you can call to configure the request for location updates:

LocationRequest
Fields:

  • Priority As Priority
    Contains the various priority constants.
Methods:
  • GetExpirationTime As Long
    Get the request expiration time, in milliseconds since boot.
  • GetFastestInterval As Long
    Get the fastest interval of this request, in milliseconds.
  • GetInterval As Long
    Get the desired interval of this request, in milliseconds.
  • GetNumUpdates As Int
    Get the number of updates requested.
  • GetPriority As Int
    Get the quality of the request.
  • GetSmallestDisplacement As Float
    Get the minimum displacement between location updates in meters.
    By default this is 0.
  • Initialize
    Initialize the LocationRequest with default parameters.
    Default parameters are for a block accuracy, slowly updated location.
  • IsInitialized As Boolean
  • SetExpirationDuration (Millis As Long) As LocationRequest
    Set the duration of this request, in milliseconds.
  • SetExpirationTime (Millis As Long) As LocationRequest
    Set the request expiration time, in millisecond since boot.
  • SetFastestInterval (Millis As Long) As LocationRequest
    Explicitly set the fastest interval for location updates, in milliseconds.
  • SetInterval (Millis As Long) As LocationRequest
    Set the desired interval for active location updates, in milliseconds.
  • SetNumUpdates (NumUpdates As Int) As LocationRequest
    Set the number of location updates.
  • SetPriority (Priority As Int) As LocationRequest
    Set the priority of the request.
  • SetSmallestDisplacement (SmallestDisplacementMeters As Float) As LocationRequest
    Set the minimum displacement between location updates in meters.
    By default this is 0.

It is important to note that part of the criteria that defines your request for a location is the location permission that you (manually) set in the manifest file.
This library does not automatically add any permission to your manifest and this library will fail to work if you do not manually add a required permission to your manifest file.

You can add one of two permissions to your manifest:
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_COARSE_LOCATION

See: https://developer.android.com/training/location/retrieve-current.html
Apps that use location services must request location permissions.
Android offers two location permissions: ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION.
The permission you choose determines the accuracy of the location returned by the API.
If you specify ACCESS_COARSE_LOCATION, the API returns a location with an accuracy approximately equivalent to a city block.

Also note that as this library uses the Google Play Services library, you must also add this entry to your manifest:

B4X:
AddApplicationText(<meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />)

Two versions of the library are attached.
  • If you're using a version of Google Play Services older than version 27 then you need to use FusedLocationProvider version 1.10.
  • If you're using Google Play Services version 27 or newer then you need to use FusedLocationProvider version 1.30 or newer

Martin.

Edit by Erel:
Add these two lines if using with B4A v6+:
B4X:
#AdditionalJar: com.android.support:support-v4
#AdditionalJar: com.google.android.gms:play-services-location
New example where FLP is managed from the starter service: https://www.b4x.com/android/forum/threads/fusedlocationprovider.50614/post-717726
 

Attachments

  • FusedLocationProvider_library_files_v1.10.zip
    19.3 KB · Views: 2,040
  • FusedLocationProvider_library_files_v1.31.zip
    20 KB · Views: 3,062
Last edited by a moderator:

hibrid0

Active Member
Licensed User
Longtime User
@imbault

Something must have changed within the Google Play Services library and it now depends on the android-support-v4 library.
To be more precise the GoogleApiClient.Builder class seems to depend on it.

The existing demo projects fail to run on my Moto G (lollipop) giving the same error as you posted:



Here's a solution:

B4X:
#Region  Project Attributes
    #ApplicationLabel: FusedLocationProvider example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
    #AdditionalRes: C:\Users\martin\AppData\Local\Android\sdk\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
    #AdditionalJar: android-support-v4.jar
#End Region

See where i have added the line #AdditionalJar: android-support-v4.jar?
That seems to be all that is required.

You must have the android-support-v4.jar file in your b4a additional libraries folder - and it'd be a good idea to ensure that it's the latest version of the v4 support library.
You can do that by running the android SDK manager, ensuring that everything is up to date and then copying android-support-v4.jar from the SDK folder to your b4a additional libraries folder.
The v4 support library .jar is located at <Android SDK Path Here>\extras\android\support\v4

Try that and post with your results.


I solved my problem with that's line!!
My problem was the demo not get the LAT or LON on Lenovo Tablet with Android 4.2.2, and demo working fine on my FirePhone.

Thanks a lot.
 

encolo

Member
Licensed User
Longtime User
I have this error ???

B4A line: 48
LocationSettingsRequestBuilder1.AddLocationRequest(LocationRequest1)
javac 1.7.0_21
src\uk\co\martinpearman\b4a\fusedlocationproviderexample\locationmonitor.java:129: error: package com.google.android.gms.location does not exist
_locationsettingsrequestbuilder1.AddLocationRequest((com.google.android.gms.location.LocationRequest)(_locationrequest1.getObject()));
 

encolo

Member
Licensed User
Longtime User
I have include this line

#AdditionalRes: L:\Android\sdk\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
#AdditionalJar: android-support-v4.jar

which library ???
 

Harris

Expert
Licensed User
Longtime User
FusedLocationProvider (as in first post)

B4X:
Sub Process_Globals
     Public FusedLocationProvider1 As FusedLocationProvider
 

Pcbeta Rabbit

Member
Licensed User
Longtime User
I have include this line

#AdditionalRes: L:\Android\sdk\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
#AdditionalJar: android-support-v4.jar

which library ???
copy your google-play-services.jar to B4A Libraries from your sdk Folder\extras\google\google_play_services\libproject\google-play-services_lib\libs
 

encolo

Member
Licensed User
Longtime User
Now i have another problem......

during compilation

B4A version: 5.50
Parsing code. (0.02s)
Compiling code. (0.80s)
Compiling layouts code. (0.03s)
Generating R file. (0.55s)
Compiling generated Java code. (1.22s)
Convert byte code - optimized dex. Error
Process timed out.
You can change the timeout value under Tools - IDE Options.


i try increase the def value to 40 but i'm not sure is the right way
 

hibrid0

Active Member
Licensed User
Longtime User
You will change to 120, projects with the Google library take time compile.
But in the first full compilation in the next compilations is too fast.
 

opus

Active Member
Licensed User
Longtime User
WTH
I just installed version 1.3 into the additional libraries folder, as well as the android-support-v4.jar and the google-play-services.jar.
When loading the fusedlocation lib into the project, my system starts the run on on 90+% mainly on the process of Java.exe resulting in a system-shutdown!
I can stop that by deselecting the lib. "Tested" that scenario now four consecutuve times!
Note: I do not compile or whatsoever, I do not run any other stuff in the background.

What is going on?
 

Daniel-White

Active Member
Licensed User
Longtime User
Hi, awesome Lib, I tested with PRIORITY_BALANCED_POWER_ACCURACY - and it is working so great. I am really impress.

I have a question for you guys, My Understanding the LocationAPI library is deprecated, and in the forums WarWound have some examples about GeoFence but with LocationAPI.

My question here is, have we Geofence in FusedlocationProvider library?
 

marcick

Well-Known Member
Licensed User
Longtime User
Hi Martin, sorry if the question sounds stupid but: which are the advantages using FuseLocation instead of the internal GPS to obtain the position ?
 

warwound

Expert
Licensed User
Longtime User
FusedLocationProvider aims to unite all 'location discovery' services into a single API.
It can get a device location using GPS hardware and/or network (wireless and cellular).

It also aims to unite all location requests on the device:
If more than one app uses FusedLocationProvider to request location then all apps receive all location updates obtained from FusedLocationProvider.
For example if you start the official android Maps app and let it get your location and then a different app uses FusedLocationProvider to request a location then that location already obtained by Maps is available to the different app.
Think of it as a 'location cache' shared by all apps that use FusedLocationProvider.
That should reduce battery and CPU usage as the device.

If another 2 different apps use the 'old fashioned' GPS library to request a location then the device will start up the hardware GPS and wait for a location fix twice - performing the same location discovery task twice instead of performing the task once and sharing the result with each app.

FusedLocationProvider does have one possible disadvantage - it relies on the Google Play Services library so inevitably bloats your .apk with a bunch of unused features.
Read more about Google Play Services bloat here:
https://www.b4x.com/android/forum/t...-google-play-apis-into-b4a-application.61537/
 

marcick

Well-Known Member
Licensed User
Longtime User
Thanks.
If I'm just interested to have better accuracy (for this I'm actually thinking to connect my app to an external bluetooth GPS) will I have benefits using FusedLocation ?
Is the internal GPS a pure hardware or does it already use some aids from the network ?
 

warwound

Expert
Licensed User
Longtime User
First - have you checked that an external bluetooth GPS device is supported by both the standard GPS library and FusedLocationProvider?

Assuming that it is supported then i'm not sure whether FusedLocationProvider will offer any advantages...
If android doesn't unite all location requests from FusedLocationProvider to the external GPS device then that's one advantage gone.
If you're only interested in high accuracy fixes then you won't be interested in any network locations returned by FusedLocationProvider so that's another advantage gone.

Is the internal GPS a pure hardware or does it already use some aids from the network ?
I don't think the internal GPS hardware uses any network assistance - that is done in software if it's done at all.
The GPS hardware should make use of any up to date aGPS data that is available - and so should any external GPS device.

All in all i don't think you'll gain anything by using FusedLocationProvider with an external GPS device when you're only interested in high accuracy fixes.
 

marcick

Well-Known Member
Licensed User
Longtime User
I didn't put the question correctly:

I'm using now the standard GPS library. To improve accuracy I was thinking to manage an external bluetooth GPS receiver that for sure has a powerful big antenna respect to the internal one of the device.
Than I falled inside this interesting thread.
So, before working on the code to manage the external GPS, I was wondering if trying use FuseLocation would improve the accuracy of the location obtained by the GPS library with internal GPS ......
 

Daniel-White

Active Member
Licensed User
Longtime User
mmm, I will share some labs I did, perhaps can help to make a decision when to use which lib, using only geo location using the cells towers, with PRIORITY_BALANCED_POWER_ACCURACY in fused lib, the accuracy is 4 blocks in the google map perhaps + or - 100 mts I did not mesure it, for me that is enough, because, if I need more, I can send a SMS to the mobile and ask to turn on the GPS and return 1 mts of accuracy and turn off the GPS later few seconds later , now, my interest is save battery life, when I used other GPS libraries or Fused library with high accuracy all the time , GPS is turned on 100%, the life battery drop drastically. Fused library is really amazing, I have one very small phone (special for stress my APPS), samsung Pocket, one CPU, soooooooooo slowly to run any APP, and it show the normal GPS or High accuracy eat 22% of battery, with Fused lib, It only used less of 1% and I think perhaps Skype eat more battery. my APP ask each 2 minutes the LAT and Long for both test. And the Geo fence work excellent. :) Thanks.
 
Last edited:

warwound

Expert
Licensed User
Longtime User
So, before working on the code to manage the external GPS, I was wondering if trying use FuseLocation would improve the accuracy of the location obtained by the GPS library with internal GPS ......

You can try the FusedLocationProvider with internal GPS but i doubt if you'll see any improvement in accuracy.
Better battery and cpu usage yes but no better location accuracy.
 

marcick

Well-Known Member
Licensed User
Longtime User
Looking in "Settings-Privacy and safety-Location-Locating method" on my Lollipop device (Galaxy s6) I see 3 choiches:

1) GPS, Wi-Fi, and mobile networks
2) Wi-Fi and mobile networks
3) GPS only

Is the method used by FusedLocation to obtain the posistion related to this setting ?
Is the method used by the GPS library also related to this setting ?

It seems to me yes. So, as you say, there shouldn't be any accuracy improvement.
 
Top