-
Notifications
You must be signed in to change notification settings - Fork 664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expected behavior from watchPosition timeouts and high accuracy #287
Comments
iOS does something unique in that when you first start up the location manager, it will immediately send in "GPS updates", in whatever state it's in. These are usually garbage and/or out-dated location events but Apple favours sending them out for responsiveness vs accuracy. Android doesn't behave this way and will wait for a GPS event that is somewhat acceptable in accuracy.
This is probably due to the fact that Apple wants iOS developers to stop the location manager on errors, though if it's stopping the watch on timeout, then that might be wrong on Cordova's part.
Before I get into this, important to note that Cordova doesn't have an Android implementation. You're using the native browser geolocation implementation on Android. The android side of this plugin only handles permissions. Android & iOS has different "energy-saving" mantras. How Android filters geolocation updates is not really known, as it's a browser implementation detail. iOS does use distance filter checks. On both platforms, Healthy GPS connections will report a GPS update approximately every second. On iOS, GPS updates are filtered by a distance filter. These are hard-coded based on the high accuracy boolean. If I recall correctly, it's 5m for high accuracy, and 3km for coarse accuracy. GPS updates doesn't get broadcasted to app code immediately, but whenever the native GPS update is provided it is recorded and broadcasted to the webview (but not app code). On the plugin's JS side, there is an interval that ticks every second that provides the last known GPS update. I believe it will use the timestamp and maximum age to determine whether if app-code callback should be invoked or not. It will also trigger timeouts if it hasn't received a GPS update from native within the requested timeout time. So depending on the configuration, you could see several "GPS updates" that are actually the same GPS point, if GPS updates from native are slow. I'm kinda going off memory, I didn't review the code before I wrote this so I might have some minor details wrong...
High accuracy allows "fine" location, which is necessary if you want to know the street the user is on. Just because you have If the boolean is off, then the option for the user to grant high accuracy location will not be shown and the user can only grant coarse accuracy (or obviously reject giving permission). If app code enables high accuracy, and the user grants high accuracy, it is still possible that the device will only operate with coarse accuracy, depending on device location settings (for example, if using GPS hardware is turned off). The exact accuracy Coarse option provides is implementation dependent but usually it uses more energy efficient means of determining the location, e.g. avoids using GPS hardware. Accuracy is usually guaranteed to be within 3km but is often (in my experience) much tighter radius. Even if the given point is accurate to a 3km radius, this is acceptable if you're trying to determine the user's country for example. If you don't need high accuracy, then allowing only coarse accuracy should see energy usage improvements. The interval used on the JS side might be a bit wasteful, but most of the energy consumption will be from the GPS hardware which the settings will configure the native stuff to be more energy efficient. |
Thanks for the informative responses. My biggest issue with iOS watchPosition() is its timing out and and not continuing on its own. Unless there is a way around this I am going to have to add code to my onError that tries to reset/restart the watchPosition() method. |
Yah that might be a bug... I know Apple wants iOS developers to stop the location manager on "denied" errors, but a timeout is likely not a deny error. And it would definitely be better if behaviour was consistent with Android. Like I said, Android uses the browser implementation, so it's likely also more closer to the W3C spec. |
@breautek - this is a good write up, maybe you can pin for others or add some of these details to the readme file. We can close this one, but I am going to open a BUG issue now specifically regarding the iOS watchPosition timeout behavior I am seeing; I will be referencing a work around - maybe the bug/work around here in this thread. |
I am testing some new rewrites of my code for geolocation and am noticing some peculiliar things and hoping others can help explain.
For both getCurrentPositions() and watchPosition() I use same following options:
var geoOptions = { maximumAge: 10000, timeout: 10000, enableHighAccuracy: true };
When app is deployed to iOS Simulator and physical iPhone the
watchPosition()
fires a 4 times (every time) and then on the 4th call I get a timeout which is triggers my onError callback. The specific error message isCode: 3, Message: Position retrieval timed out
. After 1 timeout, watchPosition() stops and does not resume. This happens on fresh install of app on either type and with simply deploying the app again (overwriting the current installed one. On physical devices and Android simulator this is not happening - I see it firing about once per second (***) continuously.When deployed a real device, watchPosition() seems to be firing every second even though my device is plugged and sitting on and not moving. How exactly is watchPosition working? I assume it would only trigger if it detected an actual movement, but my debugging shows the same coordinates every time it fires.
Is there a way to slow down the watchPosition to only "check" once per 10 seconds...I don't need extreme "watching" in my app but I do need to try and update the users coordinates at certain intervals.
Last, how intensive is
enableHighAccuracy
on the device as well as what are others experiences when not using it - the disabledHIghAccuraccy coordinates versus the enableHighAccurracy coordinates? Is there really a significant difference?Thanks.
The text was updated successfully, but these errors were encountered: