Obtener la ubicación del usuario

Use las API Windows.Devices.Geolocation para detectar la posición geográfica del dispositivo en una aplicación de SDK de Aplicaciones para Windows (WinUI 3). Puede obtener una corrección de ubicación única o realizar un seguimiento de la posición del usuario a lo largo del tiempo. En este artículo se describe el control de permisos, las lecturas de ubicación única y continua, y cómo actualizar la interfaz de usuario cuando cambia la ubicación.

Note

Las Windows.Devices.Geolocation API son api de Windows Runtime (WinRT) que funcionan en aplicaciones de escritorio de UWP y WinUI 3. El código de este artículo utiliza patrones de WinUI 3 (como DispatcherQueue para la canalización entre hilos).

Prerequisites

  • Un proyecto de WinUI 3 creado a partir de la plantilla Aplicación en blanco, empaquetada (WinUI 3 en escritorio).
  • La funcionalidad Ubicación declarada en el manifiesto del paquete (consulte Habilitación de la funcionalidad de ubicación).

Habilitación de la funcionalidad de ubicación

La aplicación debe declarar la funcionalidad Ubicación para poder acceder a la posición del usuario.

  1. En Explorador de soluciones, haga doble clic en Package.appxmanifest y seleccione la pestaña Capacidades.
  2. Active la casilla Ubicación.

Esto agrega la siguiente entrada al manifiesto:

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

Tip

En el caso de las aplicaciones sin empaquetar, la funcionalidad Ubicación no es necesaria en un manifiesto. No obstante, debes seguir llamando a RequestAccessAsync para solicitar permiso al usuario.

Obtención de la ubicación actual

Siga estos pasos para realizar una lectura puntual de posición.

Solicitar acceso a la ubicación del usuario

Llame a Geolocator.RequestAccessAsync antes de acceder a los datos de ubicación. Este método solicita al usuario permiso la primera vez que se ejecuta. Debes invocarlo desde el hilo de la interfaz de usuario mientras tu aplicación esté en primer plano.

using Windows.Devices.Geolocation;

var accessStatus = await Geolocator.RequestAccessAsync();

Leer la posición

Si el usuario concede permiso, cree un Geolocator y llame a GetGeopositionAsync para obtener una corrección de posición única.

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;
}

Realizar un seguimiento de la ubicación del usuario a lo largo del tiempo

Para recibir actualizaciones periódicas de ubicación, suscríbase al evento PositionChanged . Establezca ReportInterval para el seguimiento basado en tiempo o MovementThreshold para el seguimiento basado en distancia.

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

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

Controlar las actualizaciones de posición

El evento PositionChanged se activa en un hilo en segundo plano. Use DispatcherQueue para reenviar las actualizaciones de la interfaz de usuario al hilo principal.

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}";
    });
}

Controlar los cambios de estado

Supervise StatusChanged para detectar cuándo el usuario deshabilita los servicios de ubicación o se pierde la señal GPS.

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;
        }
    });
}

Dirigir al usuario a la configuración de ubicación

Si el usuario deniega el acceso a la ubicación, proporcione un vínculo a la configuración de privacidad del Windows para que pueda cambiar su preferencia.

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

También puede abrir la página de configuración desde el código:

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

Mostrar la ubicación en un mapa

Después de recuperar una posición, puede mostrarla en un MapControl de WinUI 3 estableciendo su Center y agregando un MapIcon. Para ver un ejemplo de trabajo completo que combina geolocalización, visualización de mapa y geovalla, consulte la información general sobre mapas y ubicaciones.

Troubleshooting

Si la aplicación no puede recuperar una ubicación, compruebe lo siguiente en Configuración > Privacidad y ubicación de seguridad>:

  • Los servicios de ubicación están activados.
  • La aplicación aparece y se establece en Activado en Permitir que las aplicaciones accedan a su ubicación.
  • El dispositivo tiene disponible un receptor GPS en funcionamiento o un posicionamiento basado en red.