Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Busque la ubicación del usuario y responda a los cambios en la ubicación. La configuración de privacidad gestiona el acceso a la ubicación del usuario en Windows Settings. En este tema también se muestra cómo comprobar si la aplicación tiene permiso para acceder a la ubicación del usuario.
Nota:
En este artículo se describe el Windows. API Devices.Geolocation para obtener la posición geográfica de un dispositivo. Si quieres mostrar ubicaciones en un mapa, el control UWP MapControl y las API de Windows.Services.Maps están en desuso. Las aplicaciones winUI 3 deben usar el nuevo MapControl con tecnología de Azure Maps. Para obtener más información, consulte Recursos para características en desuso.
Habilitación de la funcionalidad de ubicación
- En Explorador de soluciones, haga doble clic en package.appxmanifest y seleccione la pestaña Funcionalidades.
- En la lista Funcionalidades, active la casilla Ubicación. Esto agrega la funcionalidad del
locationdispositivo al archivo de manifiesto del paquete.
<Capabilities>
<!-- DeviceCapability elements must follow Capability elements (if present) -->
<DeviceCapability Name="location"/>
</Capabilities>
Obtención de la ubicación actual
En esta sección se describe cómo detectar la ubicación geográfica del usuario mediante las API en el espacio de nombres Windows.Devices.Geolocation.
Paso 1: Solicitar acceso a la ubicación del usuario
A menos que la aplicación tenga una funcionalidad de ubicación general (vea la nota), debe solicitar acceso a la ubicación del usuario mediante el método RequestAccessAsync antes de intentar acceder a la ubicación. Debes llamar al método RequestAccessAsync desde el subproceso de la interfaz de usuario y la aplicación debe estar en primer plano. La aplicación no podrá acceder a la información de ubicación del usuario hasta después de que el usuario conceda permiso a la aplicación.*
using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();
El método RequestAccessAsync solicita al usuario permiso para acceder a su ubicación. Solo se le solicita al usuario una vez (por aplicación). Después de la primera vez que conceden o deniegan el permiso, este método ya no solicita al usuario permiso. Para ayudar al usuario a cambiar los permisos de ubicación después de que se le hayan pedido, se recomienda proporcionar un vínculo a la configuración de ubicación, como se muestra más adelante en este tema.
Nota:
La función de ubicación aproximada permite a tu aplicación obtener una ubicación intencionadamente ofuscada (imprecisa) sin necesidad de obtener el permiso explícito del usuario (aunque el interruptor de ubicación del sistema debe seguir estando activado). Para saber cómo utilizar la ubicación aproximada en tu aplicación, consulta el método AllowFallbackToConsentlessPositions de la clase Geolocator.
Paso 2: Obtener la ubicación del usuario y registrar los cambios en los permisos de ubicación
El método GetGeopositionAsync realiza una lectura única de la ubicación actual. Aquí se usa una switch instrucción con accessStatus (del ejemplo anterior) para actuar solo cuando se permite el acceso a la ubicación del usuario. Si se permite el acceso a la ubicación del usuario, el código crea un objeto Geolocator , registra los cambios en los permisos de ubicación y solicita la ubicación del usuario.
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;
}
Paso 3: Controlar los cambios en los permisos de ubicación
El objeto Geolocator desencadena el evento StatusChanged para indicar que la configuración de ubicación del usuario ha cambiado. Ese evento pasa el estado correspondiente a través de la propiedad Status del argumento (de tipo PositionStatus). Tenga en cuenta que no se llama a este método desde el subproceso de la interfaz de usuario y el objeto Dispatcher invoca los cambios de la interfaz de usuario.
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;
}
});
}
Responder a las actualizaciones de ubicación
En esta sección se describe cómo usar el evento PositionChanged para recibir actualizaciones de la ubicación del usuario durante un período de tiempo. Dado que el usuario podría revocar el acceso a la ubicación en cualquier momento, es importante llamar a RequestAccessAsync y usar el evento StatusChanged como se muestra en la sección anterior.
En esta sección se da por hecho que ya has habilitado la función de ubicación y has llamado a RequestAccessAsync desde el hilo de la interfaz de usuario de tu aplicación en primer plano.
Paso 1: Definir el intervalo de informe y registrar las actualizaciones de ubicación
En este ejemplo, se usa una switch instrucción con accessStatus (del ejemplo anterior) para actuar solo cuando se permite el acceso a la ubicación del usuario. Si se permite el acceso a la ubicación del usuario, el código crea un objeto Geolocator , especifica el tipo de seguimiento y registra las actualizaciones de ubicación.
El objeto Geolocator puede desencadenar el evento PositionChanged en función de un cambio en la posición (seguimiento basado en distancia) o un cambio en el tiempo (seguimiento basado en periodicidad).
- Para el seguimiento basado en la distancia, configure la propiedad MovementThreshold.
- Para el seguimiento basado en intervalos periódicos, establezca la propiedad ReportInterval.
Si no se establece ninguna propiedad, se devuelve una posición cada 1 segundo (equivalente a ReportInterval = 1000). Aquí se usa un intervalo de informe de 2 segundos (ReportInterval = 2000).
using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();
switch (accessStatus)
{
case GeolocationAccessStatus.Allowed:
// Create Geolocator and define periodic-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("Unspecified error!", NotifyType.ErrorMessage);
LocationDisabledMessage.Visibility = Visibility.Collapsed;
break;
}
Paso 2: Controlar las actualizaciones de ubicación
El objeto Geolocator desencadena el evento PositionChanged para indicar que la ubicación del usuario ha cambiado o ha pasado el tiempo, en función de cómo la haya configurado. Ese evento pasa la ubicación correspondiente a través de la propiedad Position del argumento (de tipo Geoposition). En este ejemplo, no se llama al método desde el subproceso de la interfaz de usuario y el objeto Dispatcher invoca los cambios de la interfaz de usuario.
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);
});
}
Cambiar la configuración de privacidad de la ubicación
Si la configuración de privacidad de la ubicación no permite que la aplicación acceda a la ubicación del usuario, se recomienda proporcionar un vínculo cómodo a la configuración de privacidad de la ubicación en Configuración. En este ejemplo, se usa un control Hyperlink para ir al ms-settings:privacy-location URI.
<!--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>
Como alternativa, la aplicación puede llamar al método LaunchUriAsync para iniciar Configuración desde el código. Para obtener más información, consulta Iniciar la configuración de Windows.
using Windows.System;
...
bool result = await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));
Solucionar problemas de la aplicación
Para que la aplicación pueda acceder a la ubicación del usuario, la ubicación debe estar habilitada en el dispositivo. En Configuración, compruebe que la siguiente configuración de privacidad de ubicación está activada:
- La ubicación de este dispositivo... está activada (no se aplica a Windows 10 Mobile)
- La configuración de servicios de ubicación, Ubicación, está activada
- En la opción Elegir las aplicaciones que pueden acceder a tu ubicación, tu aplicación está activada