Aggressively reacquire a GPS fix
Aggressively reacquire a fix after poor GPS conditions and while the screen is off.
We need timely location updates even if they're not perfectly accurate. Therefore, this PR sets "waitForAccurateLocation = false" explicitly. This will deliver initial GPS locations as soon as GPS gets any fix, then continue to refine the accuracy.
The existing accuracy filtering in LocationProcessor.locationIsWithAccuracyThreshold() will still reject locations that are too inaccurate based on ignoreInaccurateLocations preference.
When the device exits Idle mode, we do not seem to automatically resume delivering fresh locations in timely manner. Monitor power state changes and automatically restart location requests when the device exits Idle mode.
Linked issues: #1898
Important / Full transparency
- I'm not familiar with the Kotlin programming language and this code (apart from minor changes) was completely AI-generated based on this repository code and my owntracks android client debug logs. I'm not sure what the policy on AI-generated code this project has.
- I believe I have reasonable understanding what all the changes in this AI-generated PR do and they do fix my issue with the current owntracks android client. I've tested the same journey 10 times this week, no issues with location reporting whatsoever. Without this patch, the failure rate was cca 8/10 times.
- I'm fully aware that this code might fix the effect of another bug and not the real cause of the issue. I hope that requesting some help from the maintainers to see if this is the case will not offend anyone.
- I do apologise in advance if AI-generated code is not welcome here.
Interesting idea.
Re: waitForAccurateLocation, there was a very specific reason why this was set away from "false" in the past, and that's because people had experiences where the first location they received after some device sleep time was waaaaaay off where they were (and sometimes, but not always low accuracy). This led to, essentially, "bad" location data being transmitted.
I think there's a case for allowing the user the choice. Could you update this to stick that option behind a preference called something like "waitForAccurateLocation" (to borrow the API name). That should allow the user to choose whether they prefer more, less accurate locations, or fewer more accurate locations.
I think there's a case for allowing the user the choice. Could you update this to stick that option behind a preference called something like "waitForAccurateLocation" (to borrow the API name). That should allow the user to choose whether they prefer more, less accurate locations, or fewer more accurate locations.
Thank you for looking into this and the context! Makes sense. I believe my PR was a little premature and the code still needs more testing. I also tried with the original waitForAccurateLocation = null (i.e. true by default) yesterday and had the first failure (GPS update came too late). Also, the 10/10 "just fine" tests (with waitForAccurateLocation = false) I was actually doing were using a different form of transport (I wasn't going by car where the failures were occuring). Let me update this based on my experiments/testing in a few weeks.
More testing is useful, thanks for doing.
I may seem overly keen to "put everything behind a preference", but this project's main lesson is that all Android devices across different manufacturers behave very differently to each other. The exact same app with the same configuration can produce a lovely route track on my Pixel, but a horrible mess on someone else's Samsung (glares at Samsung). Tuning this stuff to give a decent result on a specific device is more of an art than anything, so providing the tunables is pretty important imo.
Bad news. After some weeks of testing using car as a means of transport, I concluded that waitForAccurateLocation=false doesn't help (it actually makes matters worse when not moving at all) and ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED and ACTION_DEVICE_IDLE_MODE_CHANGED somewhat help, but are not a bullet-proof solution to the issue I'm seeing. So, back to the drawing board.
Good news. I've abandoned this approach in favour of trying to wake the device up and request a fresh GPS fix on Sensor.TYPE_SIGNIFICANT_MOTION. I'll continue testing this thoroughly before adjusting the code here, but initial testing shows the problem of waking up from DOZE in time after entering an area of bad GPS coverage can be resolved by acting on Sensor.TYPE_SIGNIFICANT_MOTION.