Поделиться через


Настройка геозоны

Настройте геозону в приложении и узнайте, как обрабатывать уведомления на переднем плане и в фоновом режиме.

Включение возможности расположения

  1. В Обозреватель решений дважды щелкните package.appxmanifest и перейдите на вкладку "Возможности".
  2. В списке возможностей проверьте расположение. Это добавляет Location возможность устройства в файл манифеста пакета.
  <Capabilities>
    <!-- DeviceCapability elements must follow Capability elements (if present) -->
    <DeviceCapability Name="location"/>
  </Capabilities>

Настройка геозоны

Шаг 1. Запрос доступа к расположению пользователя

Внимание

Перед попыткой доступа к расположению пользователя необходимо запросить доступ к расположению пользователя с помощью метода RequestAccessAsync. Необходимо вызвать метод RequestAccessAsync из потока пользовательского интерфейса, и приложение должно находиться на переднем плане. Ваше приложение не сможет получить доступ к сведениям о расположении пользователя до тех пор, пока пользователь не предоставит пользователю разрешение на доступ к приложению.

using Windows.Devices.Geolocation;
...
var accessStatus = await Geolocator.RequestAccessAsync();

Метод RequestAccessAsync запрашивает пользователю разрешение на доступ к их расположению. Пользователю предлагается только один раз (для каждого приложения). После первого предоставления или запрета разрешения этот метод больше не запрашивает у пользователя разрешение. Чтобы помочь пользователю изменить разрешения расположения после запроса, рекомендуется предоставить ссылку на параметры расположения, как показано далее в этом разделе.

Шаг 2. Регистрация изменений в состоянии геозонии и разрешениях расположения

В этом примере оператор switch используется с accessStatus (из предыдущего примера), чтобы действовать только в том случае, если доступ к расположению пользователя разрешен. Если доступ к расположению пользователя разрешен, код обращается к текущим геозонам, регистрируется для изменений состояния геозоны и регистрируется для изменений в разрешениях расположения.

Совет при использовании геозоны отслеживайте изменения разрешений расположения с помощью события StatusChanged из класса GeofenceMonitor вместо события StatusChanged из класса Geolocator. GeofenceMonitorStatus от disabled эквивалентен отключенной PositionStatus — оба указывают, что приложение не имеет разрешения на доступ к расположению пользователя.

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

Затем при переходе от приложения переднего плана отмените регистрацию прослушивателей событий.

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

    base.OnNavigatingFrom(e);
}

Шаг 3. Создание геозоны

Теперь вы готовы определить и настроить объект Geofence. Существует несколько разных перегрузок конструктора для выбора в зависимости от ваших потребностей. В самом базовом конструкторе геозоны укажите только идентификатор и geoshape, как показано здесь.

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

Вы можете настроить геозону дальше с помощью одного из других конструкторов. В следующем примере конструктор геозоны указывает следующие дополнительные параметры:

  • MonitoredStates — указывает, какие события геозоны нужно получать уведомления о вводе определенного региона, выходе из определенного региона или удалении геозоны.
  • SingleUse — удаляет геозону после выполнения всех состояний, для которых отслеживается геозона.
  • DwellTime — указывает, сколько времени пользователь должен находиться в определенной области или из определенной области перед активацией событий ввода и выхода.
  • StartTime — указывает, когда начнется мониторинг геозоны.
  • Длительность — указывает период, для которого необходимо отслеживать геозону.
// 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);

После создания не забудьте зарегистрировать новую геозону в мониторе.

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

Шаг 4. Обработка изменений в разрешениях расположения

Объект GeofenceMonitor активирует событие StatusChanged, чтобы указать, что параметры расположения пользователя изменились. Это событие передает соответствующее состояние через отправителя аргумента . Свойство status (тип GeofenceMonitorStatus). Обратите внимание, что этот метод не вызывается из потока пользовательского интерфейса, а объект диспетчера вызывает изменения пользовательского интерфейса.

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

Настройка уведомлений переднего плана

После создания геозон необходимо добавить логику для обработки того, что происходит при возникновении события геозоны. В зависимости от настроенного объекта MonitoredStates может появиться событие при следующих случаях:

  • Пользователь вводит интересующий регион.
  • Пользователь покидает интересующий регион.
  • Срок действия геозоны истек или удален. Обратите внимание, что фоновое приложение не активируется для события удаления.

Вы можете прослушивать события непосредственно из приложения при выполнении или регистрации фоновой задачи, чтобы получать фоновое уведомление при возникновении события.

Шаг 1. Регистрация событий изменения состояния геозоны

Чтобы приложение получило уведомление о изменении состояния геозоны на переднем плане, необходимо зарегистрировать обработчик событий. Обычно это настраивается при создании геозоны.

private void Initialize()
{
    // Other initialization logic

    GeofenceMonitor.Current.GeofenceStateChanged += OnGeofenceStateChanged;
}

Шаг 2. Реализация обработчика событий геозоны

Следующим шагом является реализация обработчиков событий. Действие, выполняемое здесь, зависит от того, для чего ваше приложение использует геозону.

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.

            }
        }
    });
}

Настройка фоновых уведомлений

После создания геозон необходимо добавить логику для обработки того, что происходит при возникновении события геозоны. В зависимости от настроенного объекта MonitoredStates может появиться событие при следующих случаях:

  • Пользователь вводит интересующий регион.
  • Пользователь покидает интересующий регион.
  • Срок действия геозоны истек или удален. Обратите внимание, что фоновое приложение не активируется для события удаления.

Прослушивание события геозоны в фоновом режиме

  • Объявите фоновую задачу в манифесте приложения.
  • Зарегистрируйте фоновую задачу в приложении. Если приложению нужен доступ к Интернету, например для доступа к облачной службе, можно задать флаг для этого при активации события. Вы также можете задать флаг, чтобы убедиться, что пользователь присутствует при активации события, чтобы убедиться, что пользователь получает уведомление.
  • Пока приложение запущено на переднем плане, предложите пользователю предоставить разрешения на расположение приложения.

Шаг 1. Регистрация изменений состояния геозоны

В манифесте приложения на вкладке "Объявления" добавьте объявление для фоновой задачи расположения. Для этого:

  • Добавьте объявление типа фоновых задач.
  • Задайте тип задачи свойства location.
  • Задайте точку входа в приложение для вызова при активации события.

Шаг 2. Регистрация фоновой задачи

Код на этом шаге регистрирует фоновую задачу геофенсинга. Помните, что при создании геозоны мы проверили разрешения на расположение.

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;

    }
}


Шаг 3. Обработка фонового уведомления

Действие, которое вы принимаете для уведомления пользователя, зависит от того, что делает ваше приложение, но вы можете отобразить всплывающее уведомление, воспроизвести звук или обновить динамическую плитку. Код на этом шаге обрабатывает уведомление.

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


Изменение параметров конфиденциальности

Если параметры конфиденциальности расположения не позволяют приложению получать доступ к расположению пользователя, рекомендуется предоставить удобную ссылку на параметры конфиденциальности расположения в приложении "Параметры ". В этом примере элемент управления Гиперссылка используется в 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>

Кроме того, приложение может вызвать метод LaunchUriAsync, чтобы запустить приложение Settings из кода. Дополнительные сведения см. в разделе "Запуск приложения параметров Windows".

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

Тестирование и отладка приложения

Тестирование и отладка приложений геозон может быть проблемой, так как они зависят от расположения устройства. Здесь мы рассмотрим несколько методов тестирования как переднего плана, так и фоновых геозон.

Отладка приложения геозоны

  1. Физически переместите устройство в новые расположения.
  2. Проверьте, введите геозону, создав регион геозоны, включающий текущее физическое расположение, поэтому вы уже находитесь в геозоне, и событие geofence, введенное "геозона", активируется немедленно.
  3. Используйте эмулятор Microsoft Visual Studio для имитации расположений для устройства.

Тестирование и отладка приложения геозоны, работающего на переднем плане

Тестирование приложения геозоны, работающего на переднем плане

  1. Создайте приложение в Visual Studio.
  2. Запустите приложение в эмуляторе Visual Studio.
  3. Используйте эти средства для имитации различных расположений внутри и за пределами региона геозоны. Не забудьте дождаться достаточно долгого времени, указанного свойством DwellTime , чтобы активировать событие. Обратите внимание, что необходимо принять запрос, чтобы включить разрешения расположения для приложения. Дополнительные сведения об имитации расположений см. в разделе "Настройка имитированного географического расположения устройства".
  4. Вы также можете использовать эмулятор для оценки размера заборов и времени ожидания приблизительно необходимо обнаружить на разных скоростях.

Тестирование и отладка приложения геозоны, работающего в фоновом режиме

Тестирование приложения геозоны, работающего в фоновом режиме

  1. Создайте приложение в Visual Studio. Обратите внимание, что приложение должно задать тип фоновой задачи Location .
  2. Сначала разверните приложение.
  3. Закройте приложение, которое выполняется локально.
  4. Запустите приложение в эмуляторе Visual Studio. Обратите внимание, что фоновое моделирование геозон поддерживается только в одном приложении за раз в эмуляторе. Не запускайте несколько приложений геозон в эмуляторе.
  5. Из эмулятора имитируйте различные расположения внутри и за пределами региона геозоны. Не забудьте дождаться достаточно долгого времени до DwellTime , чтобы активировать событие. Обратите внимание, что необходимо принять запрос, чтобы включить разрешения расположения для приложения.
  6. Используйте Visual Studio для активации фоновой задачи расположения. Дополнительные сведения о активации фоновых задач в Visual Studio см. в разделе "Как активировать фоновые задачи".

Устранение неполадок приложений

Прежде чем приложение сможет получить доступ к расположению, необходимо включить расположение на устройстве. В приложении "Параметры" убедитесь, что включены следующие параметры конфиденциальности расположения:

  • Расположение для этого устройства... включен (неприменимо в Windows 10 Mobile)
  • Параметр служб расположений, расположение, включен
  • В разделе "Выбор приложений, которые могут использовать ваше расположение", приложение установлено включено