Рекомендации по использованию функции отслеживания посещений
Функция "Визиты" упрощает процесс отслеживания расположения, чтобы сделать его более эффективным для практических целей многих приложений. Визит определяется как важная географическая область, в которую пользователь входит и выходит. Посещения аналогичны геозонам , что они позволяют приложению получать уведомления только при входе или выходе из определенных областей интереса, устраняя необходимость постоянного отслеживания расположения, которое может быть утечкой батареи. Однако в отличие от геозон, области посещения динамически определяются на уровне платформы и не должны быть явно определены отдельными приложениями. Кроме того, выбор того, какие посещения приложения будут отслеживаться, обрабатывается одним параметром детализации, а не путем подписки на отдельные места.
Предварительная настройка
Прежде чем идти дальше, убедитесь, что ваше приложение может получить доступ к расположению устройства. Необходимо объявить 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
метод будет обрабатывать входящие отчеты Visit. Соответствующий экземпляр 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
.
Теперь приложение должно быть способно зарегистрировать фоновую задачу для обработки посещений, и эта задача должна быть активирована всякий раз, когда устройство регистрирует изменение состояния, связанного с посещением. Вам потребуется заполнить логику в фоновом классе задач, чтобы определить, что делать с данными об изменении состояния.