As you can see, the recordings follow one another exactly every 30 seconds.
This is the code
B4X:
RegistraOgni=30000
If Not (TimerRegistra.IsInitialized) Then
T1=Main.RegistraOgni
TimerRegistra.Initialize("TimerRegistra",T1)
TimerRegistra.Interval=T1
End If
The same app, however, on another smartphone in Finland, does not behave in the same way.
I have put in brackets the actual interval in seconds which is very often very different from 30 seconds.
This is the beginning of the file (in Finland).
This is not about setting more or less accurate timing.
The error, in that smartphone, is macroscopically high.
Precisely because you said (i.e. that the timer is invoked at the end of the events) even if I set a timer to a tenth of a second I have a well-founded suspicion that nothing would change because the timer at a tenth of a second would still be called at the end of the events, that is, very very late
@LucaMs: It may be, but it is currently impossible for me to delve deeper into this aspect.
The app is installed on a couple of my smartphones and on another in Finland as a person who practices cross-country skiing in those cold lands. @Alessandro71: I would rule it out. Finland is not (yet) a war zone where GPS data is disturbed.
The measurements were carried out during the day when the aurola borealis should not influence the GPS satellites.
Not talking about GPS jamming, rather than receiver quality: on my device I can’t receive data more than once a second.
I also saw erratic behavior on some Huawei devices
Not talking about GPS jamming, rather than receiver quality: on my device I can’t receive data more than once a second.
I also saw erratic behavior on some Huawei devices
If you can get the user to try, @LucaMs suggestion would eliminate the GPS element.
If not, check your code to see if GPS disruption could affect the timer effect.
(for example, if no response from GPS, does it keep trying, before handing control back to the event handlers.)
Trusting what Erel writes ("The Timer isn't the problem") I also think that the malfunction cannot be attributed to the GPS.
It is difficult for me to regularly contact the skier in Finland so I will wait for him to return to Italy and examine his smartphone to find the cause of the malfunction.
Explanation: the app is currently on a smartphone owned by a cross-country skier in Finland (currently -7 degrees centigrade, it's not even that cold) who is quite new to IT issues so it's difficult to instruct him to change the parameters in play.
Let alone suggest installing a new version of the app.
I can only read the contents of the file I attached in my first post on the internet.
When he returns I will take matters back into my own hands.
My app records the GPS position to a file every 30 seconds.
This is the beginning of the file (in Italy).
As you can see, the recordings follow one another exactly every 30 seconds.
This is the code
B4X:
RegistraOgni=30000
If Not (TimerRegistra.IsInitialized) Then
T1=Main.RegistraOgni
TimerRegistra.Initialize("TimerRegistra",T1)
TimerRegistra.Interval=T1
End If
The same app, however, on another smartphone in Finland, does not behave in the same way.
I have put in brackets the actual interval in seconds which is very often very different from 30 seconds.
This is the beginning of the file (in Finland).
later in the file the problem occurs again
What could be the causes of this serious malfunction? The cold, the overloaded smartphone, ...?
Private lastTime As Long
Private TimerRegistra As Timer
lastTime = DateTime.Now
TimerRegistra.Initialize("TimerRegistra", 1000) 'Now the interval is 1 second, but you can adjust the value.
Sub TimerRegistra_Tick
If DateTime.Now - lastTime >= 30000 Then
'registra l'ultima GPS-Location
lastTime = DateTime.Now
End If
End Sub
I also think that it's not the timer itself. Many years ago, I wrote an Android app that measured the GPS position at regular intervals and then stored it in a log file. I had to deal with similar problems. The solution was that I outsourced the provision of the measurement data and its logging to a service.
The problem at the time was that, depending on the settings in the smartphone itself, the smartphone's energy-saving functions became noticeable and then, of course, the app stopped running and therefore the timer event did not trigger. A service is largely immune to this, as it continues to run in the background and is not deactivated so quickly by the operating system. However, I have to say that this was in the days of Android versions 7, 8, 9 and 10. This may be different with newer versions and I won't reprogram the entire app just because it is "no longer secure" these days or because other "handling concepts" are now favoured by Android. My app is an absolute niche product, actually only written for myself because I was too lazy to write down my daily customers in a notebook. An old smartphone can do that for me and still does today.
I'm attaching the routine of this service to this post, but without any guarantee that it will work with newer Android versions. In principle, it should still work today.
A service itself should still work with newer Android versions, although it may also be "killed" after a while or generally set up differently. The routine itself may not be entirely without errors, but at least it works.
If that doesn't help either, then try to prevent the smartphone from going into standby mode while the app is active. In the past, you could easily achieve this with a wakelock, you can allow the display to dim, because this consumes a lot of energy.
With these two methods, I achieve app runtimes of 5-6 hours on an old smartphone where the battery has certainly seen better days. But at least the old smartphone still fulfils a purpose...
And one more thing: This code is perhaps not quite up to date and contains some "code smells". This programme was my first project with B4A. You can also download the complete programme. You can find it on my website. Search for ODYSSEY. It's free, it's just limited by default to a 3 month cycle. It should work without any problems with older Android devices.
GPS-Service:
#Region Service Attributes
#StartAtBoot: False
#End Region
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Dim GPS1 As GPS
Dim Accuracy As Float
Dim Altitude As Double
Dim Bearing As Float
Dim Latitude As Double
Dim Longitude As Double
Dim LogData As String
Dim N As Notification
Dim Speed As Float
Dim Sats As Int
Dim GPSAltitudeSeaLevel As Double
Dim GPSNMEASpeed As Double
End Sub
Sub Service_Create
N.Initialize
N.OnGoingEvent = True
N.Sound = False
N.Vibrate = False
N.Light = False
N.Icon = "icon"
N.SetInfo("ODYSSEY", "GPS-Service", "")
N.Notify(1)
End Sub
Sub Service_Start (StartingIntent As Intent)
GPS1.Initialize("GPS")
If GPS1.GPSEnabled = False Then
ToastMessageShow("GPS ON ?", True)
StartActivity(GPS1.LocationSettingsIntent) 'Will open the relevant settings screen.
Else
GPS1.Start(0,0) 'Listen to GPS
End If
End Sub
Sub Service_Destroy
GPS1.Stop
StopService("")
N.Cancel(1)
End Sub
Sub GPS_LocationChanged (Location1 As Location)
If Location1.AccuracyValid = True Then
Accuracy = Location1.Accuracy
End If
If Location1.BearingValid = True Then
Bearing = Location1.Bearing
End If
Latitude = Location1.Latitude
Longitude = Location1.Longitude
End Sub
Sub GPS_NMEA (TimeStamp As Long, Sentence As String)
If Sentence.SubString2(0, 6) = "$GPGGA" Then
Dim vals() As String
vals = Regex.Split(",", Sentence)
If IsNumber(vals(9)) Then
GPSAltitudeSeaLevel = NumberFormat2(vals(9),1,0,0,False)
If GPSAltitudeSeaLevel > 0 Then
Altitude = GPSAltitudeSeaLevel
Else
Altitude = 0
End If
End If
End If
If Sentence.SubString2(0, 6) = "$GPRMC" Then
Dim vals() As String
vals = Regex.Split(",", Sentence)
If IsNumber(vals(7)) Then
GPSNMEASpeed = vals(7)
Speed = GPSNMEASpeed * 0.5144444444
If Speed <1 Then
If Speed >0 Then
Speed = 0
End If
End If
End If
End If
End Sub
Sub GPS_GPSStatus (Satellites As List)
Sats = 0
For i = 0 To Satellites.Size - 1
Dim Satellite As GPSSatellite
Satellite = Satellites.Get(i)
If Satellite.UsedInFix = True Then
Sats = Sats +1
End If
Next
End Sub
These last 2 posts are interesting as they approach the problem in two different ways.
The first does not directly use a timer. But I'm afraid it doesn't solve the problem.
The second uses a service, probably a more elegant and perhaps more efficient solution.
When my skier returns I will try both solutions.
I have a vague recollection reading that to handle infrequent timer events from low-power mode, an operating system would group nearby scheduled events together so that only it only needed to wake up once, and could service all the nearby calls at the same time, before returning to low-power mode.
Eg if you had a dozen processes all having a regular timer event say once a minute, then rather than wake up 12 times (on average once every 5 seconds) to individually deliver the timer event calls, it would wake up once and deliver them all but only incur onewake-up-and-back-to-sleep overhead.
Lol I say vague, as in it might have been for iOS and not Android, and I've got no idea what book it was from, but I do remember the café I was in, and I think even the seat (outside on the balcony, next to the ride-on dolphin). Would have been maybe 2010.