From c10ccc1d5fd1b84e53ecbe552d09ead4b1184a1f Mon Sep 17 00:00:00 2001 From: James Montemagno Date: Fri, 24 Aug 2018 07:24:15 -0700 Subject: [PATCH] GH-476: Put in checks to see if location services are enabled. (#488) * Put in checks to see if location services are enabled. * iOS check to see if location services are enabled. --- .../Geolocation/Geolocation.android.cs | 7 +++++++ .../Geolocation/Geolocation.ios.cs | 9 ++++++--- .../Geolocation/Geolocation.uwp.cs | 12 ++++++++++++ .../Types/Shared/Exceptions.shared.cs | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Xamarin.Essentials/Geolocation/Geolocation.android.cs b/Xamarin.Essentials/Geolocation/Geolocation.android.cs index 837b5a98c..36ab090aa 100644 --- a/Xamarin.Essentials/Geolocation/Geolocation.android.cs +++ b/Xamarin.Essentials/Geolocation/Geolocation.android.cs @@ -15,6 +15,7 @@ namespace Xamarin.Essentials public static partial class Geolocation { const long twoMinutes = 120000; + static readonly string[] ignoredProviders = new string[] { LocationManager.PassiveProvider, "local_database" }; static async Task PlatformLastKnownLocationAsync() { @@ -40,6 +41,12 @@ static async Task PlatformLocationAsync(GeolocationRequest request, Ca 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); diff --git a/Xamarin.Essentials/Geolocation/Geolocation.ios.cs b/Xamarin.Essentials/Geolocation/Geolocation.ios.cs index adda3867f..cf164a36c 100644 --- a/Xamarin.Essentials/Geolocation/Geolocation.ios.cs +++ b/Xamarin.Essentials/Geolocation/Geolocation.ios.cs @@ -9,11 +9,11 @@ namespace Xamarin.Essentials { public static partial class Geolocation { - internal static bool IsSupported - => CLLocationManager.LocationServicesEnabled; - static async Task PlatformLastKnownLocationAsync() { + if (!CLLocationManager.LocationServicesEnabled) + throw new FeatureNotEnabledException("Location services are not enabled on device."); + await Permissions.RequireAsync(PermissionType.LocationWhenInUse); var manager = new CLLocationManager(); @@ -24,6 +24,9 @@ static async Task PlatformLastKnownLocationAsync() static async Task PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken) { + if (!CLLocationManager.LocationServicesEnabled) + throw new FeatureNotEnabledException("Location services are not enabled on device."); + await Permissions.RequireAsync(PermissionType.LocationWhenInUse); // the location manager requires an active run loop diff --git a/Xamarin.Essentials/Geolocation/Geolocation.uwp.cs b/Xamarin.Essentials/Geolocation/Geolocation.uwp.cs index af7f12f16..0e3dea887 100644 --- a/Xamarin.Essentials/Geolocation/Geolocation.uwp.cs +++ b/Xamarin.Essentials/Geolocation/Geolocation.uwp.cs @@ -32,11 +32,23 @@ static async Task PlatformLocationAsync(GeolocationRequest request, Ca DesiredAccuracyInMeters = request.PlatformDesiredAccuracy }; + CheckStatus(geolocator.LocationStatus); + cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout); var location = await geolocator.GetGeopositionAsync().AsTask(cancellationToken); return location?.Coordinate?.ToLocation(); + + void CheckStatus(PositionStatus status) + { + switch (status) + { + case PositionStatus.Disabled: + case PositionStatus.NotAvailable: + throw new FeatureNotEnabledException("Location services are not enabled on device."); + } + } } } } diff --git a/Xamarin.Essentials/Types/Shared/Exceptions.shared.cs b/Xamarin.Essentials/Types/Shared/Exceptions.shared.cs index ad88ca61f..462e767d5 100644 --- a/Xamarin.Essentials/Types/Shared/Exceptions.shared.cs +++ b/Xamarin.Essentials/Types/Shared/Exceptions.shared.cs @@ -34,4 +34,21 @@ public FeatureNotSupportedException(string message, Exception innerException) { } } + + public class FeatureNotEnabledException : InvalidOperationException + { + public FeatureNotEnabledException() + { + } + + public FeatureNotEnabledException(string message) + : base(message) + { + } + + public FeatureNotEnabledException(string message, Exception innerException) + : base(message, innerException) + { + } + } }