使用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);
参考:
确保您已设置所有必要的权限。 如果您想在Android上使用Xamarin.Forms.Maps
,请确保您在项目的AndroidManifest.xml
文件中设置了以下权限:
您还可以通过在Android项目上单击鼠标右键并选择“ Properties
来设置权限。 转到Android Manifest
选项卡并标记所有必要的权限。
还要确保在应用程序标记中添加了以下两个语句: