2

GetLocationAsync 在我的 Xamarin.Forms 应用上失败。

我有最新的 Xamarin.Essentials nuget 包。

我已经在 info.plist 中设置了必要的权限。

我从的 ViewModel 中调用它。

调用非常简单:

var location = await Geolocation.GetLastKnownLocationAsync();

但即使我的 info.plist 已正确设置为:NSLocationWhenInUseUsageDescription 插入原因,它也失败并且未能提示用户权限对话框

我提出并回答这个问题是因为它令人头疼,而且我不确定要搜索什么或问题是什么。

我的各种搜索都指出了许多相关问题,但实际上并没有找到主要问题。

我得到的最接近的实际上是 Essentials github 页面上的这个问题: https ://github.com/xamarin/Essentials/issues/634

4

2 回答 2

3

这个答案的灵感来自 Xamarin/Azure 布道者 Brandon Minnick --> 看看他的项目,他使用以下代码处理类似情况:

那么我们可以从上面得到什么?如果你看一下上下文,他已经将他的 Views 与他的 ViewModels 以 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)
        {
        }
    }
}

我希望它对其他人有帮助!

于 2019-02-16T03:19:00.687 回答
0

如果你正在使用 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);
}
于 2019-07-27T18:24:35.377 回答