static async Task <Location> PlatformLastKnownLocationAsync() { await Permissions.EnsureGrantedOrRestrictedAsync <Permissions.LocationWhenInUse>(); var lm = Platform.LocationManager; AndroidLocation bestLocation = null; foreach (var provider in lm.GetProviders(true)) { var location = lm.GetLastKnownLocation(provider); if (location != null && IsBetterLocation(location, bestLocation)) { bestLocation = location; } } return(bestLocation?.ToLocation()); }
static async Task <Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken) { await Permissions.EnsureGrantedOrRestrictedAsync <Permissions.LocationWhenInUse>(); var locationManager = Platform.LocationManager; var enabledProviders = locationManager.GetProviders(true); var hasProviders = enabledProviders.Any(p => !ignoredProviders.Contains(p)); if (!hasProviders) { throw new FeatureNotEnabledException("Location services are not enabled on device."); } // get the best possible provider for the requested accuracy var providerInfo = GetBestProvider(locationManager, request.DesiredAccuracy); // if no providers exist, we can't get a location // let's punt and try to get the last known location if (string.IsNullOrEmpty(providerInfo.Provider)) { return(await GetLastKnownLocationAsync()); } var tcs = new TaskCompletionSource <AndroidLocation>(); var allProviders = locationManager.GetProviders(false); var providers = new List <string>(); if (allProviders.Contains(LocationManager.GpsProvider)) { providers.Add(LocationManager.GpsProvider); } if (allProviders.Contains(LocationManager.NetworkProvider)) { providers.Add(LocationManager.NetworkProvider); } if (providers.Count == 0) { providers.Add(providerInfo.Provider); } var listener = new SingleLocationListener(locationManager, providerInfo.Accuracy, providers); listener.LocationHandler = HandleLocation; cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout); cancellationToken.Register(Cancel); // start getting location updates // make sure to use a thread with a looper var looper = Looper.MyLooper() ?? Looper.MainLooper; foreach (var provider in providers) { locationManager.RequestLocationUpdates(provider, 0, 0, listener, looper); } var androidLocation = await tcs.Task; if (androidLocation == null) { return(null); } return(androidLocation.ToLocation()); void HandleLocation(AndroidLocation location) { RemoveUpdates(); tcs.TrySetResult(location); } void Cancel() { RemoveUpdates(); tcs.TrySetResult(listener.BestLocation); } void RemoveUpdates() { for (var i = 0; i < providers.Count; i++) { locationManager.RemoveUpdates(listener); } } }