Android Tutorial GPS tutorial

Status
Not open for further replies.
This example shows how to work with the GPS library.

upload_2016-6-23_9-56-49.png


The GPS object is declared in the Starter service. It is easier to put the GPS in a service and not in an Activity as the services life cycle is simpler.

When the program starts we check whether the location features are enabled:
B4X:
Sub Activity_Resume
   If Starter.GPS1.GPSEnabled = False Then
       ToastMessageShow("Please enable the GPS device.", True)
       StartActivity(Starter.GPS1.LocationSettingsIntent) 'Will open the relevant settings screen.
   Else
       Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_ACCESS_FINE_LOCATION)
       Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
       If Result Then CallSubDelayed(Starter, "StartGPS")
   End If
End Sub
If not then we open the relevant settings screen.

The next step is to check for the ACCESS_FINE_LOCATION permission (runtime permissions tutorial).
If we have permission then we call the StartGPS sub from the Starter service.

Now all that is left is to delegate the LocationChanged event from the service to the activity and show the information.
B4X:
'Starter service
Sub GPS_LocationChanged (Location1 As Location)
   CallSub2(Main, "LocationChanged", Location1)
End Sub

'Main activity
Public Sub LocationChanged(Location1 As Location)
   lblLat.Text = "Lat = " & Location1.ConvertToMinutes(Location1.Latitude)
   lblLon.Text = "Lon = " & Location1.ConvertToMinutes(Location1.Longitude)
   lblSpeed.Text = $"Speed = $1.2{Location1.Speed} m/s "$
End Sub

Due to Google policy change you also need to add this line to the manifest editor:
B4X:
AddManifestText(<uses-feature android:name="android.hardware.location.gps"/>)
This will prevent the app from being installed on devices without GPS hardware.

The example is attached.

Modified example with NMEA listener: https://www.b4x.com/android/forum/t...-not-firing-on-android-10.112140/#post-699351
 

Attachments

  • GPS.zip
    8.1 KB · Views: 7,274
Last edited:

ashrafidkaidek

Member
Licensed User
Longtime User
Gentlemen,
I have tried to create a txt file and write to it some information (representing the user selection before closing the app) in the:

Sub Activity_Pause (UserClosed As Boolean)

Even this task got ignored, so when the user hits the home button the app moves to the background without creating the txt file, is this how the Pause sub suppose to work? In other words what’s the point of having this sub if everything in it going to be ignored?

Thank you
 

schimanski

Well-Known Member
Licensed User
Longtime User
Hello!

I need to get the data from the internal GPS every time. If the user is not in the main-activity or the application is in the backround. Now I'm looking for the best method to catch the GPS-data with a service. I thought, that I have a Process_global GPS in the main-activity and try to read the data with the GPS_LocationChanged in the service. Is this possible without any risk? My second question is: Sends the GPS-Chip always data, when the device sleeps and the StartServiceAt is set on true?


rgds...
 

schimanski

Well-Known Member
Licensed User
Longtime User
Thanks Erel!

I have tested it on a Samsung Galaxy Tab and the GPS sends also data, when then device is sleeping. When I get you right, Erel, it is depending from the sitting OS.

Is it necessary to set the service in the foreground?
 

schimanski

Well-Known Member
Licensed User
Longtime User
Hello!

Is there a way to find out, when the gps-signal is lost? I have tried serveral things, but it seems that when the gps-signal is lost, the event GpsStatus (Satellites As List) is not raised.

rgds
 

schimanski

Well-Known Member
Licensed User
Longtime User
Thanks,

I think that is a good way to check it....I'll try it...
 

schimanski

Well-Known Member
Licensed User
Longtime User
O.k., I have a solution. GPS_GpsStatus (Satellites As List) is also raised, when the signal is lost. It runs by counting the satellites, which are used in fix:

B4X:
Sub GPS_GpsStatus (Satellites As List)
  lblSatellites.Text = "Satellites:" & CRLF
  s=0
  For i = 0 To Satellites.Size - 1
    Dim Satellite As GPSSatellite
    Satellite = Satellites.Get(i)
    lblSatellites.Text = lblSatellites.Text & CRLF & Satellite.Prn & _
         " " & Satellite.Snr & " " & Satellite.UsedInFix & " " & Satellite.Azimuth _        & " " & Satellite.Elevation
    If Satellite.UsedInFix=True Then s=s+1
      If s>0 Then 
        Status=s
      Else
        Status="Lost GPS!"
     End If
  Next
End Sub
 

splatt

Active Member
Licensed User
Longtime User
Location Name from Lat & Long

I'm only just starting to look at the GPS stuff, but is it possible to get a location name from the Lat & Long?
 

asawyer13

Member
Licensed User
Longtime User
Google Geocode API has a reverse lookup so you can put the lat and long and get the address.
Alan
 

peacemaker

Expert
Licensed User
Longtime User
In Basic4PPC there is InvalidData to be sure that connected\fixed and coordinates may be used.

How to be sure in b4a ?
 

schimanski

Well-Known Member
Licensed User
Longtime User
Look above, #30. You only have to count the satellites, which are in use. If there are 3 in use, you have a fix...
 

peacemaker

Expert
Licensed User
Longtime User
Look above, #30. You only have to count the satellites, which are in use. If there are 3 in use, you have a fix...

No, tested. Satellite.UsedInFix is just visible satellite, it's shown after several seconds (i saw 8-9 pcs), the antenna icon is animated, but the coordinates are not fixed yet, when the icon is static.

SpeedValid maybe looks that wanted, but if ... no moving how to be ? i just need to be sure that coordinates are really fixed with any accuracy staying frozen.
 
Last edited:

agraham

Expert
Licensed User
Longtime User
Detecting a lost fix seems to be an ongoing problem for many people in Android. From a post in a long thread here QuestionHub.com - Android GPS status by someone who appears to know what he is talking about

First of all, I'm a developer of SpeedView, a GPS speedometer for Android, so you can trust me when I say that we tried every possible solution to this problem, all with the same negative result. Let's start by reiterating what doesn work:

1.onStatusChanged() doesn't get called on Eclair and Froyo. It does get called on 1.6 though.
2.Simply counting all available satellites is, of course, useless.
3.Checking if any of the satellites returns true for usedInFix() isn't very helpful also. The system apparently loses the fix but still continue to report that there are several sats that are used in it.

So, the only working solution wet have, and the one we actuall use in our application, is the following
....
"the following" is some Java code which you can see for yourself in the link but what it does is save the current time when a LocationChanged event occurs and checks the difference between that time and the present time whenever a GpsStatus event occurs. If that difference is less than 3 seconds then it sets a global GpsFix flag True otherwise it sets it False.

There is a further refinement in the code that sets the GpsFix flage True when the GpsStatus event reports GPS_EVENT_FIRST_FIX but unfortunately this cannot be detected in Basic4android as the event argument is not available.
 

peacemaker

Expert
Licensed User
Longtime User
Thanks, Agraham, clear. We also can make same calculation. But... strange that Google passed this.
Military request :). Joke.
 
Status
Not open for further replies.
Top