Geolocation with react-native
You can also be interested in:
Checkout the package I've uploaded on npm to manage all geolocation stuff in react-native: react-native-location-manager!
I've had many problems with react-native geolocation module.
In particular I faced a weird behaviour of the getCurrentPosition
method: while the world was lamenting timeout problems, probably due to the fact that gps tracking is not fast at all in closed spaces, my problem was that with highAccuracy
set to true, the returned value was always a cached one, no matter how I set maxAge
option.
If your problem is a timeout problem, then you can just call getCurrentPosition
with highAccuracy
set to false on timeout.
In my case I've tried to solve the problem using the watchPosition
method, which in my tests seems not tu suffer of the cache problem. So the idea is the following.
When asking for position, the first attempt is to retrieve GPS position using watchPosition
method:
- if the position is retrieved, then the watch listener is canceled and the provided callback is called;
- if an error occurs, the watch listener is canceled and the function tries to retrieve a low accuracy position
- after the watchPosition call, a timeout function is set. This function checks if the watchPosition method returned an error or a success, in either cases does nothing. But if the watchPosition method still is running, then it performs a low accuracy call. This way a low accuracy position is immediately returned to the user, and later on, if the high accuracy call retrieves something, the user gets the updated position.
Here comes the code, all kinds of suggestions are much appreciated
export function getLocation (cb, options) { let highAccuracySuccess = false let highAccuracyError = false let highAccuracy = !options || options.highAccuracy === undefined ? true : options.highAccuracy let timeout = !options || options.timeout === undefined ? 10000 : options.timeout let getLowAccuracyPosition = () => { console.log('REQUESTING POSITION', 'HIGH ACCURACY FALSE') navigator.geolocation.getCurrentPosition( position => { console.log('POSITION NETWORK OK', position) cb(position.coords) }, error => { console.log(error) // inform the user }, { enableHighAccuracy: false, timeout: 10000, maxAge: 0 } ) } if (highAccuracy) { console.log('REQUESTING POSITION', 'HIGH ACCURACY TRUE') const watchId = navigator.geolocation.watchPosition( position => { // location retrieved highAccuracySuccess = true console.log('POSITION GPS OK', position) navigator.geolocation.clearWatch(watchId) cb(position.coords) }, error => { console.log(error) highAccuracyError = true navigator.geolocation.clearWatch(watchId) getLowAccuracyPosition() }, { enableHighAccuracy: true, timeout: 20000, maxAge: 0, distanceFilter: 1 } ) setTimeout(() => { if (!highAccuracySuccess && !highAccuracyError) { getLowAccuracyPosition() } }, timeout) } }
I use toasts to inform the user about errors directly in this function (I've stripped out such parts), but you can easily add an onError
callback.
Your Smartwatch Loves Tasker!
Your Smartwatch Loves Tasker!
Featured
Archive
- 2021
- 2020
- 2019
- 2018
- 2017
- Nov
- Oct
- Aug
- Jun
- Mar
- Feb
- 2016
- Oct
- Jun
- May
- Apr
- Mar
- Feb
- Jan
- 2015
- Nov
- Oct
- Aug
- Apr
- Mar
- Feb
- Jan
- 2014
- Sep
- Jul
- May
- Apr
- Mar
- Feb
- Jan
- 2013
- Nov
- Oct
- Sep
- Aug
- Jul
- Jun
- May
- Apr
- Mar
- Feb
- Jan
- 2012
- Dec
- Nov
- Oct
- Aug
- Jul
- Jun
- May
- Apr
- Jan
- 2011
- Dec
- Nov
- Oct
- Sep
- Aug
- Jul
- Jun
- May