christianrowlands / android-network-survey

Cellular Survey Android App
https://www.networksurvey.app
Apache License 2.0
171 stars 29 forks source link

Old (GNSS) locations in survey-data #59

Open Schramp opened 3 days ago

Schramp commented 3 days ago

Describe the bug While analysing my collected network data I noticed that several tens of minutes could contain exactly the same GNSS location data, and sometimes is clearly off by several Km's.

To Reproduce Steps to reproduce the behavior: Setup MQTT broker, start MQTT at boot autostart Cellular logging, Scan interval 5 seconds Location Provider: GNSS

Expected behavior Perhaps under discussion: Accurate locations on all registrations... or dropping location information when locations source is not available/outdated or additional timestamp of GNSS time.

At the same time I got the feeling that GNSS updates seems to need a event to restart when it stopped due to unknown causes. Is this something that other people observed or got an opinion about based on the code?

Schramp commented 3 days ago

Reading the code i wondered if it makes sense to modify getLatestLocation() to check for outdated information.

https://github.com/christianrowlands/android-network-survey/blob/ffb572dd547a00edabcdb8852ff5873dbe7d334e/networksurvey/src/main/java/com/craxiom/networksurvey/GpsListener.java#L137

It seems the listener is only started once... https://github.com/christianrowlands/android-network-survey/blob/ffb572dd547a00edabcdb8852ff5873dbe7d334e/networksurvey/src/main/java/com/craxiom/networksurvey/services/NetworkSurveyService.java#L1222

Schramp commented 3 days ago

NB. Happy to implement, but need some refinement beforehand.

christianrowlands commented 3 days ago

Let me make sure I understand the problem. It sounds like NS is getting a good location from the Android OS, and then storing it in the GpsListener. Then, the device stops getting a good location, but NS keeps the latest location stored in GpsListener, which causes all future records to have that stale location set on them.

If that is what is happening, then yes, it would be good to add some sort of location timeout in GpsListener to cause the location to be removed so it does not get stale. I could see a timer based approach where a recurring task clears it if it is old, and I could also see a situation where it starts returning null when consumers call getLatestLocation() if the age is past a threshold.

Probably simplest to do the latter since it is not a CPU intensive check.

christianrowlands commented 3 days ago

However, I am not sure I understand this comment:

At the same time I got the feeling that GNSS updates seems to need a event to restart when it stopped due to unknown causes. Is this something that other people observed or got an opinion about based on the code?

Is that a related issue, or are you seeing crashes causing GNSS to stop?

Schramp commented 2 days ago

Is that a related issue, or are you seeing crashes causing GNSS to stop? As the monitoring of Cell Measurments continue its not NS itself that crashes. But I do not know what reasons could exist to stop receiving GNSS data. In my data however I see that after some time the correct location is picked up again and accurate GNSS data is available.

This effect might be caused by not having GNSS data and therefor not receiving updates (I noticed the effect due to displacement of Cell ID's, placing the Cell at the place I step into a train. That could be the moment that the GNSS data freezes putting several measurements at the starting train station and restarts when I get the phone from my pocket. However its not that likely I put my phone in my pocket for the duration of the train ride.

An alternative reason could be that the GNSS stops for other reasons and using my phone triggered it to start again.

So I guess my question is, if it makes sense to try to restart GNSS monitoring. It would only make sense if the monitoring stopped due to a SW reason. If it stopped due to lack of signal and restarted when signal levels were OK again, then everything works as expected. In the latter case we need to suppress the old locations, or mention the (skewed) time of everylocation with the real time om the Cell Measurement. If its something that can be fixed in SW by pulling some strings that would be nice to investigate.

Schramp commented 2 days ago

Did some testing today, its probably only caused by loss of GNSS signal. When moving into GNSS signal range again, the location information starts updating again.

Lets try to move toward a agreed solution. My preferred solution is to have a "time of location field", and fall back to other means of positioning (e.g. based on WiFi and Cell-ID) and have a "locationProvider field" indicating whether it is "gps" or something else. I expect that when I would choose the FUSED provider in the configuration that would almost be standard behaviour except the location source and time are not logged in fields.

What do you think?

christianrowlands commented 19 hours ago

My preferred solution is to have a "time of location field".

I think this is a good solution, and probably something I should have had all along. Stale locations are not something someone wants. I can code this up, it should be pretty straightforward.

and fall back to other means of positioning (e.g. based on WiFi and Cell-ID) and have a "locationProvider field" indicating whether it is "gps" or something else

As for a fallback, that is what FUSED is supposed to do. So if it is not happening then it means it can't get good location data even using wifi or cellular. In that case we are just out of luck.

christianrowlands commented 18 hours ago

By any chance are you running Android 13 or higher? The best way to do this is to use the elapsed realtime, but that feature was added to the location time in Android 13. Using the other time will have some inconsistencies. Those problems can be read about in the documentation: https://developer.android.com/reference/android/location/Location#getTime()

If you are Android 13+ I will use the newer approach which means the issue will live on in older versions of android, but be fixed as people upgrade their OS.