using System;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
using TINK.Model.Device;
using Xamarin.Essentials;
namespace TINK.Services.Geolocation
{
public class LastKnownGeolocationService : IGeolocationService
{
private IGeolodationDependent Dependent { get; }
public LastKnownGeolocationService(IGeolodationDependent dependent)
{
Dependent = dependent;
}
/// Gets the current location.
/// Token to cancel request for geolocation.
/// Time when geolocation is of interest. Is used to determine whether cached geolocation can be used or not.
public async Task GetAsync(CancellationToken? cancelationToken = null, DateTime? timeStamp = null)
{
IGeolocation location;
try
{
location = (await Xamarin.Essentials.Geolocation.GetLastKnownLocationAsync()).ToGeolocation();
}
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 new GeolocationAccuracyMediumService(Dependent).GetAsync(cancelationToken, timeStamp);
}
/// If true location data returned is simulated.
public bool IsSimulation { get => false; }
/// Maximum age allowed for location info.
public TimeSpan MaxAge => new TimeSpan(0, 3 /*minutes*/, 0);
public bool IsGeolcationEnabled => Dependent.IsGeolcationEnabled;
}
}