Configurar una geovalla

Configure una geovalla en la aplicación y aprenda a controlar las notificaciones en primer plano y en segundo plano.

Habilitación de la funcionalidad de ubicación

  1. En Explorador de soluciones, haga doble clic en package.appxmanifest y seleccione la pestaña Capacidades.
  2. En la lista Funcionalidades , active 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>

Configuración de geovalla

Paso 1: Solicitar acceso a la ubicación del usuario

Importante

Debe solicitar acceso a la ubicación del usuario mediante el método RequestAccessAsync antes de intentar acceder a la ubicación del usuario. 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.

Paso 2: Registrar los cambios en el estado de geovalla y los permisos de ubicación

En este ejemplo, se usa una instrucción switch 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 accede a las geovallas actuales, registra los cambios de estado de geovalla y registra los cambios en los permisos de ubicación.

Sugerencia Al usar una geovalla, supervise los cambios en los permisos de ubicación mediante el evento StatusChanged de la clase GeofenceMonitor en lugar del evento StatusChanged de la clase Geolocator. GeofenceMonitorStatus de Disabled es equivalente a un PositionStatus deshabilitado: ambos indican que la aplicación no tiene permiso para acceder a la ubicación del usuario.

switch (accessStatus)
{
    case GeolocationAccessStatus.Allowed:
        geofences = GeofenceMonitor.Current.Geofences;

        FillRegisteredGeofenceListBoxWithExistingGeofences();
        FillEventListBoxWithExistingEvents();

        // Register for state change events.
        GeofenceMonitor.Current.GeofenceStateChanged += OnGeofenceStateChanged;
        GeofenceMonitor.Current.StatusChanged += OnGeofenceStatusChanged;
        break;


    case GeolocationAccessStatus.Denied:
        _rootPage.NotifyUser("Access denied.", NotifyType.ErrorMessage);
        break;

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

A continuación, al alejarse de la aplicación en primer plano, anule el registro de los agentes de escucha de eventos.

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    GeofenceMonitor.Current.GeofenceStateChanged -= OnGeofenceStateChanged;
    GeofenceMonitor.Current.StatusChanged -= OnGeofenceStatusChanged;

    base.OnNavigatingFrom(e);
}

Paso 3: Crear la geovalla

Ahora, está listo para definir y configurar un objeto Geofence. Hay varias sobrecargas de constructor diferentes entre las que elegir, en función de sus necesidades. En el constructor de geovalla más básico, especifique solo el identificador y la forma geográfica, como se muestra aquí.

// Set the fence ID.
string fenceId = "fence1";

// Define the fence location and radius.
BasicGeoposition position;
position.Latitude = 47.6510;
position.Longitude = -122.3473;
position.Altitude = 0.0;
double radius = 10; // in meters

// Set a circular region for the geofence.
Geocircle geocircle = new Geocircle(position, radius);

// Create the geofence.
Geofence geofence = new Geofence(fenceId, geocircle);

Puede ajustar aún más la geovalla mediante uno de los otros constructores. En el ejemplo siguiente, el constructor de geovalla especifica estos parámetros adicionales:

  • MonitoredStates : indica qué eventos de geovalla desea recibir notificaciones para entrar en la región definida, dejar la región definida o quitar la geovalla.
  • SingleUse : quita la geovalla una vez que se han cumplido todos los estados en los que se está supervisando la geovalla.
  • DwellTime : indica cuánto tiempo debe estar el usuario dentro o fuera del área definida antes de que se desencadenen los eventos de entrada y salida.
  • StartTime : indica cuándo empezar a supervisar la geovalla.
  • Duración : indica el período para el que se va a supervisar la geovalla.
// Set the fence ID.
string fenceId = "fence2";

// Define the fence location and radius.
BasicGeoposition position;
position.Latitude = 47.6510;
position.Longitude = -122.3473;
position.Altitude = 0.0;
double radius = 10; // in meters

// Set the circular region for geofence.
Geocircle geocircle = new Geocircle(position, radius);

// Remove the geofence after the first trigger.
bool singleUse = true;

// Set the monitored states.
MonitoredGeofenceStates monitoredStates =
                MonitoredGeofenceStates.Entered |
                MonitoredGeofenceStates.Exited |
                MonitoredGeofenceStates.Removed;

// Set how long you need to be in geofence for the enter event to fire.
TimeSpan dwellTime = TimeSpan.FromMinutes(5);

// Set how long the geofence should be active.
TimeSpan duration = TimeSpan.FromDays(1);

// Set up the start time of the geofence.
DateTimeOffset startTime = DateTime.Now;

// Create the geofence.
Geofence geofence = new Geofence(fenceId, geocircle, monitoredStates, singleUse, dwellTime, startTime, duration);

Después de crear, recuerde registrar la nueva geovalla en el monitor.

// Register the geofence
try {
   GeofenceMonitor.Current.Geofences.Add(geofence);
} catch {
   // Handle failure to add geofence
}

Paso 4: Controlar los cambios en los permisos de ubicación

El objeto GeofenceMonitor 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 del remitente del argumento. Propiedad Status (de tipo GeofenceMonitorStatus). 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;
...
public async void OnGeofenceStatusChanged(GeofenceMonitor sender, object e)
{
   await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
   {
    // Show the location setting message only if the status is disabled.
    LocationDisabledMessage.Visibility = Visibility.Collapsed;

    switch (sender.Status)
    {
     case GeofenceMonitorStatus.Ready:
      _rootPage.NotifyUser("The monitor is ready and active.", NotifyType.StatusMessage);
      break;

     case GeofenceMonitorStatus.Initializing:
      _rootPage.NotifyUser("The monitor is in the process of initializing.", NotifyType.StatusMessage);
      break;

     case GeofenceMonitorStatus.NoData:
      _rootPage.NotifyUser("There is no data on the status of the monitor.", NotifyType.ErrorMessage);
      break;

     case GeofenceMonitorStatus.Disabled:
      _rootPage.NotifyUser("Access to location is denied.", NotifyType.ErrorMessage);

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

     case GeofenceMonitorStatus.NotInitialized:
      _rootPage.NotifyUser("The geofence monitor has not been initialized.", NotifyType.StatusMessage);
      break;

     case GeofenceMonitorStatus.NotAvailable:
      _rootPage.NotifyUser("The geofence monitor is not available.", NotifyType.ErrorMessage);
      break;

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

Configuración de notificaciones en primer plano

Una vez creadas las geovallas, debe agregar la lógica para controlar lo que sucede cuando se produce un evento de geovalla. Dependiendo de monitoredStates que haya configurado, puede recibir un evento cuando:

  • El usuario escribe una región de interés.
  • El usuario deja una región de interés.
  • La geovalla ha expirado o se ha quitado. Tenga en cuenta que una aplicación en segundo plano no está activada para un evento de eliminación.

Puede escuchar eventos directamente desde la aplicación cuando se ejecuta o se registra para una tarea en segundo plano para que reciba una notificación en segundo plano cuando se produzca un evento.

Paso 1: Registrarse para eventos de cambio de estado de geovalla

Para que la aplicación reciba una notificación en primer plano de un cambio de estado de geovalla, debe registrar un controlador de eventos. Normalmente, esto se configura cuando se crea la geovalla.

private void Initialize()
{
    // Other initialization logic

    GeofenceMonitor.Current.GeofenceStateChanged += OnGeofenceStateChanged;
}

Paso 2: Implementar el controlador de eventos de geovalla

El siguiente paso es implementar los controladores de eventos. La acción que se realiza aquí depende del uso de la geovalla para la aplicación.

public async void OnGeofenceStateChanged(GeofenceMonitor sender, object e)
{
    var reports = sender.ReadReports();

    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        foreach (GeofenceStateChangeReport report in reports)
        {
            GeofenceState state = report.NewState;

            Geofence geofence = report.Geofence;

            if (state == GeofenceState.Removed)
            {
                // Remove the geofence from the geofences collection.
                GeofenceMonitor.Current.Geofences.Remove(geofence);
            }
            else if (state == GeofenceState.Entered)
            {
                // Your app takes action based on the entered event.

                // NOTE: You might want to write your app to take a particular
                // action based on whether the app has internet connectivity.

            }
            else if (state == GeofenceState.Exited)
            {
                // Your app takes action based on the exited event.

                // NOTE: You might want to write your app to take a particular
                // action based on whether the app has internet connectivity.

            }
        }
    });
}

Configuración de notificaciones en segundo plano

Una vez creadas las geovallas, debe agregar la lógica para controlar lo que sucede cuando se produce un evento de geovalla. Dependiendo de monitoredStates que haya configurado, puede recibir un evento cuando:

  • El usuario escribe una región de interés.
  • El usuario deja una región de interés.
  • La geovalla ha expirado o se ha quitado. Tenga en cuenta que una aplicación en segundo plano no está activada para un evento de eliminación.

Para escuchar un evento de geovalla en segundo plano

  • Declare la tarea en segundo plano en el manifiesto de la aplicación.
  • Registre la tarea en segundo plano en la aplicación. Si la aplicación necesita acceso a Internet, por ejemplo, para acceder a un servicio en la nube, puede establecer una marca para eso cuando se desencadene el evento. También puede establecer una marca para asegurarse de que el usuario está presente cuando se desencadene el evento para asegurarse de que el usuario recibe una notificación.
  • Mientras la aplicación se ejecuta en primer plano, pida al usuario que conceda permisos de ubicación de la aplicación.

Paso 1: Registro de cambios en el estado de geovalla

En el manifiesto de la aplicación, en la pestaña Declaraciones , agregue una declaración para una tarea en segundo plano de ubicación. Para ello, siga estos pasos:

  • Agregue una declaración de tipo Tareas en segundo plano.
  • Establezca un tipo de tarea de propiedad de Location.
  • Establezca un punto de entrada en la aplicación para llamar cuando se desencadene el evento.

Paso 2: Registrar la tarea en segundo plano

El código de este paso registra la tarea en segundo plano de geovalla. Recuerde que cuando se creó la geovalla, comprobamos los permisos de ubicación.

async private void RegisterBackgroundTask(object sender, RoutedEventArgs e)
{
    // Get permission for a background task from the user. If the user has already answered once,
    // this does nothing and the user must manually update their preference via PC Settings.
    BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();

    // Regardless of the answer, register the background task. Note that the user can use
    // the Settings app to prevent your app from running background tasks.
    // Create a new background task builder.
    BackgroundTaskBuilder geofenceTaskBuilder = new BackgroundTaskBuilder();

    geofenceTaskBuilder.Name = SampleBackgroundTaskName;
    geofenceTaskBuilder.TaskEntryPoint = SampleBackgroundTaskEntryPoint;

    // Create a new location trigger.
    var trigger = new LocationTrigger(LocationTriggerType.Geofence);

    // Associate the location trigger with the background task builder.
    geofenceTaskBuilder.SetTrigger(trigger);

    // If it is important that there is user presence and/or
    // internet connection when OnCompleted is called
    // the following could be called before calling Register().
    // SystemCondition condition = new SystemCondition(SystemConditionType.UserPresent | SystemConditionType.InternetAvailable);
    // geofenceTaskBuilder.AddCondition(condition);

    // Register the background task.
    geofenceTask = geofenceTaskBuilder.Register();

    // Associate an event handler with the new background task.
    geofenceTask.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);

    BackgroundTaskState.RegisterBackgroundTask(BackgroundTaskState.LocationTriggerBackgroundTaskName);

    switch (backgroundAccessStatus)
    {
    case BackgroundAccessStatus.Unspecified:
    case BackgroundAccessStatus.Denied:
        rootPage.NotifyUser("This app is not allowed to run in the background.", NotifyType.ErrorMessage);
        break;

    }
}


Paso 3: Control de la notificación en segundo plano

La acción que realices para notificar al usuario depende de lo que hace la aplicación, pero puedes mostrar una notificación del sistema, reproducir un sonido de audio o actualizar un icono en directo. El código de este paso controla la notificación.

async private void OnCompleted(IBackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs e)
{
    if (sender != null)
    {
        // Update the UI with progress reported by the background task.
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            try
            {
                // If the background task threw an exception, display the exception in
                // the error text box.
                e.CheckResult();

                // Update the UI with the completion status of the background task.
                // The Run method of the background task sets the LocalSettings.
                var settings = ApplicationData.Current.LocalSettings;

                // Get the status.
                if (settings.Values.ContainsKey("Status"))
                {
                    rootPage.NotifyUser(settings.Values["Status"].ToString(), NotifyType.StatusMessage);
                }

                // Do your app work here.

            }
            catch (Exception ex)
            {
                // The background task had an error.
                rootPage.NotifyUser(ex.ToString(), NotifyType.ErrorMessage);
            }
        });
    }
}


Cambiar la configuración de privacidad

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 the user's 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"));

Prueba y depuración de la aplicación

Las pruebas y la depuración de aplicaciones de geovalla pueden ser un desafío porque dependen de la ubicación de un dispositivo. Aquí se describen varios métodos para probar geovallas en primer plano y en segundo plano.

Para depurar una aplicación de geovalla

  1. Mueva físicamente el dispositivo a nuevas ubicaciones.
  2. Pruebe la entrada de una geovalla mediante la creación de una región de geovalla que incluya la ubicación física actual, por lo que ya está dentro de la geovalla y el evento "geovalla especificada" se desencadena inmediatamente.
  3. Use el emulador de Microsoft Visual Studio para simular ubicaciones para el dispositivo.

Prueba y depuración de una aplicación de geovalla que se ejecuta en primer plano

Para probar la aplicación de geovalla que se ejecuta en primer plano

  1. Compile la aplicación en Visual Studio.
  2. Inicie la aplicación en el emulador de Visual Studio.
  3. Use estas herramientas para simular varias ubicaciones dentro y fuera de la región de geovalla. Asegúrese de esperar lo suficiente después del tiempo especificado por la propiedad DwellTime para desencadenar el evento. Tenga en cuenta que debe aceptar el mensaje para habilitar los permisos de ubicación para la aplicación. Para obtener más información sobre la simulación de ubicaciones, consulta Establecer la geolocalización simulada del dispositivo.
  4. También puede usar el emulador para calcular el tamaño de las vallas y los tiempos de permanencia aproximadamente necesarios para detectarse a diferentes velocidades.

Prueba y depuración de una aplicación de geovalla que se ejecuta en segundo plano

Para probar la aplicación de geovalla que ejecuta el fondo

  1. Compile la aplicación en Visual Studio. Tenga en cuenta que la aplicación debe establecer el tipo de tarea En segundo plano ubicación .
  2. Implemente primero la aplicación localmente.
  3. Cierre la aplicación que se ejecuta localmente.
  4. Inicie la aplicación en el emulador de Visual Studio. Tenga en cuenta que la simulación de geovalla en segundo plano solo se admite en una aplicación a la vez dentro del emulador. No inicie varias aplicaciones de geovalla en el emulador.
  5. Desde el emulador, simula varias ubicaciones dentro y fuera de la región de geovalla. Asegúrese de esperar lo suficiente después de DwellTime para desencadenar el evento. Tenga en cuenta que debe aceptar el mensaje para habilitar los permisos de ubicación para la aplicación.
  6. Use Visual Studio para desencadenar la tarea en segundo plano de ubicación. Para obtener más información sobre cómo desencadenar tareas en segundo plano en Visual Studio, vea Cómo desencadenar tareas en segundo plano.

Solucionar problemas de la aplicación

Para que la aplicación pueda acceder a la ubicación, 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.