/// <summary> /// Gets the position asynchronous. /// </summary> /// <param name="timeout">The timeout.</param> /// <param name="cancelToken">The cancel token.</param> /// <param name="includeHeading">if set to <c>true</c> [include heading].</param> /// <returns>Task<Position>.</returns> /// <exception cref="System.ArgumentOutOfRangeException">timeout;timeout must be greater than or equal to 0</exception> public Task<Position> GetPositionAsync(int timeout, CancellationToken cancelToken, bool includeHeading) { if (timeout <= 0 && timeout != Timeout.Infinite) { throw new ArgumentOutOfRangeException("timeout", "timeout must be greater than or equal to 0"); } var tcs = new TaskCompletionSource<Position>(); if (!IsListening) { GeolocationSingleListener singleListener = null; singleListener = new GeolocationSingleListener( (float)DesiredAccuracy, timeout, _providers.Where(_manager.IsProviderEnabled), () => { for (var i = 0; i < _providers.Length; ++i) { _manager.RemoveUpdates(singleListener); } }); if (cancelToken != CancellationToken.None) { cancelToken.Register( () => { singleListener.Cancel(); for (var i = 0; i < _providers.Length; ++i) { _manager.RemoveUpdates(singleListener); } }, true); } try { var looper = Looper.MyLooper() ?? Looper.MainLooper; var enabled = 0; for (var i = 0; i < _providers.Length; ++i) { if (_manager.IsProviderEnabled(_providers[i])) { enabled++; } _manager.RequestLocationUpdates(_providers[i], 0, 0, singleListener, looper); } if (enabled == 0) { for (var i = 0; i < _providers.Length; ++i) { _manager.RemoveUpdates(singleListener); } tcs.SetException(new GeolocationException(GeolocationError.PositionUnavailable)); return tcs.Task; } } catch (SecurityException ex) { tcs.SetException(new GeolocationException(GeolocationError.Unauthorized, ex)); return tcs.Task; } return singleListener.Task; } // If we're already listening, just use the current listener lock (_positionSync) { if (_lastPosition == null) { if (cancelToken != CancellationToken.None) { cancelToken.Register(() => tcs.TrySetCanceled()); } EventHandler<PositionEventArgs> gotPosition = null; gotPosition = (s, e) => { tcs.TrySetResult(e.Position); PositionChanged -= gotPosition; }; PositionChanged += gotPosition; } else { tcs.SetResult(_lastPosition); } } return tcs.Task; }
/// <summary> /// Gets the position asynchronous. /// </summary> /// <param name="timeout">The timeout.</param> /// <param name="cancelToken">The cancel token.</param> /// <param name="includeHeading">if set to <c>true</c> [include heading].</param> /// <returns>Task<Position>.</returns> /// <exception cref="System.ArgumentOutOfRangeException">timeout;timeout must be greater than or equal to 0</exception> public Task <Position> GetPositionAsync(int timeout, CancellationToken cancelToken, bool includeHeading) { if (timeout <= 0 && timeout != Timeout.Infinite) { throw new ArgumentOutOfRangeException("timeout", "timeout must be greater than or equal to 0"); } var tcs = new TaskCompletionSource <Position>(); if (!IsListening) { GeolocationSingleListener singleListener = null; singleListener = new GeolocationSingleListener( (float)DesiredAccuracy, timeout, _providers.Where(_manager.IsProviderEnabled), () => { for (var i = 0; i < _providers.Length; ++i) { _manager.RemoveUpdates(singleListener); } }); if (cancelToken != CancellationToken.None) { cancelToken.Register( () => { singleListener.Cancel(); for (var i = 0; i < _providers.Length; ++i) { _manager.RemoveUpdates(singleListener); } }, true); } try { var looper = Looper.MyLooper() ?? Looper.MainLooper; var enabled = 0; for (var i = 0; i < _providers.Length; ++i) { if (_manager.IsProviderEnabled(_providers[i])) { enabled++; } _manager.RequestLocationUpdates(_providers[i], 0, 0, singleListener, looper); } if (enabled == 0) { for (var i = 0; i < _providers.Length; ++i) { _manager.RemoveUpdates(singleListener); } tcs.SetException(new GeolocationException(GeolocationError.PositionUnavailable)); return(tcs.Task); } } catch (SecurityException ex) { tcs.SetException(new GeolocationException(GeolocationError.Unauthorized, ex)); return(tcs.Task); } return(singleListener.Task); } // If we're already listening, just use the current listener lock (_positionSync) { if (_lastPosition == null) { if (cancelToken != CancellationToken.None) { cancelToken.Register(() => tcs.TrySetCanceled()); } EventHandler <PositionEventArgs> gotPosition = null; gotPosition = (s, e) => { tcs.TrySetResult(e.Position); PositionChanged -= gotPosition; }; PositionChanged += gotPosition; } else { tcs.SetResult(_lastPosition); } } return(tcs.Task); }