Я хочу узнать позицию пользователя, поэтому использую подключаемый модуль Geolocator Джеймса Монтемагно для Xamarin. Автор использует этот код в файле code-behind.cs; Я извлек его в статический класс:
public static class GeoService
{
public static Position savedPosition;
public static async Task<Position> GetPosition()
{
var lastknown = await ExecuteLastKnownPosition();
if(lastknown == null)
{
var current = await ExecuteGPSPosition();
if(current != null)
{
return current;
}
else
{
return null;
}
}
return lastknown;
}
private static async Task<Position> ExecuteLastKnownPosition()
{
try
{
var hasPermission = await Utils.CheckPermissions(Permission.Location);
if (!hasPermission)
return null;
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
//Progress Ring einfügen
var position = await locator.GetLastKnownLocationAsync();
if (position == null)
{
//Benachrichtigung über null lastknownLocation
//Aufrufen der CurrentPosition Methode
return null;
}
savedPosition = position;
return position;
}
catch (Exception ex)
{
Debug.WriteLine(ex);
await Application.Current.MainPage.DisplayAlert("Uh oh", "Something went wrong, but don't worry we captured for analysis! Thanks.", "OK");
return null;
}
finally
{
//Freigabe der Buttons und Bools
}
}
private static async Task<Position> ExecuteGPSPosition()
{
try
{
var hasPermission = await Utils.CheckPermissions(Permission.Location);
if (!hasPermission)
return null;
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 100;
//WarteText/Symbol
var position = await locator.GetPositionAsync(TimeSpan.FromSeconds(15));
if (position == null)
{
//Warnung, dass kein GPS vorhanden ist
return null;
}
savedPosition = position;
return position;
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Uh oh", "Something went wrong, but don't worry we captured for analysis! Thanks.", "OK");
return null;
}
finally
{
//Zurücksetzen von Buttons und Lademodus beenden
}
}
public static async Task<Address> ExecuteTrackingAdress(Position currentPosition)
{
try
{
//if (savedPosition == null)
// return null;
var hasPermission = await Utils.CheckPermissions(Permission.Location);
if (!hasPermission)
return null;
string mapkey = "Ajbb9XXXXXXatUzUg1w9BSXXXXXVUAEuF4P-TSXJpnvl5OpXXXXXXXXX";
var locator = CrossGeolocator.Current;
var addresses = await locator.GetAddressesForPositionAsync(currentPosition, mapkey);
var address = addresses.FirstOrDefault();
if (address == null)
{
Debug.WriteLine("Keine Adresse vorhanden");
}
return address;
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Uh oh", "Something went wrong, but don't worry we captured for analysis! Thanks.", "OK");
return null;
}
finally
{
}
}
}
Теперь у меня есть ContentPage, и когда я перехожу на эту страницу (PushModalAsync), конструктор в модели представления вызывает метод GetPosition()
. Есть задача разрешения, и всякий раз, когда задача выполняется, UWP предлагает мне запрашивать разрешение на местоположение.
К сожалению, с этого момента приложение зависает. Я не могу выбрать Да / Нет, и нет способа взаимодействия.
Я пробовал вызывать методы async, с Task.WhenAll()
и так далее, но каждый раз он зависает.
Это был последний код, который я написал в моей модели представления.
private async void ExecuteGetPosition()
{
IsBusy = true;
await Task.Yield();
var positiontask = GeoService.GetPosition();
var addresstask = GeoService.ExecuteTrackingAdress(positiontask.Result);
await Task.WhenAll(positiontask, addresstask);
CurrentPosition = positiontask.Result;
CurrentAddress = addresstask.Result;
OnPropertyChanged("CurrentAddressView");
IsBusy = false;
}
Я предполагаю, что XAML ContentPage еще не загружен правильно, и поэтому окно подсказки скользит «за» MainWindow или чем-то в этом роде.
Не могли бы вы дать мне идею обходного пути, чтобы справиться с этим?
Изменить: добавление этих строк в мой App.xaml.cs OnStart () - метод принес решение. Windows сейчас запрашивает разрешение OnStart, Android запрашивает разрешение на gps-запрос ... сумасшедший:
var permission = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);