Исключение разрешения 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);
}
Другие вопросы по тегам