Геолокация Xamarin Essentials не работает, GetLocationAsync не работает

Поэтому я хочу узнать местоположение пользователей и изменить геокодирование, чтобы получить адрес и номер улицы.

Поэтому я установил пакет Xamarin.Essentials, который находится в предварительной версии. Я хотел использовать API геолокации и геокодирования, поэтому я написал некоторый код, но код никогда не достигает if (location != null) в попытке GetCurrentLocation.

Я не думаю, что имеет значение, что Xamarin.Essentials находится в предварительной версии, основываясь на том, что сказал автор Xam.Plugin.Geolocator Джеймс Монтемагно:

Я буду продолжать работать и поддерживать свои плагины, но я рекомендую вам проверить Xamarin.Essentials, чтобы увидеть, подходит ли оно вашему приложению так же, как и для всех моих!

Источник: https://github.com/jamesmontemagno/GeolocatorPlugin

Что я сделал?

Я искал вопросы Stackru о проблеме, с которой я столкнулся, но я не могу найти такой, который может помочь мне, насколько я знаю.

Вопросы, на которые я смотрел:

Я также попытался, если добавление тайм-аута будет работать: var request = new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue );

Но у меня возникла такая же проблема с локацией так же быстро. Он никогда не доходил до утверждения if.

Мой код:

FillInLocationInForm(); устанавливается в конструкторе моей страницы.

public Location location; а также public Placemark placemark; устанавливаются в классе Page.

Это соответствующие функции в классе Page:

public async void FillInLocationInForm()
    {
        if (await GetCurrentLocation())
        {
            if (await ReverseGeocodeLocation())
            {
                await this.DisplayAlert("Location", placemark.AdminArea + " " + placemark.FeatureName + " " + placemark.Locality + " " + placemark.SubLocality + " " + placemark.SubAdminArea + " " + placemark.SubThoroughfare + " " + placemark.Thoroughfare, "Okay", "Okay");
            }
        }           
    }

public async Task<bool> GetCurrentLocation ()
    {
        try
        {
            var request = new GeolocationRequest(GeolocationAccuracy.Medium);
            var location = await Geolocation.GetLocationAsync(request);

            if (location != null)
            {                    
                this.location = location;
                return await Task.FromResult(true);
            }
        }
        catch (FeatureNotSupportedException fnsEx)
        {
            // Handle not supported on device exception               
        }
        catch (PermissionException pEx)
        {
            // Handle permission exception                
        }
        catch (Exception ex)
        {
            // Unable to get location              
        }
        return await Task.FromResult(false);
    }

public async Task<bool> ReverseGeocodeLocation()
    {
        try
        {
            var lat = location.Latitude;
            var lon = location.Longitude;

            var placemarks = await Geocoding.GetPlacemarksAsync(lat, lon);

            var placemark = placemarks?.FirstOrDefault();
            if (placemark != null)
            {
                //var geocodeAddress =
                //    $"AdminArea:       {placemark.AdminArea}\n" +
                //    $"CountryCode:     {placemark.CountryCode}\n" +
                //    $"CountryName:     {placemark.CountryName}\n" +
                //    $"FeatureName:     {placemark.FeatureName}\n" +
                //    $"Locality:        {placemark.Locality}\n" +
                //    $"PostalCode:      {placemark.PostalCode}\n" +
                //    $"SubAdminArea:    {placemark.SubAdminArea}\n" +
                //    $"SubLocality:     {placemark.SubLocality}\n" +
                //    $"SubThoroughfare: {placemark.SubThoroughfare}\n" +
                //    $"Thoroughfare:    {placemark.Thoroughfare}\n";

                //Console.WriteLine(geocodeAddress);
                this.placemark = placemark;
                return await Task.FromResult(true);
            }
        }
        catch (FeatureNotSupportedException fnsEx)
        {
            // Feature not supported on device
        }
        catch (Exception ex)
        {
            // Handle exception that may have occurred in geocoding
        }
        return await Task.FromResult(false);
    }

Я также добавил эти разрешения в свои приложения AndroidManifest и запрашивал их во время выполнения. Я видел расположение и хранилище, оба выбранные в настройках моего приложения.

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />

Документация, которой я следую:

Любая помощь приветствуется.

Редактировать:

У меня есть догадка, мне нужно добавить токен отмены в GetLocationAsyncно я пока не знаю как. Я не вижу его рядом с GeolocationRequest:

Изменить 2:

Я добавил CancellationToken, но оператор if все еще не достигнут. Возможно я не использую это прямо сейчас.

using System.Threading; // add above

CancellationTokenSource source = new CancellationTokenSource();
CancellationToken cancelToken = source.Token;
var location = await Geolocation.GetLocationAsync(request, cancelToken);

Изменить 3:

Точка останова на изображении ниже никогда не срабатывает, что означает, что оператор if никогда не достигается. Каким-то образом код выходит из попытки, но не входит ни в один из операторов catch. Я использую Console.WriteLine() в моих заявлениях поймать сейчас. Я ничего не вижу в моем журнале устройства. Я проверил Console.WriteLine() из подвоха, который я видел в журнале устройства.

2 ответа

Решение

Очевидно, я не ждал достаточно долго. Как сказал Джейсон.

Моя первая попытка добавить тайм-аут была:

new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue);

Каким-то образом строка выше линии не работает.

В любом случае добавление временного интервала в 10 секунд дало мне местоположение:

var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));       

В моей ситуации помогло включить опцию телефона «Повысить точность» в настройках «Местоположение»; по крайней мере для андроида.

Другие вопросы по тегам