デバイス間でもユーザーのアクティビティを継続するContinue user activity, even across devices

このトピックでは、前回ユーザーがアプリで実行していた状態から再開できるようにする方法 (PC およびデバイス間で再開する場合にも対応) について説明します。This topic describes how to help users resume what they were doing in your app on their PC, and across devices.

ユーザー アクティビティとタイムラインUser Activities and Timeline

私たちの毎日の時間は、複数のデバイス間に広がっています。Our time each day is spread across multiple devices. 私たちは、バスの中でスマートフォンを、日中は PC を、夜は電話やタブレットを使用しています。We might use our phone while on the bus, a PC during the day, then a phone or tablet in the evening. Windows 10 ビルド 1803 以降では、ユーザー アクティビティ を作成すると、そのアクティビティが Windows タイムラインと Cortana の 前回終了した位置から再開機能に表示されるようになりました。Starting in Windows 10 Build 1803 or higher, creating a User Activity makes that activity appear in Windows Timeline and in Cortana's Pick up where I left off feature. タイムラインは、ユーザー アクティビティを活用して作業していることを時系列に表示する豊富な機能を備えたタスク ビューです。Timeline is a rich task view that takes advantage of User Activities to show a chronological view of what you’ve been working on. また、さまざまなデバイス間で作業していた内容も含めることができます。It can also include what you were working on across devices.

Windows タイムラインのイメージ

同様に、お使いの電話を Windows PC に接続すると、以前に iOS やAndroid デバイスで行っていた作業を続けることができます。Likewise, linking your phone to your Windows PC allows you to continue what you were doing previously on your iOS or Android device.

UserActivity は、ユーザーがあなたのアプリ内で作業していたことと考えてください。Think of a UserActivity as something specific the user was working on within your app. たとえば、RSSリーダーを使用している場合、UserActivity はあなたが読んでいるフィードになります。For example, if you are using a RSS reader, a UserActivity could be the feed that you are reading. ゲームをプレイしている場合、UserActivity はあなたがプレイしているレベルになります。If you are playing a game, the UserActivity could be the level that you are playing. 音楽アプリを聴いている場合は、UserActivity があなたが聴いているプレイリストになります。If you are listening to a music app, the UserActivity could be the playlist that you are listening to. ドキュメントで作業している場合、UserActivity は作業を中断した場所になるなどです。If you are working on a document, the UserActivity could be where you left off working on it, and so on. 要するに、UserActivity は、ユーザーが自分のやっていることを再開できるように、アプリ内の目的地を表すものです。In short, a UserActivity represents a destination within your app so that enables the user to resume what they were doing.

UserActivity.CreateSession を呼び出して UserActivity を使用すると、システムは UserActivityの開始時刻と終了時刻を示す履歴レコードを作成します。When you engage with a UserActivity by calling UserActivity.CreateSession, the system creates a history record indicating the start and end time for that UserActivity. 時間の経過とともに UserActivity を再使用していくと、複数の履歴レコードが記録されます。As you re-engage with that UserActivity over time, multiple history records are recorded for it.

アプリにユーザー アクティビティを追加するAdd User Activities to your app

UserActivity は、Windows でのユーザー エンゲージメントの単位です。A UserActivity is the unit of user engagement in Windows. これには、アクティビティが属するアプリをアクティブ化するために使用される URI、ビジュアル、およびアクティビティを記述するメタデータの 3 つの部分があります。It has three parts: a URI used to activate the app the activity belongs to, visuals, and metadata that describes the activity.

  1. ActivationUri は、特定のコンテキストでアプリケーションを再開するために使用します。The ActivationUri is used to resume the application with a specific context. 通常、このリンクは、スキームのプロトコル ハンドラー (例: “my-app://page2?action=edit”) または AppUriHandler (例: http://constoso.com/page2?action=edit) のフォームをとります。Typically, this link takes the form of protocol handler for a scheme (e.g. “my-app://page2?action=edit”) or of an AppUriHandler (e.g. http://constoso.com/page2?action=edit).
  2. VisualElements は、タイトル、説明、またはアダプティブ カード要素でアクティビティを視覚的に識別できるようにするクラスを公開します。VisualElements exposes a class that allows the user to visually identify an activity with a title, description, or Adaptive Card elements.
  3. 最後に、コンテンツ は、特定のコンテキストでアクティビティをグループ化したり取得したりするために使用できるアクティビティのメタデータを格納できます。Finally, Content is where you can store metadata for the activity that can be used to group and retrieve activities under a specific context. 多くの場合、これは https://schema.org データのフォームとなります。Often, this takes the form of https://schema.org data.

UserActivity をアプリに追加するには:To add a UserActivity to your app:

  1. アプリケーション内でユーザーのコンテキスト (ページ ナビゲーション、新しいゲームレベルなど) が変更されたときに UserActivity オブジェクトを生成するGenerate UserActivity objects when your user’s context changes within the app (such as page navigation, new game level, etc.)
  2. 設定UserActivity必須フィールドの最小セットを持つオブジェクト。ActivityIdActivationUri、およびUserActivity.VisualElements.DisplayTextします。Populate UserActivity objects with the minimum set of required fields: ActivityId, ActivationUri, and UserActivity.VisualElements.DisplayText.
  3. UserActivity によって再アクティブ化できるように、カスタム スキーム ハンドラーをアプリケーションに追加します。Add a custom scheme handler to your app so it can be re-activated by a UserActivity.

UserActivity はわずか数行のコードでアプリに統合できます。A UserActivity can be integrated into an app with just a few lines of code. たとえば、MainPage.xaml.cs の MainPage クラス内でこのコードを想像してみてください (注: using Windows.ApplicationModel.UserActivities; を前提としています)。For example, imagine this code in MainPage.xaml.cs, inside the MainPage class (note: assumes 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 を取得します。The first line in the GenerateActivityAsync() method above gets a user’s UserActivityChannel. これは、このアプリのアクティビティが公開されるフィードです。This is the feed that this app’s activities will be published to. 次の行は、MainPage と呼ばれるアクティビティのチャネルを照会します。The next line queries the channel of an activity called MainPage.

  • ユーザーがアプリの特定の場所にいるたびに同じ ID が生成されるように、アクティビティに名前を付ける必要があります。Your app should name activities in such a way that same ID is generated each time the user is in a particular location in the app. たとえば、アプリがページ ベースの場合は、ページの識別子を使用します。ドキュメント ベースの場合は、ドキュメントの名前 (または名前のハッシュ) を使用します。For example, if your app is page-based, use an identifier for the page; if its document based, use the name of the doc (or a hash of the name).
  • 同じ ID を持つフィードに既存のアクティビティがある場合、そのアクティビティは UserActivity.State公開済み に設定されているチャンネルから返されますIf there is an existing activity in the feed with the same ID, that activity will be returned from the channel with UserActivity.State set to Published). その名前のアクティビティがない場合、UserActivity.StateNew に設定された状態で新しいアクティビティが返されます。If there is no activity with that name, and new activity is returned with UserActivity.State set to New.
  • アクティビティがアプリに適用されます。Activities are scoped to your app. アクティビティ ID が他のアプリの ID と競合するのを心配する必要はありません。You do not need to worry about your activity ID colliding with IDs in other apps.

UserActivity を取得または作成した後で、他の 2 つの必須フィールド、 UserActivity.VisualElements.DisplayTextUserActivity.ActivationUri を指定します。After getting or creating the UserActivity, specify the other two required fields: UserActivity.VisualElements.DisplayTextand UserActivity.ActivationUri.

次に、SaveAsync を呼び出して UserActivity を保存し、最後に CreateSession を保存します。これは UserActivitySession を返します。Next, save the UserActivity metadata by calling SaveAsync, and finally CreateSession, which returns a UserActivitySession. UserActivitySession は、ユーザーが実際に UserActivity を使用しているときに、管理するために使用できるオブジェクトです。The UserActivitySession is the object that we can use to manage when the user is actually engaged with the UserActivity. たとえば、UserActivitySession 上でユーザーがページを離れるときに Dispose() を呼び出す必要があります。For example, we should call Dispose() on the UserActivitySession when the user leaves the page. 上記の例では、CreateSession() を呼び出す前に _currentActivityDispose()` を呼び出しています。In the example above, we also call Dispose() on _currentActivity before calling CreateSession(). これは、_currentActivity をページのメンバー フィールドにして、新しいものを開始する前に既存のアクティビティを停止したいからです (注:?null 条件演算子 で、メンバー アクセスを実行する前に null をテストします)。This is because we made _currentActivity a member field of our page, and we want to stop any existing activity before we start the new one (note: the ? is the null-conditional operator which tests for null before performing the member access).

この場合、ActivationUri はカスタム スキームであるため、アプリケーション マニフェストにプロトコルを登録する必要もあります。Since, in this case, the ActivationUri is a custom scheme, we also need to register the protocol in the application manifest. これは、Package.appmanifest XML ファイルで、またはデザイナーを使用して行います。This is done in the Package.appmanifest XML file, or by using the designer.

デザイナーで変更を加えるには、プロジェクトの Package.appmanifest ファイルをダブルクリックしてデザイナーを起動し、 [宣言] タブを選択して、 [プロトコル] 定義を追加します。To make the change with the designer, double-click the Package.appmanifest file in your project to launch the designer, select the Declarations tab and add a Protocol definition. 記入する必要がある唯一のプロパティは、現在、名前です。The only property that needs to be filled out, for now, is Name. 上記で指定した URI の my-app と一致するはずです。It should match the URI we specified above, my-app.

ここで、プロトコルによって起動されたときに何をすべきかをアプリに伝えるコードを記述する必要があります。Now we need to write some code to tell the app what to do when it’s been activated by a protocol. App.xaml.cs の OnActivated メソッドを上書きして、メイン ページに URI を渡します。We’ll override the OnActivated method in App.xaml.cs to pass the URI on to the main page, like so:

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

このコードは、アプリがプロトコル経由でアクティブ化されたかどうかを検出します。What this code does is detect whether the app was activated via a protocol. アクティブ化されていた場合は、アプリがアクティブ化されているタスクを再開するためにアプリが何をすべきかを確認します。If it was, then it looks to see what the app should do to resume the task it is being activated for. 簡単なアプリであるアクティビティだけがこのアプリを再開しますができるようにすることセカンダリ ページで、アプリが動作するときにします。Being a simple app, the only activity this app resumes is putting you on the secondary page when the app comes up.

アダプティブ カードを使用して、タイムラインのエクスペリエンスを向上させるUse Adaptive Cards to improve the Timeline experience

ユーザーのアクティビティは、Cortana とタイムラインに表示されます。User Activities appear in Cortana and Timeline. アクティビティがタイムラインに表示されたら、アダプティブ カードフレームワークを使用してアクティビティを表示します。When activities appear in Timeline, we display them using the Adaptive Card framework. アクティビティごとにアダプティブ カードを用意していない場合、タイムラインはアプリケーション名とアイコン、タイトル フィールド、およびオプションの説明フィールドに基づいて、簡単なアクティビティ カードを自動的に作成します。If you do not provide an adaptive card for each activity, Timeline will automatically create a simple activity card based on your application name and icon, the title field and optional description field. 以下は、アダプティブ カードのペイロードとそれが生成するカードの例です。Below is an example Adaptive Card payload and the card it produces.

アダプティブ カード]]

アダプティブ カードのペイロード JSON 文字列の例:Example adaptive card payload JSON string:

{ 
  "$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 
        } 
      ] 
    } 
  ]
}

以下のように、UserActivity に JSON 文字列としてアダプティブ カードのペイロードを追加します。Add the Adaptive Cards payload as a JSON string to the UserActivity like this:

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

クロス プラットフォームとサービス間の統合Cross-platform and Service-to-service integration

アプリがクロスプラットフォーム (Android や iOS など) で稼働している場合や、クラウドにユーザーの状態を保持している場合は、Microsoft Graph で UserActivities を公開できます。If your app runs cross-platform (for example on Android and iOS), or maintains user state in the cloud, you can publish UserActivities via Microsoft Graph. アプリケーションまたはサービスが Microsoft アカウントで認証されると、上記と同じデータを使用して アクティビティ オブジェクトと 履歴 オブジェクトを生成するための 2 回の単純な REST 呼び出しが必要です。Once your application or service is authenticated with a Microsoft Account, it just takes two simple REST calls to generate Activity and History objects, using the same data as described above.

概要Summary

UserActivity API を使用して、アプリをタイムラインと Cortana に表示させることができます。You can use the UserActivity API to make your app appear in Timeline and Cortana.

キー APIKey APIs