using Serilog; using System; using System.Threading.Tasks; using TINK.Model.Device; using Xamarin.Essentials; namespace TINK.Model.Services.Geolocation { public class LastKnownGeolocationService : IGeolocation { /// Timeout for geolocation request operations. private const int GEOLOCATIONREQUEST_TIMEOUT_MS = 5000; private IGeolodationDependent Dependent { get; } public LastKnownGeolocationService(IGeolodationDependent dependent) { Dependent = dependent; } /// Time when geolocation is of interest. Is used to determine whether cached geoloation can be used or not. public async Task GetAsync(DateTime? timeStamp = null) { Location location; try { var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromMilliseconds(GEOLOCATIONREQUEST_TIMEOUT_MS)); location = await Xamarin.Essentials.Geolocation.GetLocationAsync(request); } catch (FeatureNotSupportedException fnsEx) { // Handle not supported on device exception Log.ForContext().Error("Retrieving Geolocation not supported on device. {Exception}", fnsEx); throw new Exception("Abfrage Standort nicht möglich auf Gerät.", fnsEx); } catch (FeatureNotEnabledException fneEx) { // Handle not enabled on device exception Log.ForContext().Error("Retrieving Geolocation not enabled on device. {Exception}", fneEx); throw new Exception("Abfrage Standort nicht aktiviert auf Gerät.", fneEx); } catch (PermissionException pEx) { // Handle permission exception Log.ForContext().Error("Retrieving Geolocation not permitted on device. {Exception}", pEx); throw new Exception("Berechtiung für Abfrage Standort nicht erteilt für App.", pEx); } catch (Exception ex) { // Unable to get location Log.ForContext().Error("Retrieving Geolocation failed. {Exception}", ex); throw new Exception("Abfrage Standort fehlgeschlagen.", ex); } if (location != null // Cached location is available. && (timeStamp == null || timeStamp.Value.Subtract(location.Timestamp.DateTime) < MaxAge)) { // No time stamp available or location not too old. return location; } return await Xamarin.Essentials.Geolocation.GetLocationAsync(); } /// If true location data returned is simulated. public bool IsSimulation { get => false; } public TimeSpan MaxAge => new TimeSpan(0, 3, 0); public bool IsGeolcationEnabled => Dependent.IsGeolcationEnabled; } }