Ottenere la posizione dell'utente

Usa le API Windows.Devices.Geolocation per rilevare la posizione geografica del dispositivo in un'app di SDK per app di Windows (WinUI 3). È possibile ottenere una correzione della posizione singola o tenere traccia della posizione dell'utente nel tempo. Questo articolo illustra la gestione delle autorizzazioni, le letture una tantum e la posizione continua e come aggiornare l'interfaccia utente quando cambia la posizione.

Note

Le Windows.Devices.Geolocation API sono API Windows Runtime (WinRT) che funzionano nelle app desktop UWP e WinUI 3. Il codice in questo articolo usa modelli WinUI 3 , ad esempio DispatcherQueue per il marshalling dei thread.

Prerequisiti

  • Un progetto WinUI 3 creato dal modello App vuota, con pacchetto (WinUI 3 su Desktop).
  • La funzionalità Location dichiarata nel manifesto del pacchetto (vedere Abilitare la funzionalità di posizione).

Abilita la funzionalità di localizzazione

L'app deve dichiarare la funzionalità Location prima di poter accedere alla posizione dell'utente.

  1. In Esplora soluzioni fare doppio clic su Package.appxmanifest e selezionare la scheda Funzionalità.
  2. Selezionare la casella Percorso.

Viene aggiunta la voce seguente al manifesto:

<Capabilities>
    <DeviceCapability Name="location"/>
</Capabilities>

Tip

Per le app non in pacchetto, la funzionalità Posizione non è necessaria in un manifesto. Tuttavia, è comunque necessario chiamare RequestAccessAsync per richiedere all'utente l'autorizzazione.

Ottenere la posizione corrente

Seguire questa procedura per eseguire una sola lettura della posizione.

Richiedere l'accesso alla posizione dell'utente

Chiamare Geolocator.RequestAccessAsync prima di accedere ai dati della posizione. Questo metodo richiede all'utente l'autorizzazione la prima volta che viene eseguita. È necessario chiamarlo dal thread dell'interfaccia utente mentre l'app è in primo piano.

using Windows.Devices.Geolocation;

var accessStatus = await Geolocator.RequestAccessAsync();

Leggi la posizione

Se l'utente concede l'autorizzazione, creare un geolocatore e chiamare GetGeopositionAsync per ottenere una correzione di posizione una tantum.

switch (accessStatus)
{
    case GeolocationAccessStatus.Allowed:
        var geolocator = new Geolocator { DesiredAccuracyInMeters = 50 };
        Geoposition position = await geolocator.GetGeopositionAsync();

        double latitude = position.Coordinate.Point.Position.Latitude;
        double longitude = position.Coordinate.Point.Position.Longitude;

        StatusText.Text = $"Location: {latitude:F4}, {longitude:F4}";
        break;

    case GeolocationAccessStatus.Denied:
        StatusText.Text = "Location access is denied.";
        break;

    case GeolocationAccessStatus.Unspecified:
        StatusText.Text = "An unspecified error occurred.";
        break;
}

Tenere traccia della posizione dell'utente nel tempo

Per ricevere aggiornamenti periodici della posizione, sottoscrivere l'evento PositionChanged . Impostare ReportInterval per il rilevamento basato sul tempo o movementThreshold per il rilevamento basato sulla distanza.

if (accessStatus == GeolocationAccessStatus.Allowed)
{
    var geolocator = new Geolocator { ReportInterval = 2000 }; // 2-second interval

    geolocator.PositionChanged += OnPositionChanged;
    geolocator.StatusChanged += OnStatusChanged;
}

Gestire gli aggiornamenti delle posizioni

L'evento PositionChanged viene generato su un thread in background. Usare DispatcherQueue per riportare gli aggiornamenti dell'interfaccia utente nel thread principale.

private void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
    DispatcherQueue.TryEnqueue(() =>
    {
        var position = args.Position.Coordinate.Point.Position;
        StatusText.Text = $"Updated: {position.Latitude:F4}, {position.Longitude:F4}";
    });
}

Gestire le modifiche dello stato

Monitor StatusChanged per rilevare quando l'utente disabilita i servizi di posizione o il segnale GPS viene perso.

private void OnStatusChanged(Geolocator sender, StatusChangedEventArgs args)
{
    DispatcherQueue.TryEnqueue(() =>
    {
        switch (args.Status)
        {
            case PositionStatus.Ready:
                StatusText.Text = "Location is available.";
                break;
            case PositionStatus.Disabled:
                StatusText.Text = "Location is disabled. Check Settings.";
                break;
            case PositionStatus.NoData:
                StatusText.Text = "Unable to determine location.";
                break;
            case PositionStatus.NotAvailable:
                StatusText.Text = "Location is not available on this device.";
                break;
        }
    });
}

Indirizzare l'utente alle impostazioni della posizione

Se l'utente nega l'accesso alla posizione, fornire un collegamento alle impostazioni di privacy Windows in modo che possano modificare le proprie preferenze.

<HyperlinkButton Content="Open location settings"
                 NavigateUri="ms-settings:privacy-location" />

È anche possibile aprire la pagina delle impostazioni dal codice:

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

Mostra la posizione su una mappa

Dopo aver recuperato una posizione, è possibile visualizzarla in un controllo MapControl di WinUI 3 impostando la relativa proprietà Center e aggiungendo un oggetto MapIcon. Per un esempio completo e funzionante che combina geolocalizzazione, visualizzazione della mappa e geofencing, consulta la panoramica su mappe e localizzazione.

Risoluzione dei problemi

Se l'app non riesce a recuperare una posizione, verificare quanto segue in Impostazioni > Privacy e posizione di sicurezza>:

  • I servizi di posizionesono attivati.
  • L'app è elencata e impostata su in Consenti alle app di accedere alla posizione.
  • Il dispositivo dispone di un ricevitore GPS funzionante oppure è disponibile il posizionamento basato sulla rete.