次の方法で共有


ビジット追跡の使用ガイドライン

アクセス機能を使用すると、場所追跡のプロセスが効率化され、多くのアプリの実用的な目的でより効率的になります。 Visit は、ユーザーが出入りする重要な地理的領域として定義されます。 アクセスは geofences に似ていますが ユーザーが関心のある特定の領域に出入りしたときにのみアプリに通知を受け取ることができるため、バッテリ寿命の浪費となる可能性がある継続的な場所追跡が不要になります。 ただし、ジオフェンスとは異なり、Visit 領域はプラットフォーム レベルで動的に識別されるため、個々のアプリで明示的に定義する必要はありません。 また、アプリが追跡するアクセスの選択は、個々の場所をサブスクライブするのではなく、単一の細分性設定によって処理されます。

準備段階のセットアップ

先に進む前に、アプリがデバイスの場所にアクセスできることを確認します。 マニフェストで Location 機能を宣言し、 Geolocator.RequestAccessAsync メソッドを呼び出して、ユーザーがアプリの場所のアクセス許可を付与できるようにする必要があります。 これを行う方法の詳細については、「 ユーザーの場所を取得する を参照してください。

クラスに Geolocation 名前空間を追加することを忘れないでください。 これは、このガイドのすべてのコード スニペットが機能するために必要です。

using Windows.Devices.Geolocation;

最新の訪問を確認する

訪問追跡機能を使用する最も簡単な方法は、最後に既知の Visit 関連の状態変化を取得することです。 状態の変更とは、ユーザーが重要な場所に出入りするか、最後のレポート以降に大きな動きがあるか、ユーザーの場所が失われるプラットフォームログイベントです ( VisitStateChange 列挙型を参照)。 状態の変更は、 Geovisit インスタンスによって表されます。 最後に記録された状態変更の Geovisit インスタンスを取得するには、 GeovisitMonitor クラスで指定されたメソッドを使用します。

Note

最後にログに記録された訪問を確認しても、システムによって現在訪問が追跡されているわけではありません。 訪問の発生を追跡するには、フォアグラウンドでそれらを監視するか、バックグラウンド追跡用に登録する必要があります (以下のセクションを参照)。

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

Visit 関連の状態の変更の監視が完了したら、モニターを停止し、イベント ハンドラーの登録を解除する必要があります。 これは、アプリが一時停止または閉じられたときにも実行する必要があります。

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

バックグラウンドでアクセスを監視する

また、バックグラウンド タスクで Visit 監視を実装して、アプリが開いていない場合でも Visit 関連のアクティビティをデバイスで処理できるようにすることもできます。 これは、より汎用性とエネルギー効率が高く、推奨される方法です。

このガイドでは、 でモデルを使用し、アウトプロセス バックグラウンド タスクを登録しますメイン アプリケーション ファイルは 1 つのプロジェクトに存在し、バックグラウンド タスク ファイルは同じソリューション内の別のプロジェクトに存在します。 バックグラウンド タスクを初めて実装する場合は、そのガイダンスに主に従って、Visit-handling バックグラウンド タスクを作成するために以下に必要な置換を行うことをお勧めします。

Note

次のスニペットでは、わかりやすくするために、エラー処理やローカル ストレージなどの重要な機能が存在しません。 バックグラウンド アクセス処理の堅牢な実装については、 サンプル アプリを参照してください。

まず、アプリでバックグラウンド タスクのアクセス許可が宣言されていることを確認します。 Package.appxmanifest ファイルのApplication/Extensions要素に、次の拡張子を追加します (まだ存在しない場合は、Extensions要素を追加します)。

<Extension Category="windows.backgroundTasks" EntryPoint="Tasks.VisitBackgroundTask">
    <BackgroundTasks>
        <Task Type="location" />
    </BackgroundTasks>
</Extension>

次に、バックグラウンド タスク クラスの定義で、次のコードを貼り付けます。 このバックグラウンド タスクの Run メソッドは、トリガーの詳細 (Visits 情報を含む) を別のメソッドに渡すだけです。

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

これにより、名前空間TasksVisitBackgroundTaskと呼ばれるバックグラウンド タスク クラスが、location トリガーの種類で何かを行うことを確立します。

これで、アプリはアクセス処理のバックグラウンド タスクを登録できるようになり、デバイスが Visit 関連の状態の変更をログに記録するたびに、このタスクをアクティブにする必要があります。 バックグラウンド タスク クラスのロジックを入力して、この状態変更情報の処理を決定する必要があります。