我最近在Xamarin.forms中将sdk级别更新为6.0。 我使用Xaml在页面上放置地图。由于我更新到6.0,因此需要显示地图。我现在的问题是我无法弄清楚如何在应用程序尝试显示之前请求显示地图的权限。结果我得到了一个未处理的例外。
public MapPage()
{
Init();
InitializeComponent();
azureService = AzureService.defaultManager;
}
private async Task Init()
{
await RequestLocationPermission();
}
protected async override void OnAppearing()
{
base.OnAppearing();
MyMap.MoveToRegion(
MapSpan.FromCenterAndRadius(
new Position(0, 0),
Distance.FromMiles(10.0)));
}
private async Task RequestLocationPermission()
{
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
await DisplayAlert("Need location", "Gunna need that location", "OK");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Location });
status = results[Permission.Location];
}
if (status == PermissionStatus.Granted)
{
}
else if (status != PermissionStatus.Unknown)
{
await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
}
}
catch (Exception ex)
{
}
}
如果地图是在Xaml中设置的,如何在显示之前请求权限?
答案 0 :(得分:1)
您的构造函数现在的设置方式,您将在一个将在单独的线程中运行的任务中启动权限请求。这意味着InitializeComponent()可能会在用户授予权限之前运行。问题是你不能使构造函数成为异步方法,因此不容易解决这个问题。
为了使这项工作不费吹灰之力,您可以将InitializeComponent()从构造函数移动到" if(status == PermissionStatus.Granted)"块。它可能看起来像这样:
if (status == PermissionStatus.Granted)
{
Device.BeginInvokeOnMainThread(() =>
{
InitializeComponent()
});
}
使用这种方法,你必须要小心你在OnAppearing()中所做的事情,因为它可能会在InitializeComponent()之前被调用。如果您在此时尝试访问任何UI组件,则会失败。
但是我认为处理此问题的更好方法是将您的权限请求代码提升一级。换句话说,将它放在要从中实例化此页面的类中。然后,如果授予访问权限,则可以显示此页面;如果访问被拒绝,则可以显示没有该地图的其他页面。它可以带来更好的用户体验。