Obtenir la localisation de l’utilisateur

Notes

MapControl et les services de carte nécessitent une clé d’authentification de cartes appelée MapServiceToken. Pour plus d’informations sur l’obtention et la définition d’une clé d’authentification de cartes, voir Demander une clé d’authentification de cartes.

Déterminez l’emplacement de l’utilisateur et réagissez aux changements d’emplacement. L’accès à l’emplacement de l’utilisateur est géré par les paramètres de confidentialité définis dans l’application Paramètres. Cette rubrique montre également comment vérifier si votre application est autorisée à accéder à l’emplacement de l’utilisateur.

Conseil Pour en savoir plus sur l’accès à l’emplacement de l’utilisateur dans votre application, téléchargez l’exemple suivant à partir du référentiel Windows-universal-samples sur GitHub.

Activer la fonctionnalité de localisation

  1. Dans l’Explorateur de solutions, double-cliquez sur package.appxmanifest, puis sélectionnez l’onglet Capacités.
  2. Dans la liste Fonctionnalités, case activée la zone Emplacement. Cette opération ajoute la fonctionnalité location de l’appareil au fichier manifeste du package.
  <Capabilities>
    <!-- DeviceCapability elements must follow Capability elements (if present) -->
    <DeviceCapability Name="location"/>
  </Capabilities>

Obtenir l’emplacement actuel

Cette section explique comment détecter l’emplacement géographique de l’utilisateur à l’aide d’API dans l’espace de noms Windows.Devices.Geolocation .

Étape 1 : Demander l’accès à l’emplacement de l’utilisateur

À moins que votre application ne dispose d’une fonctionnalité de localisation grossière (voir la remarque), vous devez demander l’accès à l’emplacement de l’utilisateur à l’aide de la méthode RequestAccessAsync avant d’essayer d’accéder à l’emplacement. Vous devez appeler la méthode RequestAccessAsync à partir du thread de l’interface utilisateur et votre application doit être au premier plan. Votre application ne sera pas en mesure d’accéder aux informations d’emplacement de l’utilisateur tant que l’utilisateur n’aura pas accordé l’autorisation à votre application.*

using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();

La méthode RequestAccessAsync demande à l’utilisateur l’autorisation d’accéder à son emplacement. L’utilisateur est invité une fois seulement (par application). Une fois la première autorisation accordée ou refusée, cette méthode ne demande plus d’autorisation. Pour aider l’utilisateur à modifier les autorisations d’emplacement une fois qu’il a été invité, nous vous recommandons de fournir un lien vers les paramètres d’emplacement, comme illustré plus loin dans cette rubrique.

Remarque : La fonctionnalité de localisation grossière permet à votre application d’obtenir un emplacement intentionnellement obscurci (imprécis) sans obtenir l’autorisation explicite de l’utilisateur (le commutateur d’emplacement à l’échelle du système doit toutefois toujours être activé). Pour savoir comment utiliser un emplacement grossaire dans votre application, consultez la méthode AllowFallbackToConsentlessPositions dans la classe Geolocator .

Étape 2 : Obtenir l’emplacement de l’utilisateur et inscrire les changements d’autorisation de localisation

La méthode GetGeopositionAsync effectue une lecture unique de l’emplacement actuel. Ici, une instruction switch est utilisée avec l’élément accessStatus (de l’exemple précédent) afin d’agir uniquement lorsque l’accès à l’emplacement de l’utilisateur est autorisé. Si cette opération est autorisée, le code crée un objet Geolocator, inscrit les modifications dans les autorisations d’emplacement et demande l’emplacement de l’utilisateur.

switch (accessStatus)
{
    case GeolocationAccessStatus.Allowed:
        _rootPage.NotifyUser("Waiting for update...", NotifyType.StatusMessage);

        // If DesiredAccuracy or DesiredAccuracyInMeters are not set (or value is 0), DesiredAccuracy.Default is used.
        Geolocator geolocator = new Geolocator { DesiredAccuracyInMeters = _desireAccuracyInMetersValue };

        // Subscribe to the StatusChanged event to get updates of location status changes.
        _geolocator.StatusChanged += OnStatusChanged;

        // Carry out the operation.
        Geoposition pos = await geolocator.GetGeopositionAsync();

        UpdateLocationData(pos);
        _rootPage.NotifyUser("Location updated.", NotifyType.StatusMessage);
        break;

    case GeolocationAccessStatus.Denied:
        _rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);
        LocationDisabledMessage.Visibility = Visibility.Visible;
        UpdateLocationData(null);
        break;

    case GeolocationAccessStatus.Unspecified:
        _rootPage.NotifyUser("Unspecified error.", NotifyType.ErrorMessage);
        UpdateLocationData(null);
        break;
}

Étape 3 : Gérer les modifications apportées aux autorisations d’emplacement

L’objet Geolocator déclenche l’événement StatusChanged pour indiquer que les paramètres d’emplacement de l’utilisateur ont changé. Cet événement transmet l’état correspondant par le biais de la propriété Status de l’argument (de type PositionStatus). Notez que cette méthode n’est pas appelée à partir du thread d’interface utilisateur et que l’objet Dispatcher invoque les modifications de l’interface utilisateur.

using Windows.UI.Core;
...
async private void OnStatusChanged(Geolocator sender, StatusChangedEventArgs e)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        // Show the location setting message only if status is disabled.
        LocationDisabledMessage.Visibility = Visibility.Collapsed;

        switch (e.Status)
        {
            case PositionStatus.Ready:
                // Location platform is providing valid data.
                ScenarioOutput_Status.Text = "Ready";
                _rootPage.NotifyUser("Location platform is ready.", NotifyType.StatusMessage);
                break;

            case PositionStatus.Initializing:
                // Location platform is attempting to acquire a fix.
                ScenarioOutput_Status.Text = "Initializing";
                _rootPage.NotifyUser("Location platform is attempting to obtain a position.", NotifyType.StatusMessage);
                break;

            case PositionStatus.NoData:
                // Location platform could not obtain location data.
                ScenarioOutput_Status.Text = "No data";
                _rootPage.NotifyUser("Not able to determine the location.", NotifyType.ErrorMessage);
                break;

            case PositionStatus.Disabled:
                // The permission to access location data is denied by the user or other policies.
                ScenarioOutput_Status.Text = "Disabled";
                _rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);

                // Show message to the user to go to location settings.
                LocationDisabledMessage.Visibility = Visibility.Visible;

                // Clear any cached location data.
                UpdateLocationData(null);
                break;

            case PositionStatus.NotInitialized:
                // The location platform is not initialized. This indicates that the application
                // has not made a request for location data.
                ScenarioOutput_Status.Text = "Not initialized";
                _rootPage.NotifyUser("No request for location is made yet.", NotifyType.StatusMessage);
                break;

            case PositionStatus.NotAvailable:
                // The location platform is not available on this version of the OS.
                ScenarioOutput_Status.Text = "Not available";
                _rootPage.NotifyUser("Location is not available on this version of the OS.", NotifyType.ErrorMessage);
                break;

            default:
                ScenarioOutput_Status.Text = "Unknown";
                _rootPage.NotifyUser(string.Empty, NotifyType.StatusMessage);
                break;
        }
    });
}

Répondre aux mises à jour de localisation

Cette section explique comment utiliser l’événement PositionChanged pour recevoir des mises à jour de l’emplacement de l’utilisateur sur une période donnée. Étant donné que l’utilisateur peut révoquer l’accès à l’emplacement à tout moment, il est important d’appeler RequestAccessAsync et d’utiliser l’événement StatusChanged , comme indiqué dans la section précédente.

Cette section suppose que vous avez déjà activé la fonctionnalité de localisation et appelé RequestAccessAsync à partir du thread d’interface utilisateur de votre application au premier plan.

Étape 1 :Définir l’intervalle de rapport et inscrire les mises à jour d’emplacement

Dans cet exemple, une instruction switch est utilisée avec l’élément accessStatus (de l’exemple précédent) afin d’agir uniquement lorsque l’accès à l’emplacement de l’utilisateur est autorisé. Si l’accès à l’emplacement de l’utilisateur est autorisé, le code crée un objet Geolocator , spécifie le type de suivi et s’inscrit pour les mises à jour d’emplacement.

L’objet Geolocator peut déclencher l’événement PositionChanged sur la base d’un changement de position (suivi basé sur la distance) ou d’un changement dans le temps (suivi basé sur le temps).

  • Pour le suivi basé sur la distance, définissez la propriété MovementThreshold .
  • Pour le suivi basé sur le temps, définissez la propriété ReportInterval.

Si aucune des propriétés n’est définie, une position est renvoyée chaque seconde (équivalente à ReportInterval = 1000). Ici, un intervalle de rapport de 2 secondes (ReportInterval = 2000) est utilisé.

using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();

switch (accessStatus)
{
    case GeolocationAccessStatus.Allowed:
        // Create Geolocator and define perodic-based tracking (2 second interval).
        _geolocator = new Geolocator { ReportInterval = 2000 };

        // Subscribe to the PositionChanged event to get location updates.
        _geolocator.PositionChanged += OnPositionChanged;

        // Subscribe to StatusChanged event to get updates of location status changes.
        _geolocator.StatusChanged += OnStatusChanged;

        _rootPage.NotifyUser("Waiting for update...", NotifyType.StatusMessage);
        LocationDisabledMessage.Visibility = Visibility.Collapsed;
        StartTrackingButton.IsEnabled = false;
        StopTrackingButton.IsEnabled = true;
        break;

    case GeolocationAccessStatus.Denied:
        _rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);
        LocationDisabledMessage.Visibility = Visibility.Visible;
        break;

    case GeolocationAccessStatus.Unspecified:
        _rootPage.NotifyUser("Unspecificed error!", NotifyType.ErrorMessage);
        LocationDisabledMessage.Visibility = Visibility.Collapsed;
        break;
}

Étape 2 : Gérer les mises à jour d’emplacement

L’objet Geolocator déclenche l’événement PositionChanged pour indiquer que l’emplacement de l’utilisateur a changé ou que le temps s’est écoulé, selon la façon dont vous l’avez configuré. Cet événement transmet l’emplacement correspondant via la propriété de l’argument Position (de type Geoposition). Dans cet exemple, la méthode n’est pas appelée à partir du thread d’interface utilisateur et l’objet Dispatcher appelle les modifications de l’interface utilisateur.

using Windows.UI.Core;
...
async private void OnPositionChanged(Geolocator sender, PositionChangedEventArgs e)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        _rootPage.NotifyUser("Location updated.", NotifyType.StatusMessage);
        UpdateLocationData(e.Position);
    });
}

Modifier les paramètres de confidentialité d’emplacement

Si les paramètres de confidentialité d’emplacement n’autorisent pas votre application à accéder à l’emplacement de l’utilisateur, nous vous recommandons de fournir un lien pratique vers les paramètres de confidentialité d’emplacement dans l’application Paramètres. Dans cet exemple, un contrôle de lien hypertexte est utilisé pour accéder à l’URI ms-settings:privacy-location.

<!--Set Visibility to Visible when access to location is denied -->  
<TextBlock x:Name="LocationDisabledMessage" FontStyle="Italic"
                 Visibility="Collapsed" Margin="0,15,0,0" TextWrapping="Wrap" >
          <Run Text="This app is not able to access Location. Go to " />
              <Hyperlink NavigateUri="ms-settings:privacy-location">
                  <Run Text="Settings" />
              </Hyperlink>
          <Run Text=" to check the location privacy settings."/>
</TextBlock>

Par ailleurs, votre application peut appeler la méthodeLaunchUriAsync pour lancer l’application Paramètres à partir du code. Pour plus d’informations, voir Lancer l’application Paramètres Windows.

using Windows.System;
...
bool result = await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));

Résoudre les problèmes de votre application

Pour que votre application puisse accéder à l’emplacement de l’utilisateur, l’option Localisation doit être activée sur l’appareil. Dans l’application Paramètres, vérifiez que les paramètres de confidentialité relatifs à la géolocalisation suivants sont bien activés :

  • Le paramètre Emplacement de cet appareil... est activé (non applicable dans Windows 10 Mobile).
  • Le paramètre des services de localisation Emplacement est activé.
  • Sous Choisir les applications qui peuvent utiliser votre emplacement, votre application est activée.