问题
I recently updated sdk level to 6.0 in Xamarin.forms. I used Xaml to place a map on a page. Since I updated to 6.0 permission is required to show the map. My problem now is I can't figure out how to request permission to show the map before the app attempts to show it. As a result I get an unhandled exception.
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)
{
}
}
If the map is set up in Xaml, how can I request permission before showing it?
回答1:
The way your constructor is set up right now, you are starting the permission request in a task which will run in a separate thread. That means that InitializeComponent() will probably run before the user can grant permission. The problem is you can't make the constructor an async method so there isn't an easy way to get around this.
To make this work without to much effort, you can move the InitializeComponent() from your constructor into your "if (status == PermissionStatus.Granted)" block. It would probably look something like this:
if (status == PermissionStatus.Granted)
{
Device.BeginInvokeOnMainThread(() =>
{
InitializeComponent()
});
}
With this approach you will have to be careful what you do in OnAppearing() as it will probably be called before InitializeComponent(). If you try to access any of your UI components at that point it will fail.
However I think the better way to handle this is to move your permission request code one level up. In other words put it in the class where you are instantiating this page from. Then you can show this page if access is granted, or another page that does not have the map if access is denied. It would make for a better user experience.
来源:https://stackoverflow.com/questions/41325729/how-to-request-location-permission-before-showing-map-set-up-in-xaml-xamarin-fo