J'essaie d'implémenter une application Xamarin.Forms à l'aide de Xamarin.Forms.Maps, mais je tombe toujours dans l'exception:
Java.Lang.SecurityException: mon emplacement nécessite l'autorisation ACCESS_FINE_LOCATION ou ACCESS_COARSE_LOCATION
J'ai déjà essayé de suivre les étapes de ce tutoriel https://blog.xamarin.com/requesting-runtime-permissions-in-Android-Marshmallow/ mais je n'ai pas obtenu de résultats.
Quelqu'un aurait-il quelque chose de plus cohérent pour m'aider?
Ce que j'ai l'intention est d'utiliser une application très proche d'Uber et je ne peux pas progresser si je ne peux pas obtenir les autorisations de localisation.
Ma MainPage ressemble à ceci dans mon 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;
}
}
Ma classe MainActivity dans Xamarin.Android ressemble à ceci:
[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 <23)
{
await GetLocationAsync ();
return;
}
await GetLocationPermissionAsync ();
}
async Task GetLocationPermissionAsync ()
{
const string permission = Manifest.Permission.AccessFineLocation;
if (CheckSelfPermission (permission) == Permission.Granted)
{
await GetLocationAsync ();
return;
}
if (ShouldShowRequestPermissionRationale (permission))
{
Snackbar.Make (layout, "You must allow the application to access your location options.", Snackbar.LengthIndefinite)
.SetAction ("OK", v => RequestPermissions (PermissionsLocation, RequestLocationId))
.Show();
return;
}
RequestPermissions (PermissionsLocation, RequestLocationId);
}
async Task GetLocationAsync ()
{
try
{
var locator = CrossGeolocator.Current;
}
catch (Exception e)
{
e.ToString ();
throw new NotImplementedException ();
}
}
};
Autorisation de localisation pour Android ci-dessus 6.0 avec Xamarin.Forms.Maps
Vous avez écrit beaucoup de code sur l'autorisation mais je ne trouve pas où vous demandez l'autorisation, vous devez demander l'autorisation avant de l'utiliser.
Lorsque vous définissez la propriété IsShowingUser
sur true, vous devez d'abord demander l'autorisation, voici trois solutions.
Je remarque que vous utilisez PermissionsPlugin dans votre code, si vous avez besoin de demander cette autorisation dans PCL
, vous pouvez vous référer à échantillon officiel PermissionsPlugin .
Ajoutez ce code dans votre MainActivity
:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Demandez la permission quand vous en avez besoin:
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)
{
//...
}
Lorsque vous ouvrez votre application, demandez d'abord l'autorisation, dans la méthode 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!!!");
}
}
Utilisez DependencyService pour demander l'autorisation lorsque vous en avez besoin, voici le exemple lié au tutoriel que vous avez lu. Dans cet exemple, il demande l'autorisation lors de l'exécution de cette ligne:
buttonGetLocation.Click += async (sender, e) => await TryGetLocationAsync();
ajouter ceci à l'intérieur Android MainActiviy OnCreate ()
Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this;
ajoutez ceci à 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);
}
alors ce code fonctionnera, invitant l'utilisateur à l'autorisation de localisation.
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 1000;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
faire référence à:
Assurez-vous que vous avez défini toutes les autorisations nécessaires. Si vous souhaitez utiliser Xamarin.Forms.Maps
on Android assurez-vous que les autorisations suivantes sont définies dans le AndroidManifest.xml
fichier de votre projet:
<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE" />
<uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE" />
<uses-permission Android:name="Android.permission.INTERNET" />
Vous pouvez également définir les autorisations en cliquant avec la souris droite sur votre Android et en sélectionnant Properties
. Allez dans l'onglet Android Manifest
et marquez toutes les autorisations nécessaires.
Assurez-vous également que vous avez ajouté les deux instructions suivantes dans la balise d'application:
<meta-data Android:name="com.google.Android.geo.API_KEY" Android:value="ADD_YOUR_KEY_HERE" />
<meta-data Android:name="com.google.Android.gms.version" Android:value="@integer/google_play_services_version" />
Cette vidéo peut vous aider à obtenir l'autorisation d'exécution dans les formulaires xamarin https://www.youtube.com/watch?v=IWdpzpFChUQ