Obtener la ubicación del usuario
Importante
Retirada del servicio Mapas de Bing for Enterprise
Los servicios MapControl y de mapa del espacio de nombres Windows.Services.Maps se basan en Mapas de Bing. Mapas de Bing for Enterprise está en desuso y se retirará, momento en el que los servicios y MapControl ya no recibirán datos.
Para obtener más información, consulte la documentación del Centro para desarrolladores de Mapas de Bing y Mapas de Bing.
Nota:
MapControl y servicios de mapas requieren una clave de autenticación de mapas denominada MapServiceToken. Para obtener más información sobre cómo obtener y establecer una clave de autenticación de mapas, consulta Solicitar una clave de autenticación de mapas.
Busque la ubicación del usuario y responda a los cambios en la ubicación. La configuración de privacidad administra el acceso a la ubicación del usuario en la aplicación Configuración de Windows. En este tema también se muestra cómo comprobar si la aplicación tiene permiso para acceder a la ubicación del usuario.
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
location
dispositivo 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. El usuario solo se le solicita 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 característica de ubicación general permite a la aplicación obtener una ubicación ofuscada intencionadamente (imprecisa) sin obtener el permiso explícito del usuario (el modificador de ubicación para todo el sistema todavía debe estar activado). Para obtener información sobre cómo usar la ubicación general en la aplicación, consulta el método AllowFallbackToConsentlessPositions en 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 supone que ya ha habilitado la funcionalidad de ubicación y que se ha llamado RequestAccessAsync desde el subproceso de interfaz de usuario de la 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 distancia, establezca la propiedad MovementThreshold.
- Para el seguimiento basado en 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 la aplicación 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 la aplicación Configuración desde el código. Para obtener más información, consulte Inicio de la aplicación 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 la aplicación Configuración , compruebe que la siguiente configuración de privacidad de ubicación está activada:
- Ubicación para este dispositivo... está activado (no aplicable en Windows 10 Mobile)
- La configuración de servicios de ubicación, Ubicación, está activada
- En Elegir aplicaciones que pueden usar la ubicación, la aplicación está establecida en activado.