Configurar uma cerca geográfica

Uma Geofence define uma delimitação geográfica circular em torno de um ponto de interesse. Seu aplicativo recebe notificações quando o usuário entra ou sai do limite. Cercas geográficas são úteis para lembretes, alertas, check-ins e entrega de conteúdo contextual com base na localização.

Este artigo mostra como criar uma cerca geográfica, monitorar alterações de estado e lidar com eventos de cerca geográfica em um aplicativo do SDK do Aplicativo Windows (WinUI 3).

Pré-requisitos

  • Um projeto WinUI 3 criado a partir do modelo Aplicativo em Branco, Empacotado (WinUI 3 na Área de Trabalho).
  • A funcionalidade Localização declarada no manifesto do pacote. Consulte Obter a localização do usuário para obter instruções.

Solicitar acesso ao local

Chame Geolocator.RequestAccessAsync antes de criar ou monitorar cercas geográficas.

using Windows.Devices.Geolocation;
using Windows.Devices.Geolocation.Geofencing;

var accessStatus = await Geolocator.RequestAccessAsync();
if (accessStatus != GeolocationAccessStatus.Allowed)
{
    StatusText.Text = "Location access is required for geofencing.";
    return;
}

Criar uma cerca geográfica

Defina uma geocerca especificando um identificador, um centro geográfico, um raio em metros e quais transições de estado monitorar (entrada, saída ou remoção).

var position = new BasicGeoposition
{
    Latitude = 47.6062,
    Longitude = -122.3321
};

var geocircle = new Geocircle(position, 200); // 200-meter radius

var geofence = new Geofence(
    "SeattleDowntown",                          // Unique identifier
    geocircle,                                  // Geographic boundary
    MonitoredGeofenceStates.Entered |           // States to monitor
    MonitoredGeofenceStates.Exited,
    false,                                      // Single use: false = persistent
    TimeSpan.FromSeconds(10)                    // Dwell time before triggering
);

GeofenceMonitor.Current.Geofences.Add(geofence);

Parâmetros de cerca geográfica

Parâmetro Description
id Uma string exclusiva que identifica a cerca geográfica. Use isso para distinguir eventos de diferentes cercas geográficas.
geoshape Um Geocircle que define o limite. Há suporte apenas para limites circulares.
monitoredStates Quais transições para monitorar: Entered, Exitedou Removed. Combine com o operador |.
singleUse Se true, a cerca geográfica é acionada uma vez e removida automaticamente.
dwellTime Por quanto tempo o usuário deve permanecer dentro (ou fora) do limite antes que o evento seja acionado. Ajuda a filtrar interseções breves.

Monitorar eventos de cerca geográfica em primeiro plano

Assine o evento GeofenceMonitor.Current.GeofenceStateChanged para receber notificações enquanto seu aplicativo está em execução.

GeofenceMonitor.Current.GeofenceStateChanged += OnGeofenceStateChanged;

Leia os relatórios e atualize a interface do usuário. O evento é disparado em uma thread em segundo plano, portanto, use DispatcherQueue para gerenciar as atualizações da interface do usuário.

private void OnGeofenceStateChanged(GeofenceMonitor sender, object args)
{
    var reports = sender.ReadReports();

    DispatcherQueue.TryEnqueue(() =>
    {
        foreach (var report in reports)
        {
            var state = report.NewState;
            var id = report.Geofence.Id;

            switch (state)
            {
                case GeofenceState.Entered:
                    StatusText.Text = $"Entered geofence: {id}";
                    break;
                case GeofenceState.Exited:
                    StatusText.Text = $"Exited geofence: {id}";
                    break;
                case GeofenceState.Removed:
                    StatusText.Text = $"Geofence removed: {id}";
                    // Re-add the geofence if it was removed due to expiration
                    break;
            }
        }
    });
}

Monitorar alterações de status da cerca geográfica

Use GeofenceMonitor.Current.StatusChanged para detectar quando o monitoramento da cerca geográfica é desativado — por exemplo, quando o usuário desativa os serviços de localização.

GeofenceMonitor.Current.StatusChanged += (sender, args) =>
{
    DispatcherQueue.TryEnqueue(() =>
    {
        var status = sender.Status;
        if (status == GeofenceMonitorStatus.Disabled)
        {
            StatusText.Text = "Geofence monitoring is disabled. Check location settings.";
        }
    });
};

Tip

Ao usar cercas geográficas, monitore as alterações de permissão por meio de GeofenceMonitor.StatusChanged em vez de Geolocator.StatusChanged. Um valor de GeofenceMonitorStatus de Disabled é equivalente a um PositionStatus de Disabled, mas GeofenceMonitorStatus fornece mais contexto para cenários de cerca geográfica.

Remover uma cerca geográfica

Remova uma cerca geográfica encontrando-a na coleção GeofenceMonitor.Current.Geofences.

var geofences = GeofenceMonitor.Current.Geofences;
var target = geofences.FirstOrDefault(g => g.Id == "SeattleDowntown");

if (target != null)
{
    geofences.Remove(target);
}

Práticas recomendadas

  • Defina um tempo de espera razoável. Um tempo de permanência de pelo menos 10 segundos ajuda a filtrar a oscilação do GPS e evita falsos acionamentos nas bordas dos limites.
  • Use um raio de pelo menos 50 metros. A precisão do GPS varia de acordo com o dispositivo e o ambiente. Um raio menor que 50 metros pode produzir resultados não confiáveis.
  • Verifique o acesso à Internet, se necessário. Se o aplicativo executar operações de rede quando um evento de cerca geográfica for acionado (como enviar uma notificação a um servidor), verifique a conectividade antes de criar a cerca geográfica.
  • Manipular o estado Removed. As cercas geográficas podem ser removidas pelo sistema se expirarem ou se o sistema estiver sob pressão de recursos. Verificar GeofenceState.Removed e recriar a cerca geográfica se o seu cenário exigir.
  • Não monitore o primeiro plano e o segundo plano simultaneamente para a mesma cerca geográfica, a menos que seja necessário. Se o fizer, cancele o registro do ouvinte de primeiro plano quando o aplicativo for suspenso e registre-o novamente quando for retomado.