次の方法で共有


デバイス間でもユーザーのアクティビティを継続する

このトピックでは、ユーザーが自分の PC やデバイス間でアプリで実行していた操作を再開する方法について説明します。

Note

2021 年 7 月から、Microsoft アカウント (MSA) を介して Windows デバイス間でアクティビティ履歴を同期しているユーザーには、タイムラインでの新しいアクティビティのアップロードのオプションがなくなりました。 引き続きタイムラインを使用して、ローカル PC でアクティビティ履歴 (最近使用したアプリ、Web サイト、ファイルに関する情報) を表示できます。 AAD 接続されたアカウントには影響はありません。

ユーザー アクティビティとタイムライン

私たちの毎日の時間は、複数のデバイスに分散しています。 バスに乗っている間は電話を使い、日中はPCを使い、夕方には電話やタブレットを使うかもしれません。 Windows 10 ビルド 1803 以降では、 User アクティビティを作成すると そのアクティビティが Windows タイムラインと Cortana の [ピックアップ] 機能に表示されます。 タイムラインは、ユーザー アクティビティを利用して、作業内容の時系列ビューを表示する豊富なタスク ビューです。 また、デバイス間で作業していた内容を含めることもできます。

Windows タイムラインの画像

同様に、スマートフォンを Windows PC にリンクすると、iOS または Android デバイスで以前実行していた操作を続行できます。

UserActivity は、ユーザーがアプリ内で作業していた特定のものとして考えてください。 たとえば、RSS リーダーを使用している場合、UserActivity は読み取っているフィードである可能性があります。 ゲームをプレイしている場合、UserActivity はプレイしているレベルになる可能性があります。 音楽アプリを聴いている場合、UserActivity は、聴いているプレイリストである可能性があります。 ドキュメントで作業している場合、UserActivity は作業を中断した場所などです。 つまり、 UserActivity はアプリ内の宛先を表し、ユーザーが実行していた操作を再開できるようにします。

UserActivity.CreateSessionを呼び出してUserActivityを操作すると、そのUserActivityの開始時刻と終了時刻を示す履歴レコードが作成されます。 時間の経過と共にその UserActivity に再び関わると、そのユーザーに対して複数の履歴レコードが記録されます。

アプリにユーザー アクティビティを追加する

UserActivity は、Windows でのユーザー エンゲージメントの単位です。 これには、アクティビティが属するアプリのアクティブ化に使用される URI、ビジュアル、アクティビティを説明するメタデータの 3 つの部分があります。

  1. ActivationUri は、特定のコンテキストでアプリケーションを再開するために使用されます。 通常、このリンクは、スキームのプロトコル ハンドラー (例: "my-app://page2?action=edit") または AppUriHandler (例: http://contoso.com/page2?action=edit) の形式をとります。
  2. VisualElements は、ユーザーがタイトル、説明、またはアダプティブ カード要素を使用してアクティビティを視覚的に識別できるようにするクラスを公開します。
  3. 最後に、コンテンツでは、特定のコンテキストでアクティビティをグループ化および取得するために使用できるアクティビティのメタデータを保存できます。 多くの場合、これは https://schema.org データの形式を取ります。

UserActivity をアプリに追加するには:

  1. アプリ内でユーザーのコンテキストが変更されたときに UserActivity オブジェクトを生成します (ページ ナビゲーション、新しいゲーム レベルなど)。
  2. UserActivity オブジェクトに必要なフィールドの最小セット (ActivityIdActivationUri、および UserActivity.VisualElements.DisplayText を設定します。
  3. UserActivity によって再アクティブ化できるように、カスタム スキーム ハンドラーをアプリに追加します。

UserActivityは、わずか数行のコードでアプリに統合できます。 たとえば、MainPage クラス内の MainPage.xaml.cs の次のコードを考えてみましょう (注: using Windows.ApplicationModel.UserActivities;を想定しています)。

UserActivitySession _currentActivity;
private async Task GenerateActivityAsync()
{
    // Get the default UserActivityChannel and query it for our UserActivity. If the activity doesn't exist, one is created.
    UserActivityChannel channel = UserActivityChannel.GetDefault();
    UserActivity userActivity = await channel.GetOrCreateUserActivityAsync("MainPage");
 
    // Populate required properties
    userActivity.VisualElements.DisplayText = "Hello Activities";
    userActivity.ActivationUri = new Uri("my-app://page2?action=edit");
     
    //Save
    await userActivity.SaveAsync(); //save the new metadata
 
    // Dispose of any current UserActivitySession, and create a new one.
    _currentActivity?.Dispose();
    _currentActivity = userActivity.CreateSession();
}

上記の GenerateActivityAsync() メソッドの最初の行は、ユーザーの UserActivityChannelを取得します。 これは、このアプリのアクティビティが公開されるフィードです。 次の行は、 MainPageと呼ばれるアクティビティのチャネルを照会します。

  • アプリでは、ユーザーがアプリ内の特定の場所にいるたびに同じ ID が生成されるようにアクティビティに名前を付ける必要があります。 たとえば、アプリがページベースの場合は、ページの識別子を使用します。ドキュメントベースの場合は、ドキュメントの名前 (または名前のハッシュ) を使用します。
  • 同じ ID のフィードに既存のアクティビティがある場合、そのアクティビティはチャネルから返され、 UserActivity.StatePublished) に設定されます。 その名前のアクティビティがなく、 UserActivity.StateNew に設定された状態で新しいアクティビティが返される場合。
  • アクティビティのスコープはアプリに設定されます。 アクティビティ ID が他のアプリの ID と衝突することを心配する必要はありません。

UserActivity を取得または作成した後で、他の 2 つの必須フィールド、 UserActivity.VisualElements.DisplayTextUserActivity.ActivationUri を指定します。

次に、SaveAsync を呼び出して UserActivity メタデータを保存し、最後に CreateSession を取得して、UserActivitySession を返します。 UserActivitySession は、ユーザーが実際に UserActivity に関与しているときの管理に使用できるオブジェクトです。 たとえば、ユーザーがページを離れたときに、UserActivitySessionDispose()を呼び出す必要があります。 上記の例では、CreateSession()を呼び出す前に、_currentActivityDispose()も呼び出します。 これは、ページのメンバー フィールド _currentActivity し、新しいアクティビティを開始する前に既存のアクティビティを停止する必要があるためです (注: ? は、メンバー アクセスを実行する前に null をテストする null 条件演算子 です)。

この場合、 ActivationUri はカスタム スキームであるため、プロトコルもアプリケーション マニフェストに登録する必要があります。 これは、Package.appmanifest XML ファイルで、またはデザイナーを使用して行います。

デザイナーで変更を行うには、プロジェクトの Package.appmanifest ファイルをダブルクリックしてデザイナーを起動し、[宣言] タブを選択してプロトコル定義を追加します。 現時点では、入力する必要がある唯一のプロパティは Name です。 これは、上記で指定した URI ( my-app) と一致する必要があります。

次に、プロトコルによってアクティブ化されたときに何をすべきかをアプリに伝えるコードを記述する必要があります。 次のように、App.xaml.csの OnActivated メソッドをオーバーライドして、URI をメイン ページに渡します。

protected override void OnActivated(IActivatedEventArgs e)
{
    if (e.Kind == ActivationKind.Protocol)
    {
        var uriArgs = e as ProtocolActivatedEventArgs;
        if (uriArgs != null)
        {
            if (uriArgs.Uri.Host == "page2")
            {
                // Navigate to the 2nd page of the  app
            }
        }
    }
    Window.Current.Activate();
}

このコードでは、アプリがプロトコルを介してアクティブ化されたかどうかを検出します。 有効になっている場合は、アクティブ化されているタスクを再開するためにアプリが実行する必要があることを確認します。 シンプルなアプリであるため、このアプリが再開する唯一のアクティビティは、アプリが起動したときにセカンダリページにユーザーを入れることです。

アダプティブ カードを使用してタイムライン エクスペリエンスを向上させる

ユーザー アクティビティが Cortana とタイムラインに表示されます。 タイムラインにアクティビティが表示されたら、 Adaptive Card フレームワークを使用してアクティビティを表示します。 アクティビティごとにアダプティブ カードを指定しない場合、タイムラインは、アプリケーション名とアイコン、タイトル フィールド、およびオプションの説明フィールドに基づいて、単純なアクティビティ カードを自動的に作成します。 アダプティブ カードペイロードと生成されるカードの例を次に示します。

アダプティブ カード]

アダプティブ カード ペイロード JSON 文字列の例:

{ 
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", 
  "type": "AdaptiveCard", 
  "version": "1.0",
  "backgroundImage": "https://winblogs.azureedge.net/win/2017/11/eb5d872c743f8f54b957ff3f5ef3066b.jpg", 
  "body": [ 
    { 
      "type": "Container", 
      "items": [ 
        { 
          "type": "TextBlock", 
          "text": "Windows Blog", 
          "weight": "bolder", 
          "size": "large", 
          "wrap": true, 
          "maxLines": 3 
        }, 
        { 
          "type": "TextBlock", 
          "text": "Training Haiti’s radiologists: St. Louis doctor takes her teaching global", 
          "size": "default", 
          "wrap": true, 
          "maxLines": 3 
        } 
      ] 
    } 
  ]
}

アダプティブ カード ペイロードを JSON 文字列として UserActivity に追加します 次のようにします。

activity.VisualElements.Content = 
Windows.UI.Shell.AdaptiveCardBuilder.CreateAdaptiveCardFromJson(jsonCardText); // where jsonCardText is a JSON string that represents the card

クロスプラットフォームとサービス間の統合

アプリがクロスプラットフォーム (Android や iOS など) で実行されている場合、またはクラウドでユーザーの状態を維持している場合は、 Microsoft Graph を使用して UserActivities を発行できます。 アプリケーションまたはサービスが Microsoft アカウントで認証されると、上記と同じデータを使用して、 Activity オブジェクトと History オブジェクトを生成する単純な REST 呼び出しが 2 回だけ実行されます。

まとめ

UserActivity API を使用して、アプリをタイムラインと Cortana に表示できます。

キー API