97 lines
2.8 KiB
C#
97 lines
2.8 KiB
C#
using Microsoft.Maui.ApplicationModel;
|
|
using Microsoft.Maui.Devices.Sensors;
|
|
|
|
namespace LMEMappeCatastaliApp.Services;
|
|
|
|
public sealed class PreciseLocationService : IAsyncDisposable
|
|
{
|
|
private CancellationTokenSource? trackingCancellation;
|
|
|
|
public bool IsTracking => trackingCancellation is not null;
|
|
|
|
public async Task<PermissionStatus> EnsurePermissionAsync()
|
|
{
|
|
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
|
|
if (status != PermissionStatus.Granted)
|
|
{
|
|
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
public async Task StartTrackingAsync(Func<LocationSnapshot, Task> onLocation, Func<string, Task> onError)
|
|
{
|
|
if (trackingCancellation is not null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var permission = await EnsurePermissionAsync();
|
|
if (permission != PermissionStatus.Granted)
|
|
{
|
|
await onError("Permesso GPS non concesso.");
|
|
return;
|
|
}
|
|
|
|
trackingCancellation = new CancellationTokenSource();
|
|
var token = trackingCancellation.Token;
|
|
|
|
_ = Task.Run(async () =>
|
|
{
|
|
while (!token.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
var request = new GeolocationRequest(GeolocationAccuracy.Best, TimeSpan.FromSeconds(5));
|
|
var location = await Geolocation.Default.GetLocationAsync(request, token);
|
|
if (location is not null)
|
|
{
|
|
await onLocation(new LocationSnapshot(
|
|
location.Latitude,
|
|
location.Longitude,
|
|
location.Accuracy,
|
|
location.Altitude,
|
|
location.Course,
|
|
location.Speed,
|
|
location.Timestamp));
|
|
}
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
break;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await onError(ex.Message);
|
|
await Task.Delay(TimeSpan.FromSeconds(2), token);
|
|
}
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(1), token);
|
|
}
|
|
}, token);
|
|
}
|
|
|
|
public void StopTracking()
|
|
{
|
|
trackingCancellation?.Cancel();
|
|
trackingCancellation?.Dispose();
|
|
trackingCancellation = null;
|
|
}
|
|
|
|
public ValueTask DisposeAsync()
|
|
{
|
|
StopTracking();
|
|
return ValueTask.CompletedTask;
|
|
}
|
|
}
|
|
|
|
public sealed record LocationSnapshot(
|
|
double Latitude,
|
|
double Longitude,
|
|
double? Accuracy,
|
|
double? Altitude,
|
|
double? Course,
|
|
double? Speed,
|
|
DateTimeOffset Timestamp);
|