Исключение разрешения Geolocation GetLastKnownLocationAsync() из форм Xamarin - сбой вызова и отсутствие запроса на разрешение
Сбой GetLocationAsync в моем приложении Xamarin.Forms.
У меня последняя версия пакета Nua Xamarin.Essentials.
Я установил необходимые разрешения в info.plist.
Я звоню это из моей ViewModel.
Звонок очень прост:
var location = await Geolocation.GetLastKnownLocationAsync();
но он не работает и не выводит диалоговое окно с разрешениями пользователя, даже если мой info.plist был правильно настроен с помощью: NSLocationWhenInUseUsageDescription Вставить причину
Я спрашиваю и отвечаю на этот вопрос, потому что это был головной убор, и я не был точно уверен, что искать или в чем проблема.
Мои различные поиски указывали на многие связанные проблемы, но ничего, что на самом деле не доходило до основной проблемы.
Самым близким, что я получил, была эта проблема на странице github Essentials: https://github.com/xamarin/Essentials/issues/634
1 ответ
Этот ответ вдохновлен евангелистом Xamarin/Azure, Брэндоном Минником -> взгляните на его проект, где он обрабатывает похожую ситуацию с помощью следующего кода:
Итак, что мы можем отнять у вышесказанного? Если вы посмотрите на контекст, он соединил свои виды с моделями представления в стиле MVVM. Однако различные библиотеки требуют, чтобы определенные методы вызывались из основного потока. В этом суть проблемы, и именно это может решить этот код.
Поэтому, чтобы принять приведенный выше код для проблемы геолокации, рассматриваемой в этом вопросе, я сделал следующее:
Task<Xamarin.Essentials.Location> GetLocationFromPhone()
{
var locationTaskCompletionSource = new TaskCompletionSource<Xamarin.Essentials.Location>();
Device.BeginInvokeOnMainThread(async () =>
{
locationTaskCompletionSource.SetResult(await Geolocation.GetLastKnownLocationAsync());
});
return locationTaskCompletionSource.Task;
}
Я использую выше из моей ViewModel из задачи. Что-то вроде следующего.
async Task ExecuteGetGeoLocationCommand()
{
try
{
var locationFromPhone = await GetLocationFromPhone().ConfigureAwait(false);
if (locationFromPhone is null)
return;
_location = locationFromPhone;
if (_location != null)
{
Console.WriteLine($"Latitude: {_location.Latitude}, Longitude {_location.Longitude}, Altitude: {_location.Altitude}");
}
else
{
Console.WriteLine($"Exiting geolocation");
}
catch (FeatureNotSupportedException fnsEx)
{
}
catch (Exception ex)
{
}
}
}
Я надеюсь, что это полезно для кого-то еще!
Если вы используете Xamarin.Essentials и не запрашиваете разрешение на Android, убедитесь, что вы добавили весь необходимый код в основное действие Android.
Подробнее см. https://docs.microsoft.com/en-us/xamarin/essentials/get-started?tabs=windows%2Candroid.
Из документов:
protected override void OnCreate(Bundle savedInstanceState) {
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
а также
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}