使用Xamarin.Forms.Maps,Android的位置权限高于6.0

我正在尝试使用Xamarin.Forms.Maps实现Xamarin.Forms应用程序,但是我总是陷入exception:

Java.Lang.SecurityException:我的位置需要权限ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION

我已经尝试按照本教程https://blog.xamarin.com/requesting-runtime-permissions-in-android-marshmallow/中的步骤操作,但没有得到结果。

有人会有更一致的东西来帮助我吗?

我打算使用非常接近优步的应用程序,如果我无法获得位置权限,我就无法进步。

我的主页在我的PCL中看起来像这样:

public partial class MainPage: ContentPage     {         public MainPage ()         {             InitializeComponent ();             var map = new Map ()             {                 MapType = MapType.Street,                 IsShowingUser = true             };             var stack = new StackLayout {Spacing = 0};             stack.Children.Add (map);             Content = stack;         }     } 

我在Xamarin.Android中的MainActivity类看起来像这样:

 [Activity (Label = "ExampleGeolocation", Icon = "@ drawable / icon",              Theme = "@ style / MainTheme", MainLauncher = true,              ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]    public class MainActivity: global :: Xamarin.Forms.Platform.Android.FormsAppCompatActivity, ActivityCompat.IOnRequestPermissionsResultCallback    {        View layout;        const int RequestLocationId = 0;        readonly string [] PermissionsLocation = {Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation};        protected override void OnCreate (Bundle bundle)        {            TabLayoutResource = Resource.Layout.Tabbar;            ToolbarResource = Resource.Layout.Toolbar;            base.OnCreate (bundle);            global :: Xamarin.Forms.Forms.Init (this, bundle);            global :: Xamarin.FormsMaps.Init (this, bundle);            Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this;            SetStatusBarColor (Android.Graphics.Color.Black);            LoadApplication (new App ());        }        public override async void OnRequestPermissionsResult (int requestCode, string [] permissions, [GeneratedEnum] Permission [] grantResults)        {            switch (requestCode)            {                case RequestLocationId:                    {                        if (grantResults [0] == Permission.Granted)                        {                            var snack = Snackbar.Make (layout, "Location Permission is Available.", Snackbar.LengthShort);                            snack.Show ();                            await GetLocationAsync ();                        }                        else                        {                            var snack = Snackbar.Make (layout, "Location Permission Denied", Snackbar.LengthShort);                            snack.Show ();                        }                    }                    break;            }        }        async Task TryGetLocationAsync ()        {            if ((int) Build.VERSION.SdkInt  RequestPermissions (PermissionsLocation, RequestLocationId))                        .Show();                return;            }            RequestPermissions (PermissionsLocation, RequestLocationId);        }        async Task GetLocationAsync ()        {            try            {                var locator = CrossGeolocator.Current;            }            catch (Exception e)            {                e.ToString ();                throw new NotImplementedException ();            }        }    }; 

使用Xamarin.Forms.Maps,Android的位置权限高于6.0

您编写了大量有关权限的代码,但我无法找到您请求权限的位置,您需要在使用之前请求权限。

当您将IsShowingUser属性设置为true时,您应首先请求权限,这里有三个解决方案。

解决方案1:

我注意到您在代码中使用PermissionsPlugin ,如果您需要在PCL请求此权限,您可以参考PermissionsPlugin官方示例 。

MainActivity添加此代码:

 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) { PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults); } 

需要时请求权限:

 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(Permission.Location); status = results[Permission.Location]; } if (status == PermissionStatus.Granted) { //Permission granted, do what you want do. } else if(status != PermissionStatus.Unknown) { await DisplayAlert("Location Denied", "Can not continue, try again.", "OK"); } } catch (Exception ex) { //... } 

解决方案2:

打开应用程序时,首先在MainActivity OnStart方法中请求权限:

 protected override void OnStart() { base.OnStart(); if (ContextCompat.CheckSelfPermission(this, permission) != Permission.Granted) { ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation }, 0); } else { System.Diagnostics.Debug.WriteLine("Permission Granted!!!"); } } 

解决方案3:

使用DependencyService在需要时请求权限,以下是与您已阅读的教程相关的示例 。 在此示例中,它在执行此行时请求权限:

 buttonGetLocation.Click += async (sender, e) => await TryGetLocationAsync(); 

在Android内部添加此内容MainActiviy OnCreate()

 Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this; 

将此添加到android mainactivity:

 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults) { Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } 

然后此代码将起作用,提示用户获取位置权限。

  var locator = CrossGeolocator.Current; locator.DesiredAccuracy = 1000; var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000); 

参考:

https://jamesmontemagno.github.io/GeolocatorPlugin/

确保您已设置所有必要的权限。 如果您想在Android上使用Xamarin.Forms.Maps ,请确保您在项目的AndroidManifest.xml文件中设置了以下权限:

       

您还可以通过在Android项目上单击鼠标右键并选择“ Properties来设置权限。 转到Android Manifest选项卡并标记所有必要的权限。

还要确保在应用程序标记中添加了以下两个语句: