Xamarin.Essentials:Géolocalisation
La classe Geolocation fournit des API permettant de récupérer les coordonnées de géolocalisation de l’appareil.
Démarrage
Pour commencer à utiliser cette API, lisez le guide de prise en main pour Xamarin.Essentials vous assurer que la bibliothèque est correctement installée et configurée dans vos projets.
Pour accéder à la fonctionnalité de géolocalisation, la configuration suivante spécifique à la plateforme est obligatoire :
Les autorisations de localisation approximative et de localisation précise sont obligatoires, et doivent être configurées dans le projet Android. De plus, si votre application cible Android 5.0 (niveau d’API 21) ou une version ultérieure, vous devez déclarer que votre application utilise les fonctionnalités matérielles dans le fichier manifeste. Vous pouvez le faire de plusieurs façons, comme indiqué ci-dessous :
Ouvrez le fichier AssemblyInfo.cs sous le dossier Propriétés et ajoutez :
[assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
[assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
[assembly: UsesFeature("android.hardware.location", Required = false)]
[assembly: UsesFeature("android.hardware.location.gps", Required = false)]
[assembly: UsesFeature("android.hardware.location.network", Required = false)]
Ou mettez à jour le manifeste Android :
Ouvrez le fichier AndroidManifest.xml sous le dossier Propriétés, puis ajoutez ce qui suit dans le nœud manifeste :
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
Vous pouvez également cliquer avec le bouton droit sur le projet Android, et ouvrir les propriétés du projet. Sous Manifeste Android, recherchez la zone Autorisations nécessaires, puis cochez les autorisations ACCESS_COARSE_LOCATION et ACCESS_FINE_LOCATION. Cela met automatiquement à jour le fichier AndroidManifest.xml.
Si votre application cible Android 10 - Q (niveau d’API 29 ou version ultérieure) et demande LocationAlways, vous devez également ajouter l’autorisation suivante dans AssemblyInfo.cs :
[assembly: UsesPermission(Manifest.Permission.AccessBackgroundLocation)]
Ou directement dans votre AndroidManifest.xml :
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Il est recommandé de lire la documentation Android sur les mises à jour d’emplacement en arrière-plan, car de nombreuses restrictions doivent être prises en compte.
Cette API utilise des autorisations d’exécution sur Android. Vérifiez que la Xamarin.Essentials gestion des autorisations est entièrement initialisée et configurée dans votre application.
Dans le projet MainLauncher
Android ou tout Activity
projet lancé Xamarin.Essentials doit être initialisé dans la OnCreate
méthode :
protected override void OnCreate(Bundle savedInstanceState)
{
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
}
Pour gérer les autorisations d’exécution sur Android, Xamarin.Essentials doivent recevoir n’importe quel OnRequestPermissionsResult
. Ajoutez le code suivant à toutes les classes Activity
:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Utilisation de la géolocalisation
Ajoutez une référence à Xamarin.Essentials votre classe :
using Xamarin.Essentials;
Si nécessaire, l’API de géolocalisation demande également des autorisations à l’utilisateur.
Vous pouvez obtenir la dernière localisation connue de l’appareil en appelant la méthode GetLastKnownLocationAsync
. Bien que cela soit souvent plus rapide que d’effectuer une requête complète, cela peut aussi être moins précis et retourner null
si aucun emplacement mis en cache n’existe.
try
{
var location = await Geolocation.GetLastKnownLocationAsync();
if (location != null)
{
Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
}
catch (FeatureNotEnabledException fneEx)
{
// Handle not enabled on device exception
}
catch (PermissionException pEx)
{
// Handle permission exception
}
catch (Exception ex)
{
// Unable to get location
}
Pour interroger les coordonnées relatives à la localisation de l’appareil actuel, vous pouvez utiliser GetLocationAsync
. Il est préférable de passer un GeolocationRequest
et un CancellationToken
complets, car il peut s’écouler un certain temps avant d’obtenir la localisation de l’appareil.
CancellationTokenSource cts;
async Task GetCurrentLocation()
{
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
cts = new CancellationTokenSource();
var location = await Geolocation.GetLocationAsync(request, cts.Token);
if (location != null)
{
Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
}
}
catch (FeatureNotSupportedException fnsEx)
{
// Handle not supported on device exception
}
catch (FeatureNotEnabledException fneEx)
{
// Handle not enabled on device exception
}
catch (PermissionException pEx)
{
// Handle permission exception
}
catch (Exception ex)
{
// Unable to get location
}
}
protected override void OnDisappearing()
{
if (cts != null && !cts.IsCancellationRequested)
cts.Cancel();
base.OnDisappearing();
}
Notez que toutes les valeurs peuvent être disponibles en raison de la façon dont chaque appareil interroge la géolocalisation via différents fournisseurs. Par exemple, la Altitude
propriété peut être null
, avoir une valeur de 0, ou avoir une valeur positive, qui est en mètres au-dessus du niveau de la mer. D’autres valeurs peuvent être exclues, comme les propriétés Speed
et Course
.
Précision de la géolocalisation
Le tableau suivant indique la précision en fonction de la plateforme :
Minimale
Plate-forme | Distance (en mètres) |
---|---|
Android | 500 |
iOS | 3000 |
UWP | 1 000 - 5 000 |
Faible
Plate-forme | Distance (en mètres) |
---|---|
Android | 500 |
iOS | 1 000 |
UWP | 300 - 3 000 |
Moyenne (par défaut)
Plate-forme | Distance (en mètres) |
---|---|
Android | 100 - 500 |
iOS | 100 |
UWP | 30 - 500 |
Forte
Plate-forme | Distance (en mètres) |
---|---|
Android | 0 - 100 |
iOS | 10 |
UWP | <= 10 |
La meilleure
Plate-forme | Distance (en mètres) |
---|---|
Android | 0 - 100 |
iOS | ~0 |
UWP | <= 10 |
Détection des emplacements fictifs
Certains appareils peuvent retourner un emplacement fictif du fournisseur ou par une application qui fournit des emplacements fictifs. Vous pouvez le détecter à l’aide de IsFromMockProvider
sur tout Location
.
var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);
if (location != null)
{
if(location.IsFromMockProvider)
{
// location is from a mock provider
}
}
Distance entre deux emplacements
Les classes Location
et LocationExtensions
définissent les méthodes CalculateDistance
qui vous permettent de calculer la distance entre deux emplacements géographiques. Cette distance calculée ne prend pas en compte les routes et autres chemins. Elle constitue simplement la distance la plus courte entre deux points à la surface de la Terre, également appelée distance orthodromique ou, familièrement, distance « à vol d’oiseau ».
Voici un exemple :
Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);
double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);
Le constructeur Location
a des arguments de latitude et de longitude dans cet ordre. Les valeurs de latitude positives sont au nord de l’équateur, et les valeurs de longitude positives sont à l’est du premier méridien. Utilisez le dernier argument pour CalculateDistance
afin de spécifier des miles ou des kilomètres. La classe UnitConverters
définit également les méthodes KilometersToMiles
et MilesToKilometers
pour effectuer la conversion entre les deux unités.
Différences entre les plateformes
Le calcul de l’altitude diffère selon la plateforme.
Sur Android, l’altitude (si disponible) est renvoyée en mètres au-dessus de l’ellipsoïde de référence WGS 84. Si cet emplacement n’a pas d’altitude, 0,0 est retourné.