Version 3.0.381

This commit is contained in:
Anja 2024-04-09 12:53:23 +02:00
parent f963c0a219
commit 3a363acf3a
1525 changed files with 60589 additions and 125098 deletions

View file

@ -0,0 +1,35 @@
using System;
namespace ShareeBike.Services.Geolocation
{
public class Geolocation : IGeolocation
{
private Geolocation() { }
public DateTimeOffset Timestamp { get; private set; }
public double Latitude { get; private set; }
public double Longitude { get; private set; }
public double? Accuracy { get; private set; }
public class Builder
{
public DateTimeOffset Timestamp { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double? Accuracy { get; set; }
public Geolocation Build()
=> new Geolocation() {
Timestamp = Timestamp,
Latitude = Latitude,
Longitude = Longitude,
Accuracy = Accuracy};
}
}
}

View file

@ -0,0 +1,13 @@
using ShareeBike.Model.Device;
using Xamarin.Essentials;
namespace ShareeBike.Services.Geolocation
{
public class GeolocationAccuracyBestService : GeolocationService
{
public GeolocationAccuracyBestService(IGeolodationDependent dependent) : base(
dependent, GeolocationAccuracy.Best)
{
}
}
}

View file

@ -0,0 +1,13 @@
using ShareeBike.Model.Device;
using Xamarin.Essentials;
namespace ShareeBike.Services.Geolocation
{
public class GeolocationAccuracyHighService : GeolocationService
{
public GeolocationAccuracyHighService(IGeolodationDependent dependent) : base(
dependent, GeolocationAccuracy.High)
{
}
}
}

View file

@ -0,0 +1,13 @@
using ShareeBike.Model.Device;
using Xamarin.Essentials;
namespace ShareeBike.Services.Geolocation
{
public class GeolocationAccuracyMediumService : GeolocationService
{
public GeolocationAccuracyMediumService(IGeolodationDependent dependent) : base(
dependent, GeolocationAccuracy.Medium)
{
}
}
}

View file

@ -0,0 +1,69 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
using ShareeBike.Model.Device;
using Xamarin.Essentials;
namespace ShareeBike.Services.Geolocation
{
public abstract class GeolocationService : IGeolocationService
{
/// <summary> Timeout for geolocation request operations.</summary>
private const int GEOLOCATIONREQUEST_TIMEOUT_MS = 10000;
private IGeolodationDependent Dependent { get; }
private GeolocationAccuracy Accuracy { get; }
public GeolocationService(
IGeolodationDependent dependent,
GeolocationAccuracy accuracy = GeolocationAccuracy.Default)
{
Dependent = dependent;
Accuracy = accuracy;
}
public bool IsSimulation => false;
public bool IsGeolcationEnabled => Dependent.IsGeolcationEnabled;
/// <summary> Gets the current location.</summary>
/// <param name="cancellationToken">Token to cancel request for geolocation.</param>
/// <param name="timeStamp">Time when geolocation is of interest. Is used to determine whether cached geolocation can be used or not.</param>
public async Task<IGeolocation> GetAsync(CancellationToken? cancellationToken = null, DateTime? timeStamp = null)
{
try
{
var request = new GeolocationRequest(Accuracy, TimeSpan.FromMilliseconds(GEOLOCATIONREQUEST_TIMEOUT_MS));
return cancellationToken.HasValue
? (await Xamarin.Essentials.Geolocation.GetLocationAsync(request, cancellationToken.Value)).ToGeolocation()
: (await Xamarin.Essentials.Geolocation.GetLocationAsync(request)).ToGeolocation();
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
Log.ForContext<GeolocationService>().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<GeolocationService>().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<GeolocationService>().Error("Retrieving Geolocation not permitted on device. {Exception}", pEx);
throw new Exception("Berechtigung für Abfrage Standort nicht erteilt für App.", pEx);
}
catch (Exception ex)
{
// Unable to get location
Log.ForContext<GeolocationService>().Error("Retrieving Geolocation failed. {Exception}", ex);
throw new Exception("Abfrage Standort fehlgeschlagen.", ex);
}
}
}
}

View file

@ -0,0 +1,15 @@
using System;
namespace ShareeBike.Services.Geolocation
{
public interface IGeolocation
{
double Latitude { get; }
double Longitude { get; }
double? Accuracy { get; }
DateTimeOffset Timestamp { get; }
}
}

View file

@ -0,0 +1,20 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using ShareeBike.Model.Device;
namespace ShareeBike.Services.Geolocation
{
/// <summary> Query geolocation. </summary>
public interface IGeolocationService : IGeolodationDependent
{
/// <summary> Gets the current location.</summary>
/// <param name="cancellationToken">Token to cancel request for geolocation. If null request can not be cancels and times out after GeolocationService.GEOLOCATIONREQUEST_TIMEOUT_MS if geolocation is not available.</param>
/// <param name="timeStamp">Time when geolocation is of interest. Is used to determine for some implementations whether cached geolocation can be used or not.</param>
/// <returns></returns>
Task<IGeolocation> GetAsync(CancellationToken? cancellationToken = null, DateTime? timeStamp = null);
/// <summary> If true location data returned is simulated.</summary>
bool IsSimulation { get; }
}
}

View file

@ -0,0 +1,72 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
using ShareeBike.Model.Device;
using Xamarin.Essentials;
namespace ShareeBike.Services.Geolocation
{
public class LastKnownGeolocationService : IGeolocationService
{
private IGeolodationDependent Dependent { get; }
public LastKnownGeolocationService(IGeolodationDependent dependent)
{
Dependent = dependent;
}
/// <summary> Gets the current location.</summary>
/// <param name="cancelationToken">Token to cancel request for geolocation.</param>
/// <param name="timeStamp">Time when geolocation is of interest. Is used to determine whether cached geolocation can be used or not.</param>
public async Task<IGeolocation> 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<LastKnownGeolocationService>().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<LastKnownGeolocationService>().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<LastKnownGeolocationService>().Error("Retrieving Geolocation not permitted on device. {Exception}", pEx);
throw new Exception("Berechtigung für Abfrage Standort nicht erteilt für App.", pEx);
}
catch (Exception ex)
{
// Unable to get location
Log.ForContext<LastKnownGeolocationService>().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);
}
/// <summary> If true location data returned is simulated.</summary>
public bool IsSimulation { get => false; }
/// <summary> Maximum age allowed for location info. </summary>
public TimeSpan MaxAge => new TimeSpan(0, 3 /*minutes*/, 0);
public bool IsGeolcationEnabled => Dependent.IsGeolcationEnabled;
}
}

View file

@ -0,0 +1,21 @@
using Xamarin.Essentials;
namespace ShareeBike.Services.Geolocation
{
public static class LocationHelper
{
/// <summary>
/// Converts Xamarin.Essentials Location object to Geolocatin object.
/// </summary>
/// <param name="location"></param>
/// <returns></returns>
public static IGeolocation ToGeolocation(this Location location)
=> new Geolocation.Builder
{
Latitude = location.Latitude,
Longitude = location.Longitude,
Accuracy = location.Accuracy,
Timestamp = location.Timestamp,
}.Build();
}
}

View file

@ -0,0 +1,35 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using ShareeBike.Model.Device;
using Xamarin.Essentials;
namespace ShareeBike.Services.Geolocation
{
public class SimulatedGeolocationService : IGeolocationService
{
private IGeolodationDependent Dependent { get; }
public SimulatedGeolocationService(IGeolodationDependent dependent)
{
Dependent = dependent;
}
/// <summary> Gets the current location.</summary>
/// <param name="cancelToken">Token to cancel request for geolocation.</param>
/// <param name="timeStamp">Time when geolocation is of interest. Is used to determine whether cached geolocation can be used or not.</param>
public async Task<IGeolocation> GetAsync(CancellationToken? cancelToken = null, DateTime? timeStamp = null)
{
return await Task.FromResult(new Geolocation.Builder {
Latitude = 47.976634,
Longitude = 7.825490,
Accuracy = 0,
Timestamp = timeStamp ?? DateTime.Now }.Build()); ;
}
/// <summary> If true location data returned is simulated.</summary>
public bool IsSimulation { get => true; }
public bool IsGeolcationEnabled => Dependent.IsGeolcationEnabled;
}
}