【问题标题】:Xamarin essentials geolocation is not working, GetLocationAsync breaks out of tryXamarin Essentials 地理定位不起作用,GetLocationAsync 中断尝试
【发布时间】:2018-10-17 13:12:57
【问题描述】:

所以我想获取用户的位置并对其进行反向地理编码以获取地址和门牌号。

因此,我安装了预发布的包 Xamarin.Essentials。我想使用地理定位和地理编码 API,所以我写了一些代码,但代码在 GetCurrentLocation 的尝试中从未到达if (location != null)。

根据 Xam.Plugin.Geolocator 作者 James Montemagno 所说,我认为 Xamarin.Essentials 处于预发布状态并不重要:

我将继续工作和维护我的插件,但我建议您查看 Xamarin.Essentials,看看它是否非常适合您的应用程序,因为它一直适用于我的所有应用程序!

来源:https://github.com/jamesmontemagno/GeolocatorPlugin

我做了什么?

我已经搜索了有关我遇到的问题的 StackOverflow 问题,但据我所知,我找不到可以帮助我的问题。

我看过的问题:

我也尝试过添加超时是否可行:var request = new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue );

但我在该位置上也遇到了同样的问题。它从未到达 if 语句。

我的代码:

FillInLocationInForm(); 在我的 Page 构造函数中设置。

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 语句。我现在在我的 catch 语句中使用 Console.WriteLine()。我在设备日志中看不到任何内容。我在设备日志中看到的捕获中测试了Console.WriteLine()。

【问题讨论】:

  • 在你的截图中,断点在第一行,这意味着它还没有执行,所以当然变量是空的。如果你跳到下一行,request 还是 null 吗?
  • 您是否明确授予您的应用位置权限?如果您进入手机设置 -> 应用程序 -> [应用程序名称] -> 权限,是否启用了位置?
  • @Jason 请求毕竟包含一些东西。我已经改变了我的问题。代码永远不会进入if (location != null)。 @Tom 我已经看到启用了位置。
  • 你等了多久?你确定没有抛出异常 - 你正在捕获异常但没有对它们做任何事情。您是在设备还是模拟器上进行测试?
  • 我的 maxvalue 超时:new GeolocationRequest(GeolocationAccuracy.Medium, timeout: TimeSpan.MaxValue );,但我看到代码继续运行,因为我在 if (await ReverseGeocodeLocation()) 有一个断点,但从未到达该断点。我也没有例外。我在每个 Catch 中添加了一个 DisplayAlert,但没有一个被解雇。我正在真实设备上进行测试。

标签: c# android xamarin xamarin.forms xamarin.essentials


【解决方案1】:

显然,我没有等待足够长的时间。就像杰森说的那样。

我第一次尝试添加超时是:

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

不知何故,上面的行不起作用。

无论如何添加 10 秒的时间跨度给了我一个位置:

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

【讨论】:

  • 超时似乎真的很重要,因为如果你不指定超时,它不会第二次起作用。
  • 这似乎对函数有时工作至关重要。
【解决方案2】:

在我的情况下,在位置设置下打开手机的“提高准确性”选项很有帮助;至少对于 Android 来说是这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    相关资源
    最近更新 更多