129 lines
4.2 KiB
C#
129 lines
4.2 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Billing.Models;
|
|
using Billing.UI;
|
|
using Xamarin.Essentials;
|
|
using Xamarin.Forms;
|
|
using Xamarin.Forms.Maps;
|
|
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
|
|
using Map = Xamarin.Forms.Maps.Map;
|
|
|
|
namespace Billing.Views
|
|
{
|
|
public class ViewLocationPage : BillingPage
|
|
{
|
|
public event EventHandler<Location> Synced;
|
|
|
|
private readonly Bill bill;
|
|
|
|
private CancellationTokenSource tokenSource;
|
|
|
|
public ViewLocationPage(Bill bill)
|
|
{
|
|
On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(false);
|
|
this.bill = bill;
|
|
Title = bill.Name;
|
|
|
|
ToolbarItems.Add(new ToolbarItem
|
|
{
|
|
IconImageSource = "location.png",
|
|
Order = ToolbarItemOrder.Primary,
|
|
Command = new Command(OnSynced)
|
|
});
|
|
|
|
if (bill.Latitude != null && bill.Longitude != null)
|
|
{
|
|
var (longitude, latitude) = (bill.Longitude.Value, bill.Latitude.Value).Wgs84ToGcj02();
|
|
var position = new Position(latitude, longitude);
|
|
var mapSpan = new MapSpan(position, 0.01, 0.01);
|
|
Content = new Map(mapSpan)
|
|
{
|
|
Pins =
|
|
{
|
|
new Pin
|
|
{
|
|
Label = bill.Name,
|
|
Type = PinType.Generic,
|
|
Position = position,
|
|
Address = bill.Store
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
protected override void OnDisappearing()
|
|
{
|
|
if (tokenSource != null && !tokenSource.IsCancellationRequested)
|
|
{
|
|
tokenSource.Cancel();
|
|
}
|
|
base.OnDisappearing();
|
|
}
|
|
|
|
private async void OnSynced()
|
|
{
|
|
if (Tap.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
using (Tap.Start())
|
|
{
|
|
if (tokenSource != null)
|
|
{
|
|
return;
|
|
}
|
|
var location = await GetCurrentLocation();
|
|
if (location != null)
|
|
{
|
|
Synced?.Invoke(this, location);
|
|
|
|
MainThread.BeginInvokeOnMainThread(() =>
|
|
{
|
|
var (longitude, latitude) = (location.Longitude, location.Latitude).Wgs84ToGcj02();
|
|
var position = new Position(latitude, longitude);
|
|
var mapSpan = new MapSpan(position, 0.01, 0.01);
|
|
Content = new Map(mapSpan)
|
|
{
|
|
Pins =
|
|
{
|
|
new Pin
|
|
{
|
|
Label = bill.Name,
|
|
Type = PinType.Generic,
|
|
Position = position,
|
|
Address = bill.Store
|
|
}
|
|
}
|
|
};
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task<Location> GetCurrentLocation()
|
|
{
|
|
try
|
|
{
|
|
var request = new GeolocationRequest(GeolocationAccuracy.Best, TimeSpan.FromSeconds(10));
|
|
tokenSource = new CancellationTokenSource();
|
|
var status = await Helper.CheckAndRequestPermissionAsync<Permissions.LocationWhenInUse>();
|
|
if (status != PermissionStatus.Granted)
|
|
{
|
|
return null;
|
|
}
|
|
return await Geolocation.GetLocationAsync(request, tokenSource.Token);
|
|
}
|
|
catch (FeatureNotSupportedException) { }
|
|
catch (FeatureNotEnabledException) { }
|
|
catch (PermissionException) { }
|
|
catch (Exception ex)
|
|
{
|
|
Helper.Error("location.get", ex);
|
|
}
|
|
tokenSource = null;
|
|
return null;
|
|
}
|
|
}
|
|
} |