I am building an app that updates the distance from current location, but for some reason I am not getting a consistent callback frequency for navigator.geolocation.watchPosition
It seems like something reseting the watch. My code has only componentWillUnmount where it would reset, but I put Alert it never occurred.
Is there frequency parameter I can specify or I guess I am thinking to go with manual timeout approach.
componentDidMount(){
AsyncStorage.getItem('listings')
.then((value) => {
this.state.listings = value?JSON.parse(value):[];
this.state.passProps.listings = this.state.listings;
this.redrawListings();
this.startWatch();
})
.done();
}
componentWillUnmount(){
navigator.geolocation.clearWatch(this.watchID);
}
startWatch(){
this.watchID = navigator.geolocation.watchPosition((lastPosition) => {
this.curLat = lastPosition.coords.latitude;
this.curLon = lastPosition.coords.longitude;
this._updateDistances();
},
(error) => AlertIOS.alert(error),
{enableHighAccuracy: true, timeout: 0, maximumAge: 1000});
}
@opolyo01 - the geolocation module uses CALocationManager, and the startUpdatingLocation method when you call watchPosition.
From the docs on it:
Calling this method causes the location manager to obtain an initial location fix (which may take several seconds) and notify your delegate by calling its locationManager:didUpdateLocations: method. (In iOS 5 and earlier, the location manager calls the locationManager:didUpdateToLocation:fromLocation: method instead.) After that, the receiver generates update events primarily when the value in the distanceFilter property is exceeded. Updates may be delivered in other situations though. For example, the receiver may send another notification if the hardware gathers a more accurate location reading.
distanceFilter is set to kCLLocationAccuracyHundredMeters - if you were to set it to kCLLocationAccuracyTenMeters you would receive updates more frequently.
It might make sense to have this be configurable, but you'll have to keep in mind that greater degrees of accuracy result in higher battery usage. Any reason not to expose this @nicklockwood?
If you'd like to get the updates every x seconds, then just setting a timeout and grabbing the current location would be okay.
There's no reason not to expose the accuracy, but it should be done so in a way that's compliant with the HTML5 Geolocation API as far as possible.
I thought we already did this, but I guess I misremembered.
@nicklockwood - poor wording on my behalf - desiredAccuracy is exposed, distanceFilter is not
What about monitoring significant updates only? It feels like the most reasonable approach would've been to implement own geolocation where HTML5 compliancy does not matter.
It would be useful to expose this API more completely. After a basic look into it, we seem to be missing a large amount of control over the location API when making it comply with HTML5. Perhaps I'm wrong, that's my initial take as I work through using this.
@christopherdro I've upgraded to rn 0.20.0-rc1 which should include your update, right? I'm still experiencing a similar issue, where I only get location updates once every ~25 seconds. Even using the following options: {enableHighAccuracy: true, distanceFilter: 1, timeout: 1000}
@joshblour Are you testing in iOS or Android. Did you try setting distance filter to 10 and see if that changes anything?
@joshblour @christopherdro the distanceFilter commit was merged master but has not landed in any release yet. You might consider cherry picking https://github.com/facebook/react-native/pull/5563 in the meantime.
@rt2zz Thanks for checking on that!
@joshblour This would be the commit to cherry pick. https://github.com/facebook/react-native/commit/109036b4c4b530c04c394c48e43319ca91ca2d53
Do _navigator.geolocation.getCurrentPosition_ work and _navigator.geolocation.watchPosition_ work on android? I'm just getting a timeout error. I've got <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />in my manifest file, and I can see the users current position (the blue dot) on a map, but I can't programatically get the position.
Is it possible distanceFilter is completely ignored on iOS? I've set it to a ridiculously high number but the callback is triggered very frequently without any or just small change in the coordinates.
I am having the same issue as @dominicmh. On Android the distanceFilter option seems to be also ignored and I get responses every 20 seconds. I would really like to only update my location when it changes by 5 meters. Does anyone know how to achieve this? My code is as below
this.watchID = navigator.geolocation.watchPosition((pos)=>{
var crd = pos.coords;
this.updateLocation(crd.latitude, crd.longitude);
},
{enableHighAccuracy: true, timeout: 1000, maximumAge: 0,distanceFilter:5});
I even tried setting the distanceFilter to something crazy like 200 but it still updates every 20s
distanceFilter seems to be ignored for me too (ios, latest React from npm)
@quatrix This got recently merged and might be worth looking into.
https://github.com/facebook/react-native/pull/6987
I still can't get updates at the frequency I want. When I use react-native-maps and turn on the showsUserLocation option the blue dot moves around with a much greater frequency than my watchPosition gets called. Any idea why?
@Jonrock23 did you ever figure out how to only get the updated locations once it's changed by 5 metres?
@christopherdro I am having the same issue for IOS. Has this issue you resolved only work for android?
It says in the react-native-background-geolocation repo:
Can anyone tell me if this is still the case?
Any insight is greatly appreciated.
@npomfret @willyyang Are you having this problem for IOS or Android?
I'm having the problem on iOS. If I use react-native-maps I see the blue user dot moving around with great frequency, but the calls backs my RN app sees aren't anyway near as frequent.
Thanks. I'm going to see what its like for android.
I'm experiencing the issue where location updates are triggered every ~100m even if I set distanceFilter to a lower value. I've done some troubleshooting and I think the issue I'm experiencing is related to these lines: https://github.com/facebook/react-native/blob/0.42-stable/Libraries/Geolocation/RCTLocationObserver.m#L309-L311.
I'm still working on it and hope to be able to provide some more detail. But I believe for me those lines are causing to be reset back to it's default distanceFilter value of kCLLocationAccuracyHundredMeters.
My solution was to call the "navigator.geolocation.getCurrentPosition" function inside a "setInterval" function.
The timeout parameter is working for me now, I'm getting much more frequent updates by setting it to _250_ (ms).
I'm using the following options for watchPosition and have managed to get pretty frequent updates in iOS Simulator and built onto my iPhone (RN 0.42.3):
{
enableHighAccuracy: true,
distanceFilter: 1,
}
@Isei How frequent is it, as in how much metres do you travel for it to return locations? Just asking because if you're zoomed out it appears to be accurate but the more you zoom in you realise how inaccurate it is.
Most helpful comment
@christopherdro I've upgraded to rn 0.20.0-rc1 which should include your update, right? I'm still experiencing a similar issue, where I only get location updates once every ~25 seconds. Even using the following options:
{enableHighAccuracy: true, distanceFilter: 1, timeout: 1000}