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 ), finishedCallback: () => { for(int i = 0; i < providers.Length; ++i) { manager.RemoveUpdates( singleListener ); } } ); if(cancelToken != CancellationToken.None) { cancelToken.Register( () => { singleListener.Cancel(); for(int i = 0; i < providers.Length; ++i) { manager.RemoveUpdates( singleListener ); } }, true ); } try { Looper looper = Looper.MyLooper() ?? Looper.MainLooper; int enabled = 0; for(int i = 0; i < providers.Length; ++i) { if(manager.IsProviderEnabled( providers[i] )) { enabled++; } manager.RequestLocationUpdates( providers[i], 0, 0, singleListener, looper ); } if(enabled == 0) { for(int 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; }
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, this.providers.Where(this.manager.IsProviderEnabled), finishedCallback: () => { for (int i = 0; i < this.providers.Length; ++i) { this.manager.RemoveUpdates(singleListener); } }); if (cancelToken != CancellationToken.None) { cancelToken.Register(() => { singleListener.Cancel(); for (int i = 0; i < this.providers.Length; ++i) { this.manager.RemoveUpdates(singleListener); } }, true); } try { Looper looper = Looper.MyLooper() ?? Looper.MainLooper; int enabled = 0; for (int i = 0; i < this.providers.Length; ++i) { if (this.manager.IsProviderEnabled(this.providers[i])) { enabled++; } this.manager.RequestLocationUpdates(this.providers[i], 0, 0, singleListener, looper); } if (enabled == 0) { for (int i = 0; i < this.providers.Length; ++i) { this.manager.RemoveUpdates(singleListener); } tcs.SetException(new GeolocationException(GeolocationError.PositionUnavailable)); return(tcs.Task); } } catch (Java.Lang.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 (this.positionSync) { if (this.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(this.lastPosition); } } return(tcs.Task); }