Рекомендации по использованию функции отслеживания посещений
Примечание
MapControl и службы карт требуют ключ проверки подлинности Maps, который называется MapServiceToken. Дополнительные сведения о получении и установке ключа проверки подлинности карт см. в статье Запрос ключа проверки подлинности карт.
Функция посещений упрощает процесс отслеживания местоположения, чтобы повысить его эффективность при фактическом использовании многих приложений. Посещение определяется как значительная географическая область, в которую пользователь входит и из которой выходит. Посещения похожи на геозоны, так как они позволяют отправлять приложению уведомление, только если пользователь входит в определенные целевые области или покидает их, что устраняет необходимость постоянного отслеживания местоположения и, как следствие, замедляет снижение уровня заряда. Тем не менее, в отличие от геозон, области посещения динамически определяются на уровне платформы и не требуют явного определения отдельными приложениями. Кроме того, выбор посещений для отслеживания приложением регулируется одним параметром детализации, а не подпиской на отдельные места.
Предварительная настройка
Прежде чем продолжить, убедитесь, что ваше приложение может получить доступ к местоположению устройства. Необходимо объявить возможность Location
в манифесте и вызвать метод Geolocator.RequestAccessAsync, чтобы пользователи предоставили приложению разрешение на отслеживание местоположения. Дополнительные сведения о том, как это сделать, см. в разделе Получение местоположения пользователя.
Обязательно добавьте пространство имен Geolocation
в ваш класс. Это потребуется для работы всех фрагментов кода в этом руководстве.
using Windows.Devices.Geolocation;
Проверка последнего посещения
Самый простой способ использования функции отслеживания посещений заключается в получении последнего известного изменения состояния, связанного с посещением. Изменение состояния — это событие, заносимое в журнал платформой, которое происходит в трех случаях: пользователь входит в значимое местоположение или покидает его, пользователь перемещается на существенное расстояние с момента последнего отчета, либо местоположение пользователя теряется (см. перечисление VisitStateChange). Изменения состояния представлены экземплярами Geovisit. Чтобы получить экземпляр Geovisit для последнего зарегистрированного изменения состояния, используйте указанный метод в классе GeovisitMonitor.
Примечание
Проверка последнего занесенного в журнал посещения не гарантирует, что система отслеживает посещения. Для отслеживания посещений в режиме реального времени необходимо выполнять их мониторинг на переднем плане или зарегистрироваться для фонового отслеживания (см. разделы ниже).
private async void GetLatestStateChange() {
// retrieve the Geovisit instance
Geovisit latestVisit = await GeovisitMonitor.GetLastReportAsync();
// Using the properties of "latestVisit", parse out the time that the state
// change was recorded, the device's location when the change was recorded,
// and the type of state change.
}
Анализ экземпляра Geovisit (необязательно)
Следующий метод преобразовывает все данные, хранящиеся в экземпляре Geovisit, в удобную для чтения строку. Его можно использовать в любом из сценариев в этом руководстве, чтобы упростить отправку отчетов по регистрируемым посещениям.
private string ParseGeovisit(Geovisit visit){
string visitString = null;
// Use a DateTimeFormatter object to process the timestamp. The following
// format configuration will give an intuitive representation of the date/time
Windows.Globalization.DateTimeFormatting.DateTimeFormatter formatterLongTime;
formatterLongTime = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(
"{hour.integer}:{minute.integer(2)}:{second.integer(2)}", new[] { "en-US" }, "US",
Windows.Globalization.CalendarIdentifiers.Gregorian,
Windows.Globalization.ClockIdentifiers.TwentyFourHour);
// use this formatter to convert the timestamp to a string, and add to "visitString"
visitString = formatterLongTime.Format(visit.Timestamp);
// Next, add on the state change type value
visitString += " " + visit.StateChange.ToString();
// Next, add the position information (if any is provided; this will be null if
// the reported event was "TrackingLost")
if (visit.Position != null) {
visitString += " (" +
visit.Position.Coordinate.Point.Position.Latitude.ToString() + "," +
visit.Position.Coordinate.Point.Position.Longitude.ToString() +
")";
}
return visitString;
}
Мониторинг посещений на переднем плане
Класс GeovisitMonitor, используемый в предыдущем разделе, отвечает также за обработку сценария прослушивания изменений состояния за определенный период времени. Для этого необходимо создать экземпляр данного класса, зарегистрировать метод обработчика этого события и вызвать метод Start
.
// this GeovisitMonitor instance will belong to the class scope
GeovisitMonitor monitor;
public void RegisterForVisits() {
// Create and initialize a new monitor instance.
monitor = new GeovisitMonitor();
// Attach a handler to receive state change notifications.
monitor.VisitStateChanged += OnVisitStateChanged;
// Calling the start method will start Visits tracking for a specified scope:
// For higher granularity such as venue/building level changes, choose Venue.
// For lower granularity in the range of zipcode level changes, choose City.
monitor.Start(VisitMonitoringScope.Venue);
}
В этом примере метод OnVisitStateChanged
будет обрабатывать входящие отчеты о посещениях. Соответствующий экземпляр Geovisit передается через параметр события.
private void OnVisitStateChanged(GeoVisitWatcher sender, GeoVisitStateChangedEventArgs args) {
Geovisit visit = args.Visit;
// Using the properties of "visit", parse out the time that the state
// change was recorded, the device's location when the change was recorded,
// and the type of state change.
}
Когда приложение завершит мониторинг изменений состояния, связанных с посещениями, оно должно остановить работу монитора и отменить регистрацию обработчиков событий. Это также необходимо сделать, если приложение приостановлено или закрыто.
public void UnregisterFromVisits() {
// Stop the monitor to stop tracking Visits. Otherwise, tracking will
// continue until the monitor instance is destroyed.
monitor.Stop();
// Remove the handler to stop receiving state change events.
monitor.VisitStateChanged -= OnVisitStateChanged;
}
Мониторинг посещений в фоновом режиме
Также можно реализовать мониторинг посещений в фоновой задаче, чтобы действия, связанные с посещениями, обрабатывались на устройстве, даже если приложение закрыто. Это рекомендуемый метод, так как он более универсален и требует меньше энергии.
В этом руководстве будет использоваться модель из раздела Создание и регистрация внепроцессной фоновой задачи, согласно которой основные файлы приложения расположены в одном проекте, а файл фоновой задачи — в отдельном проекте в том же решении. Если вы не знакомы с реализацией фоновых задач, рекомендуется в целом следовать указанному руководству и делать необходимые замены ниже, чтобы создать фоновую задачу для обработки посещений.
Примечание
В следующих фрагментах кода некоторые важные возможности, такие как обработка ошибок и локальное хранилище, отсутствуют для большего удобства. Действующую реализацию обработки посещений в фоновом режиме см. в примере приложения.
Прежде всего, убедитесь, что в вашем приложении объявлены разрешения на выполнение фоновых задач. В элементе Application/Extensions
файла Package.appxmanifest добавьте следующее расширение (добавьте элемент Extensions
, если он еще не существует).
<Extension Category="windows.backgroundTasks" EntryPoint="Tasks.VisitBackgroundTask">
<BackgroundTasks>
<Task Type="location" />
</BackgroundTasks>
</Extension>
Затем вставьте следующий код в определение класса фоновой задачи. Метод Run
этой фоновой задачи передаст состав триггера (который содержит сведения о посещениях) отдельному методу.
using Windows.ApplicationModel.Background;
namespace Tasks {
public sealed class VisitBackgroundTask : IBackgroundTask {
public void Run(IBackgroundTaskInstance taskInstance) {
// get a deferral
BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
// this task's trigger will be a Geovisit trigger
GeovisitTriggerDetails triggerDetails = taskInstance.TriggerDetails as GeovisitTriggerDetails;
// Handle Visit reports
GetVisitReports(triggerDetails);
finally {
deferral.Complete();
}
}
}
}
Определите метод GetVisitReports
в любом месте этого же класса.
private void GetVisitReports(GeovisitTriggerDetails triggerDetails) {
// Read reports from the triggerDetails. This populates the "reports" variable
// with all of the Geovisit instances that have been logged since the previous
// report reading.
IReadOnlyList<Geovisit> reports = triggerDetails.ReadReports();
foreach (Geovisit report in reports) {
// Using the properties of "visit", parse out the time that the state
// change was recorded, the device's location when the change was recorded,
// and the type of state change.
}
// Note: depending on the intent of the app, you many wish to store the
// reports in the app's local storage so they can be retrieved the next time
// the app is opened in the foreground.
}
Затем в основном проекте приложения необходимо выполнить регистрацию этой фоновой задачи. Создайте метод регистрации, который может быть вызван действием пользователя или вызывается при каждой активации класса.
// a reference to this registration should be declared at the class level
private IBackgroundTaskRegistration visitTask = null;
// The app must call this method at some point to allow future use of
// the background task.
private async void RegisterBackgroundTask(object sender, RoutedEventArgs e) {
string taskName = "MyVisitTask";
string taskEntryPoint = "Tasks.VisitBackgroundTask";
// First check whether the task in question is already registered
foreach (var task in BackgroundTaskRegistration.AllTasks) {
if (task.Value.Name == taskName) {
// if a task is found with the name of this app's background task, then
// return and do not attempt to register this task
return;
}
}
// Attempt to register the background task.
try {
// Get permission for a background task from the user. If the user has
// already responded once, this does nothing and the user must manually
// update their preference via Settings.
BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
switch (backgroundAccessStatus) {
case BackgroundAccessStatus.AlwaysAllowed:
case BackgroundAccessStatus.AllowedSubjectToSystemPolicy:
// BackgroundTask is allowed
break;
default:
// notify user that background tasks are disabled for this app
//...
break;
}
// Create a new background task builder
BackgroundTaskBuilder visitTaskBuilder = new BackgroundTaskBuilder();
visitTaskBuilder.Name = exampleTaskName;
visitTaskBuilder.TaskEntryPoint = taskEntryPoint;
// Create a new Visit trigger
var trigger = new GeovisitTrigger();
// Set the desired monitoring scope.
// For higher granularity such as venue/building level changes, choose Venue.
// For lower granularity in the range of zipcode level changes, choose City.
trigger.MonitoringScope = VisitMonitoringScope.Venue;
// Associate the trigger with the background task builder
visitTaskBuilder.SetTrigger(trigger);
// Register the background task
visitTask = visitTaskBuilder.Register();
}
catch (Exception ex) {
// notify user that the task failed to register, using ex.ToString()
}
}
Таким образом, класс фоновой задачи с именем VisitBackgroundTask
в пространстве имен Tasks
выполнит определенное действие с типом триггера location
.
После этого ваше приложение сможет регистрировать фоновую задачу обработки посещений, а эта задача будет активироваться каждый раз, когда устройство заносит в журнал изменение состояния, связанного с посещением. Потребуется заполнить логику в классе фоновой задачи, чтобы определить, что делать с этими сведениями об изменении состояния.
Связанные разделы
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по