Share via


Géolocalisation

Browse sample. Parcourir l'exemple

Dans cet article, vous allez apprendre à utiliser l’interface IGeolocation de l’application multiplateforme .NET (.NET MAUI). Cette interface fournit plusieurs API pour récupérer les coordonnées de géolocalisation actuelles de l’appareil.

L’implémentation par défaut de l’interface IGeolocation est disponible via la propriété Geolocation.Default. L’espace de noms Microsoft.Maui.Devices.Sensors contient à la fois l’interface IGeolocation et la classe Geolocation.

Bien démarrer

Pour accéder à la fonctionnalité de géolocalisation, la configuration suivante spécifique à la plateforme est obligatoire :

Les autorisations relatives à la position (approximative ou exacte, ou les deux) doivent être spécifiées et 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 :

  • Ajoutez l’autorisation basée sur l’assembly :

    Ouvrez le fichier Platforms/Android/MainApplication.cs et ajoutez les attributs d’assembly suivants après les directives using :

    [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)]
    

    Si votre application cible Android 10 – Q (niveau d’API 29 ou version ultérieure) et effectue une requête pour LocationAlways, vous devez également ajouter la demande d’autorisation suivante :

    [assembly: UsesPermission(Manifest.Permission.AccessBackgroundLocation)]
    

    - ou -

  • Mettez à jour le manifeste Android :

    Ouvrez le fichier Plateformes/Android/AndroidManifest.xml et ajoutez le code suivant dans le nœud manifest :

    <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" />
    

    Si votre application cible Android 10 – Q (niveau d’API 29 ou version ultérieure) et effectue une requête pour LocationAlways, vous devez également ajouter la demande d’autorisation suivante :

    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    

    - ou -

  • Mettez à jour le manifeste Android dans l’éditeur de manifeste :

    Dans Visual Studio, double-cliquez sur le fichier Plateformes/Android/AndroidManifest.xml pour ouvrir l’éditeur de manifeste Android. Ensuite, dans Autorisations requises, activez les autorisations répertoriées ci-dessus. Cela met automatiquement à jour le fichier AndroidManifest.xml.

Conseil

Veuillez lire la documentation Android sur les mises à jour de la position en arrière-plan pour prendre en compte les nombreuses restrictions qui s’appliquent.

Obtenir la dernière position connue

L’appareil a peut-être mis en cache la dernière position de l’appareil. Utilisez la méthode GetLastKnownLocationAsync() pour accéder à la position mise en cache, le cas échéant. Cette méthode permet généralement de récupérer la position plus rapidement qu’avec une requête complète. Toutefois, la position peut être moins précise. Si aucun position n’est mise en cache, cette méthode renvoie null.

Remarque

Si nécessaire, l’API de géolocalisation invite l’utilisateur à activer des autorisations.

L’exemple de code suivant illustre la recherche d’une position mise en cache :

public async Task<string> GetCachedLocation()
{
    try
    {
        Location location = await Geolocation.Default.GetLastKnownLocationAsync();

        if (location != null)
            return $"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
    }

    return "None";
}

La disponibilité des valeurs indiquant la position varie selon le type d’appareil. Par exemple, la valeur de la propriété Altitude peut être null, 0 ou positive (altitude en mètres au-dessus du niveau de la mer). D’autres valeurs peuvent être exclues, comme les propriétés Speed et Course.

Obtenir la position actuelle

Si récupérer la dernière position connue de l’appareil permet souvent de gagner en rapidité, les informations renvoyées peuvent être inexactes. Utilisez la méthode GetLocationAsync pour demander la position actuelle de l’appareil. Vous pouvez configurer la précision et le délai d’expiration de la requête. Nous vous recommandons de privilégier cette méthode par rapport à celle basée sur les paramètres GeolocationRequest et CancellationToken, qui occasionne une surcharge. En effet, la recherche de la position de l’appareil peut prendre un certain temps.

Remarque

Si nécessaire, l’API de géolocalisation invite l’utilisateur à activer des autorisations.

L’exemple de code suivant montre comment demander la position de l’appareil avec annulation de la requête :

private CancellationTokenSource _cancelTokenSource;
private bool _isCheckingLocation;

public async Task GetCurrentLocation()
{
    try
    {
        _isCheckingLocation = true;

        GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));

        _cancelTokenSource = new CancellationTokenSource();

        Location location = await Geolocation.Default.GetLocationAsync(request, _cancelTokenSource.Token);

        if (location != null)
            Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
    }
    // Catch one of the following exceptions:
    //   FeatureNotSupportedException
    //   FeatureNotEnabledException
    //   PermissionException
    catch (Exception ex)
    {
        // Unable to get location
    }
    finally
    {
        _isCheckingLocation = false;
    }
}

public void CancelRequest()
{
    if (_isCheckingLocation && _cancelTokenSource != null && _cancelTokenSource.IsCancellationRequested == false)
        _cancelTokenSource.Cancel();
}

La disponibilité des valeurs indiquant la position varie selon le type d’appareil. Par exemple, la valeur de la propriété Altitude peut être null, 0 ou positive (altitude en mètres au-dessus du niveau de la mer). D’autres valeurs peuvent être exclues, comme les propriétés Speed et Course.

Avertissement

GetLocationAsync peut renvoyer null dans certains scénarios. Cela indique que la plateforme sous-jacente n’est pas en mesure d’obtenir l’emplacement actuel.

Surveiller les changements de position

Vous pouvez également surveiller les changements de position de l’appareil lorsqu’une application est au premier plan.

Pour vérifier si l’application surveille actuellement les changements de position, vous pouvez effectuer une requête avec la propriété IsListeningForeground. Lorsque vous souhaitez commencer à surveiller les changements de position, vous devez appeler la méthode StartListeningForegroundAsync pour commencer à écouter les mises à jour de la position et déclencher l’événement LocationChanged à chaque changement de position (à condition que l’application soit au premier plan). L’objet GeolocationLocationChangedEventArgsde cet événement est lié à une propriété Location de type Location, qui représente la nouvelle position détectée.

Remarque

Si nécessaire, l’API de géolocalisation invite l’utilisateur à activer des autorisations.

L’exemple de code suivant montre comment prendre en compte un changement de position et traiter la nouvelle position :

async void OnStartListening()
{
    try
    {
        Geolocation.LocationChanged += Geolocation_LocationChanged;
        var request = new GeolocationListeningRequest((GeolocationAccuracy)Accuracy);
        var success = await Geolocation.StartListeningForegroundAsync(request);

        string status = success
            ? "Started listening for foreground location updates"
            : "Couldn't start listening";
    }
    catch (Exception ex)
    {
        // Unable to start listening for location changes
    }
}

void Geolocation_LocationChanged(object sender, GeolocationLocationChangedEventArgs e)
{
    // Process e.Location to get the new location
}

Pour gérer les erreurs, vous pouvez enregistrer un gestionnaire d’événements pour l’événement ListeningFailed. L’objet GeolocationListeningFailedEventArgs de cet événement est lié à une propriété Error de type GeolocationError, qui indique pourquoi la surveillance de la position a échoué. Lors du déclenchement de l’événement ListeningFailed, la surveillance des changements de position est interrompue et aucun autre événement LocationChanged n’est déclenché.

Pour arrêter la surveillance des changements de position, appelez la méthode StopListeningForeground :

void OnStopListening()
{
    try
    {
        Geolocation.LocationChanged -= Geolocation_LocationChanged;
        Geolocation.StopListeningForeground();
        string status = "Stopped listening for foreground location updates";
    }
    catch (Exception ex)
    {
        // Unable to stop listening for location changes
    }
}

Remarque

La méthode StopListeningForeground n’a aucun effet lorsque l’application ne surveille pas les changements de position.

Précision

Les sections suivantes décrivent la distance de précision de la position pour chaque plateforme :

Important

iOS présente certaines limitations en matière de précision. Pour en savoir plus, consultez la section Différences selon les plateformes.

Minimale

Plate-forme Distance (en mètres)
Android 500
iOS 3000
Windows 1 000 - 5 000

Faible

Plate-forme Distance (en mètres)
Android 500
iOS 1 000
Windows 300 - 3 000

Moyenne (par défaut)

Plate-forme Distance (en mètres)
Android 100 - 500
iOS 100
Windows 30 - 500

Forte

Plate-forme Distance (en mètres)
Android 0 - 100
iOS 10
Windows <= 10

La meilleure

Plate-forme Distance (en mètres)
Android 0 - 100
iOS ~0
Windows <= 10

Détection des positions fictives

Certains appareils peuvent retourner un emplacement fictif du fournisseur ou par une application qui fournit des emplacements fictifs. Vous pouvez détecter les positions fictives à l’aide de la propriété IsFromMockProvider sur n’importe quel objet Location :

public async Task CheckMock()
{
    GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium);
    Location location = await Geolocation.Default.GetLocationAsync(request);

    if (location != null && location.IsFromMockProvider)
    {
        // location is from a mock provider
    }
}

Distance entre deux positions

La méthode CalculateDistance permet de calculer la distance entre deux positions géographiques. Ce calcul de distance ne prend pas en compte les routes ni les autres voies. Il s’agit simplement de la distance la plus courte entre deux points à surface de la Terre. On appelle cette méthode le calcul de la distance du grand cercle.

Le code suivant calcule la distance entre Boston et San Francisco (États-Unis) :

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(Double, Double, Double) accepte les arguments de latitude et de longitude, respectivement. 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 selon les plateformes

Cette section décrit les différences spécifiques à la plateforme concernant l’API de géolocalisation.

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 cette position n’est associée à aucune altitude, 0.0 est renvoyé.

iOS est la seule plateforme qui utilise la propriété Location.ReducedAccuracy. Les autres plateformes renvoient la valeur false.