/// <inheritdoc/> public Task<Position> GetPositionAsync (int timeout = Timeout.Infinite, CancellationToken? cancelToken = null, bool includeHeading = false) { if (!CheckPermission("android.permission.ACCESS_COARSE_LOCATION")) { Console.WriteLine("Unable to get location, ACCESS_COARSE_LOCATION not set."); return null; } if (!CheckPermission("android.permission.ACCESS_FINE_LOCATION")) { Console.WriteLine("Unable to get location, ACCESS_FINE_LOCATION not set."); return null; } if (timeout <= 0 && timeout != Timeout.Infinite) throw new ArgumentOutOfRangeException ("timeout", "timeout must be greater than or equal to 0"); if (!cancelToken.HasValue) cancelToken = CancellationToken.None; 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.Value.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.Value.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; }
/// <inheritdoc/> public Task <Position> GetPositionAsync(int timeoutMilliseconds = Timeout.Infinite, CancellationToken?cancelToken = null, bool includeHeading = false) { if (!CheckPermission("android.permission.ACCESS_COARSE_LOCATION")) { Console.WriteLine("Unable to get location, ACCESS_COARSE_LOCATION not set."); return(null); } if (!CheckPermission("android.permission.ACCESS_FINE_LOCATION")) { Console.WriteLine("Unable to get location, ACCESS_FINE_LOCATION not set."); return(null); } if (timeoutMilliseconds <= 0 && timeoutMilliseconds != Timeout.Infinite) { throw new ArgumentOutOfRangeException("timeoutMilliseconds", "timeout must be greater than or equal to 0"); } if (!cancelToken.HasValue) { cancelToken = CancellationToken.None; } var tcs = new TaskCompletionSource <Position>(); if (!IsListening) { GeolocationSingleListener singleListener = null; singleListener = new GeolocationSingleListener((float)DesiredAccuracy, timeoutMilliseconds, 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.Value.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.Value.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); }