`RequestPermissionAsync`不返回并且没有按预期工作.询问权限等待它和GetLocation允许权限时出现问题 [英] `RequestPermissionAsync` is not returning and not working as expected. Ask Permission wait for it and GetLocation when permission is allowed problem

查看:329
本文介绍了`RequestPermissionAsync`不返回并且没有按预期工作.询问权限等待它和GetLocation允许权限时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Xamarin.Forms的新手.我想向用户请求位置许可,然后,如果用户允许,请获取他的位置.问题是RequestPermissionAsynGetLastKnownLocationAsync,它们都是异步操作.因此,我想等到用户授予许可,然后再调用GetLastKnownLocationAsync.我将此插件用于Permision Plugin.Permissions v3.0.0.12

这是我正在使用的代码

async void AskPermission(object sender, EventArgs e)
{
    await Task.Run(async () =>
    {
        var permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
        if (permissionStatus != PermissionStatus.Granted)
        {
            var response = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
            var userResponse = response[Permission.Location];
            Debug.WriteLine($"Permission {Permission.Location} {permissionStatus}");
        }
        else
            Debug.WriteLine($"Permission is finally {Permission.Location} {permissionStatus}");
    });

    // Call the GetLocation if user allowed the permission.
}

async void GetLocation()
{
    Location location;
    location = await Geolocation.GetLastKnownLocationAsync();
    Location.Text = location.Latitude.ToString();
}

我可以成功提示用户允许许可,但是GetLocation()没有执行.这意味着即使我写Debug.WriteLine("");是否已授予权限?,我也不会在输出窗口中得到任何东西.任何帮助将非常感激.基本上,我想一个接一个地运行两个异步操作.我不知道问题出在异步操作还是从UI线程运行.

解决方案

我认为RequestPermissionsAsync无法返回可能存在问题.因此,我在代码中进行了此修改.现在,我使用相同的插件询问用户权限,并检查是否在其他线程中启用了该权限.该操作每1秒执行一次,直到应用获得所需的许可.当允许该应用访问位置的权限时,请放置计时器,这样它就不会再次检查该权限.

该项目内使用的插件中还存在另一个错误. ( Plugin.Permissions v3.0.0.12).当我们两次请求许可,两次都拒绝用户许可时,将引发Exception.因此,我陷入了try-catch

内部

这是有效的代码,被困在这里的人可能会发现它很有用:

public MainPage()
{
    InitializeComponent();
    Device.BeginInvokeOnMainThread(() => AskPermission());
    CheckPermissionStatusRepeatedly();
    ...
}

async void AskPermission()
{
    var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
    if (status != PermissionStatus.Granted)
    {
        await Application.Current.MainPage.DisplayAlert("Permission Request", "This app needs to access device location. Please allow access for location.", "Ok");
        try
        {
            await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Location });
        }
        catch (Exception ex)
        {
            Location.Text = "Error: " + ex;
        }                
    }
}

void CheckPermissionStatusRepeatedly()
{
    Timer timer = null;
    timer = new Timer(new TimerCallback(async delegate
    {
        var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
        if (status != PermissionStatus.Granted)
            Debug.WriteLine("Still permission is not Granted");
        else
        {
            Debug.WriteLine("Now permision is Granted, Hence calling GetLocation()");
            Device.BeginInvokeOnMainThread(() => GetLocation());                    
            timer.Dispose();
        }
    }), "test", 1000, 1000);
}

async void GetLocation()
{
    Location location;
    location = await Geolocation.GetLastKnownLocationAsync();
    Location.Text = "Lat: " + location.Latitude + " Long: " + location.Longitude;
}

I am new in Xamarin.Forms. I want to ask for the location permission to the user, then if user allows it, get his location. The problem is RequestPermissionAsyn and GetLastKnownLocationAsync, both are async operations. Hence I want to wait till user grants permission and then call the GetLastKnownLocationAsync. I am using this plugin for Permision Plugin.Permissions v3.0.0.12

Here is the code I am using

async void AskPermission(object sender, EventArgs e)
{
    await Task.Run(async () =>
    {
        var permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
        if (permissionStatus != PermissionStatus.Granted)
        {
            var response = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
            var userResponse = response[Permission.Location];
            Debug.WriteLine($"Permission {Permission.Location} {permissionStatus}");
        }
        else
            Debug.WriteLine($"Permission is finally {Permission.Location} {permissionStatus}");
    });

    // Call the GetLocation if user allowed the permission.
}

async void GetLocation()
{
    Location location;
    location = await Geolocation.GetLastKnownLocationAsync();
    Location.Text = location.Latitude.ToString();
}

I can successfully prompt the user for allowing permission, but GetLocation() is not executing. That means even if I write Debug.WriteLine(""); whether permission granted?, I am not getting anything in the output Window. Any Help would be much appreciated. Basically I want to run both the asynchronous operations one after the other. I do not understand whether the problem is with asynchronous operations or whether it needs to run from UI Thread.

解决方案

I think there might be a problem with RequestPermissionsAsync not returning. Hence I have made this modification in my code. Now I ask the user permission using same plugin, and check if the the permission is enabled in other thread. This operation is performed every 1 second until the app gets required permission. When permission is allowed for the app to access location, dispose the timer, hence it will not check for the permissions again.

Also there is another bug in this used plugin inside the project. (Plugin.Permissions v3.0.0.12). When we ask for permission 2 times, and both the times if user denies the permission, then Exception was thrown. Hence I caught in inside try-catch

This is the working code, someone stuck here might find it useful:

public MainPage()
{
    InitializeComponent();
    Device.BeginInvokeOnMainThread(() => AskPermission());
    CheckPermissionStatusRepeatedly();
    ...
}

async void AskPermission()
{
    var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
    if (status != PermissionStatus.Granted)
    {
        await Application.Current.MainPage.DisplayAlert("Permission Request", "This app needs to access device location. Please allow access for location.", "Ok");
        try
        {
            await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Location });
        }
        catch (Exception ex)
        {
            Location.Text = "Error: " + ex;
        }                
    }
}

void CheckPermissionStatusRepeatedly()
{
    Timer timer = null;
    timer = new Timer(new TimerCallback(async delegate
    {
        var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
        if (status != PermissionStatus.Granted)
            Debug.WriteLine("Still permission is not Granted");
        else
        {
            Debug.WriteLine("Now permision is Granted, Hence calling GetLocation()");
            Device.BeginInvokeOnMainThread(() => GetLocation());                    
            timer.Dispose();
        }
    }), "test", 1000, 1000);
}

async void GetLocation()
{
    Location location;
    location = await Geolocation.GetLastKnownLocationAsync();
    Location.Text = "Lat: " + location.Latitude + " Long: " + location.Longitude;
}

这篇关于`RequestPermissionAsync`不返回并且没有按预期工作.询问权限等待它和GetLocation允许权限时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆