来自Xamarin Forms的Geolocation GetLastKnownLocationAsync()权限异常 - 调用失败且没有权限提示

问题描述 投票:0回答:1

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

我有最新的Xamarin.Essentials nuget包。

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

我从我的ViewModel调用它。

这个电话非常简单:

var location = await Geolocation.GetLastKnownLocationAsync();

但它既失败又无法提示用户权限对话框,即使我的info.plist已正确设置:NSLocationWhenInUseUsageDescription插入原因

我问并回答这个问题,因为这是一个令人头疼的问题,我不确定要搜索什么或问题是什么。

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

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

xamarin.forms geolocation xamarin.essentials
1个回答
1
投票

这个答案的灵感来自于Xamarin / Azure布道者布兰登·明尼克 - >看看他的项目,他处理类似情况下面的code:

那么我们可以从上面拿走什么呢?如果你看一下上下文,他已将他的Views与MVVM风格的ViewModels联系起来。但是,各种库要求从主线程调用某些方法。这是问题的本质,这就是这段代码可以解决的问题。

因此,对于问题中提到的地理定位问题采用上述代码,我做了以下内容:

Task<Xamarin.Essentials.Location> GetLocationFromPhone()
{

    var locationTaskCompletionSource = new TaskCompletionSource<Xamarin.Essentials.Location>();

    Device.BeginInvokeOnMainThread(async () =>
    {
        locationTaskCompletionSource.SetResult(await Geolocation.GetLastKnownLocationAsync());
    });

    return locationTaskCompletionSource.Task;
}

我在一个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)
        {
        }
    }
}

我希望它对别人有帮助!


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);
}
© www.soinside.com 2019 - 2024. All rights reserved.