B4A Library FusedLocationProvider

Discussion in 'Additional libraries, classes and official updates' started by warwound, Feb 13, 2015.

  1. warwound

    warwound Expert Licensed User

    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
    Also note that as this library uses the Google Play Services library, you must also add this entry to your manifest:

    Code:
    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+:
    Code:
    #AdditionalJar: com.android.support:support-v4
    #AdditionalJar: com.google.android.gms:play-services-location
     

    Attached Files:

    Last edited by a moderator: Sep 13, 2017
  2. warwound

    warwound Expert Licensed User

    This is an example that shows syntax and basic usage of the FusedLocationProvider.

    The activity connects to the locations services and requests location updates with an interval of 1000 milliseconds and a 'SmallestDisplacement' of 1 meter.
    As location updates are received a Label shows the latest location's time, latitude and longitude.

    Code:
    Sub Process_Globals
        
    Private FusedLocationProvider1 As FusedLocationProvider
        
    Private LastLocation As Location
    End Sub

    Sub Globals
        
    Private LastLocationLabel As Label
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    '    **    IMPORTANT see manifest for required entries    **
        If FirstTime Then
            FusedLocationProvider1.Initialize(
    "FusedLocationProvider1")
        
    End If
        
        
    Activity.LoadLayout("Main")

        
    If LastLocation.IsInitialized Then
            UpdateUI
        
    End If

    End Sub

    Sub Activity_Resume
        
    '    attempt to connect to the location services
        '    after calling Connect we are waiting for either ConnectionFailed or ConnectionSuccess events
        FusedLocationProvider1.Connect
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        FusedLocationProvider1.Disconnect
    End Sub

    Sub FusedLocationProvider1_ConnectionFailed(ConnectionResult1 As Int)
        
    Log("FusedLocationProvider1_ConnectionFailed")
        
        
    '    the FusedLocationProvider ConnectionResult object contains the various CoonectionResult constants
        
        
    Select ConnectionResult1
            
    Case FusedLocationProvider1.ConnectionResult.NETWORK_ERROR
                
    '    a network error has occurred, this is likely to be a recoverable error
                '    so try to connect again
                FusedLocationProvider1.Connect
            
    Case Else
                
    '    TODO handle other errors
        End Select
    End Sub

    Sub FusedLocationProvider1_ConnectionSuccess
        
    Log("FusedLocationProvider1_ConnectionSuccess")
        
    Dim LocationRequest1 As LocationRequest
        LocationRequest1.Initialize
        LocationRequest1.SetInterval(
    1000)    '    1000 milliseconds
        LocationRequest1.SetPriority(LocationRequest1.Priority.PRIORITY_HIGH_ACCURACY)
        LocationRequest1.SetSmallestDisplacement(
    1)    '    1 meter
        FusedLocationProvider1.RequestLocationUpdates(LocationRequest1)
    End Sub

    Sub FusedLocationProvider1_ConnectionSuspended(SuspendedCause1 As Int)
        
    Log("FusedLocationProvider1_ConnectionSuspended")
        
        
    '    the FusedLocationProvider SuspendedCause object contains the various SuspendedCause constants
        
        
    Select SuspendedCause1
            
    Case FusedLocationProvider1.SuspendedCause.CAUSE_NETWORK_LOST
                
    '    TODO take action
            Case FusedLocationProvider1.SuspendedCause.CAUSE_SERVICE_DISCONNECTED
                
    '    TODO take action
        End Select
    End Sub

    Sub FusedLocationProvider1_LocationChanged(Location1 As Location)
        
    Log("FusedLocationProvider1_LocationChanged")
        LastLocation=Location1
        UpdateUI
    End Sub

    Sub UpdateUI
        LastLocationLabel.Text=
    DateTime.Time(LastLocation.Time)&" ("&LastLocation.Latitude&", "&LastLocation.Longitude&")"
    End Sub
    Martin.
     

    Attached Files:

    Last edited: Apr 14, 2015
    Mikonios, janderkan, toby and 3 others like this.
  3. coslad

    coslad Well-Known Member Licensed User

    Last edited: Feb 13, 2015
  4. coslad

    coslad Well-Known Member Licensed User

    i tried your sample code and works like a charm!
     
    warwound likes this.
  5. coslad

    coslad Well-Known Member Licensed User

    Any way to know the accuracy?
     
  6. warwound

    warwound Expert Licensed User

    The Location object passed to the LocationChanged sub has an Accuracy property you can use to determine the accuracy.
     
    Last edited: Apr 14, 2015
  7. coslad

    coslad Well-Known Member Licensed User

    You are right , i didn't saw it !

    Thanks
     
  8. Shay

    Shay Well-Known Member Licensed User

    it looks similar to the locationAPI library
    what is the difference between them?
     
  9. warwound

    warwound Expert Licensed User

    See my post here:
    http://www.b4x.com/android/forum/th...e-low-power-location.29700/page-6#post-316394

    The API used by the LocationAPI no longer exists.
    The LocationAPI will probably still work if you use an old version of the Google Play Services library(though i have not tested this).
    But if you use the current version of the Google Play Services library then the LocationAPI library will fail.
    You'll see an exception such as:
    So the FusedLocationProvider is much the same as the LocationAPI but works with the current Google Play Services.
     
  10. gudino jose luis

    gudino jose luis Active Member Licensed User

    hi
    I have this little problem
    I have the version 21 of Google Play Services and shows me this message:

    java.lang.NoClassDefFoundError: uk.co.martinpearman.b4a.android.gms.location.subclasses.LocationClient

    but only when I debug
    when I run without debugging it is perfect

    note:I'm using FusedLocationProvider
     
  11. warwound

    warwound Expert Licensed User

    That exception can only occur if you use the old LocationAPI - that class is only part of the old LocationAPI, it's not part of the FusedLocationProvider.

    Have you got both libraries checked in the b4a IDE?
     
    thedesolatesoul likes this.
  12. gudino jose luis

    gudino jose luis Active Member Licensed User

    Thank you for your answers and time.

    I have just checked a library FusedLocationProvider.

    when I debug (legacy) this message is displayed:
    java.lang.NoClassDefFoundError: uk.co.martinpearman.b4a.fusedlocationprovider.FusedLocationProvider

    when debug (rapid) the program exits without displaying message.

    best regards
     
  13. warwound

    warwound Expert Licensed User

    There's a very similar problem when using GoogleMapsExtras in debug mode - some classes are not found.
    The error occurs because some classes in the Google Play Services library are not found - and classes that depend on these Play Service classes can't be created.

    There's no workaround i know of - that makes debugging an activity that depends on a library that depends on Google Play Services tricky.
     
    thedesolatesoul likes this.
  14. gudino jose luis

    gudino jose luis Active Member Licensed User

    In fact I was also using Google Maps Extras in debug mode means problems

    Install a new version with SDK 21, but gave me many problems when compiling,

    Reinstall the previous SDK to version 19 and google play services reinstall the version 15

    I can not FusedLocationProvider in debug mode.
    I can Google Maps Extras in debug mode.

    thanks for your help
     
    Last edited: Feb 24, 2015
  15. Shay

    Shay Well-Known Member Licensed User

    I had same issue:
    java.lang.NoClassDefFoundError: uk.co.martinpearman.b4a.android.gms.location.subclasses.LocationClient

    I fixed it by removing old code of LocationApi library and put the new one, base on the example above (the attached project example)
     
  16. gudino jose luis

    gudino jose luis Active Member Licensed User

    Thanks I'll try
    Greetings and thanks for your time
     
  17. gudino jose luis

    gudino jose luis Active Member Licensed User

    hi

    yet I could not solve the problem even get the message
    "java.lang.NoClassDefFoundError: uk.co.martinpearman.b4a.fusedlocationprovider.FusedLocationProvider"
    I have installed the version SDK 21

    any suggestions?
    thanks in advance.
     
  18. warwound

    warwound Expert Licensed User

    FusedLocationProvider updated to version 1.10

    This updates adds support for the Location Settings Dialog that is part of the latest Google Play Services update.
    For more info have a read here: http://android-developers.blogspot.co.uk/2015/03/google-play-services-70-places-everyone.html.

    You must run the Android SDK Manager and ensure that you have the latest version of Google Play Services installed, and you must also ensure that your copy of the Google Play Services library (google-play-services.jar) in your b4a additional libraries folder is a copy of the latest version.

    The FusedLocationProvider has a new method:

    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)


    You create a LocationSettingsRequest and pass it to this new method.
    LocationSettingsRequest is created using the LocationSettingsRequestBuilder object:

    LocationSettingsRequestBuilder
    Methods:
    • AddLocationRequest (LocationRequest1 As LocationRequest) As LocationSettingsRequestBuilder
      Adds one LocationRequest that the client is interested in.
      This method can be called multiple times if required to add additional location requests.
    • Build As LocationSettingsRequest
      Creates a LocationSettingsRequest.
    • Initialize
    • IsInitialized As Boolean
    • SetNeedBle (NeedBle As Boolean) As LocationSettingsRequestBuilder
      Sets whether the client wants BLE to be enabled.

    The LocationSettingsChecked event is raised and passed a LocationSettingsResult object:

    LocationSettingsResult
    Methods:
    • GetLocationSettingsStates As LocationSettingsStates
      Returns the location settings states.
    • GetLocationSettingsStatus As LocationSettingsStatus
      Returns the location settings result status.
    • IsInitialized As Boolean

    The LocationSettingsStates object details exactly which location services are available and enabled on the device:

    LocationSettingsStates
    Methods:
    • IsBlePresent As Boolean
      Whether BLE is present on the device.
    • IsBleusable As Boolean
      Whether BLE is enabled and is usable by the app.
    • IsGpsPresent As Boolean
      Whether GPS provider is present on the device.
    • IsGpsUsable As Boolean
      Whether GPS provider is enabled and is usable by the app.
    • IsInitialized As Boolean
    • IsLocationPresent As Boolean
      Whether location is present on the device.
      This method returns true when either GPS or network location provider is present.
    • IsLocationUsable As Boolean
      Whether location is enabled and is usable by the app.
      This method returns true when either GPS or network location provider is usable.
    • IsNetworkLocationPresent As Boolean
      Whether network location provider is present on the device.
    • IsNetworkLocationUsable As Boolean
      Whether network location provider is enabled and usable by the app.

    And the LocationSettingsStatus object details whether the device's current settings meet the requirements for your LocationRequest object(s):

    LocationSettingsStatus
    Events:
    • ResolutionDialogDismissed (LocationSettingsUpdated As Boolean)
    Fields:
    • StatusCodes As StatusCodes
      Contains the various StatusCode constants.
    Methods:
    • GetStatusCode As Int
      Returns the status code that describes whether the location settings meet the location request requirements.
    • IsInitialized As Boolean
    • StartResolutionDialog (EventName As String)
      Starts the resolution dialog.
      The user can then enable the location settings required to meet the location request requirements.
      This method must be called from an Activity.
      Raises the event:
      ResolutionDialogDismissed(LocationSettingsUpdated As Boolean)

    The StatusCode is the value to look at:

    StatusCodes
    Fields:
    • RESOLUTION_REQUIRED As Int
      Location settings do not meet the location request requirements.
      Location settings can be changed to meet the location request requirements.
      A resolution dialog is available.
    • SETTINGS_CHANGE_UNAVAILABLE As Int
      Location settings do not meet the location request requirements.
      Location settings can't be changed to meet the location request requirements.
      No resolution dialog is available.
    • SUCCESS As Int
      Location settings meet the location request requirements.

    The LocationSettingsStatus object contains the all important StartResolutionDialog method that shows the user a dialog which enables them to adjust the device location settings.

    The StartResolutionDialog method must be called from an Activity - it cannot be called from a Service.

    I've attached 2 b4a example projects to this post.
    One example shows how to show the Location Settings Dialog when the FusedLocationProvider is being used within an Activity, the other example shows how to show the dialog when the FusedLocationProvider is being used in a Service.

    FusedLocationProvider version 1.10 library files are attached to the first post in this thread.

    Martin.
     

    Attached Files:

    janderkan, Seneca, MarcoRome and 5 others like this.
  19. Cebuvi

    Cebuvi Active Member Licensed User

    Very good work and very useful.

    Cesar
     
  20. Cebuvi

    Cebuvi Active Member Licensed User

    Hi Martin,

    I am using your FusedLocationProvider library for a widget to obtain the coordinates. I would like them to update every hour, I configure the LocationRequest object and all is ok. The problem I found is that when the divice is switched on, the widget obtains lat=0,0 and long=0,0 as the coordinates and it does not update them until after 1 hour.

    How can I do for it to first update the coordinates until it find the correct values and then, after that, automatically update then hourly?.

    Thanks.

    Cesar
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice