SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine(コードジン) DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

UWPアプリ開発の最前線

Windows 10 1803の新機能「タイムライン」とはなにか?
~まずはUWPアプリから使ってみる

UWPアプリ開発の最前線 第5回


プロトコルアクティベーションに対応する方法

 「タイムライン」にカードを表示できるようになりましたが、それだけではカードをクリックしても何も起きません。プロトコルアクティベーションに対応したアプリにする必要があります。

 UWPアプリでは、次の2つの作業が必要です。

  1. マニフェストに宣言する:アプリケーションマニフェストの[宣言]タブでアクティベーションURIのスキーム(プロトコル)を追加します
  2. プロトコルアクティベーションを処理する:App.xaml.csでOnActivatedメソッドをオーバーライドします。引数に渡されたProtocolActivatedEventArgsを見て、以前の状態を復元します

マニフェストでプロトコルを宣言する

 Visual Studioのソリューションエクスプローラーで「Package.appxmanifest」ファイルをダブルクリックしてマニフェストエディターを開きます。[宣言]タブを選び、[使用可能な宣言]で[プロトコル]を選んで[追加]ボタンをクリックし、[名前]欄にアクティベーションURIのスキーム(「:」は含みません)を入力します(次の画像)。[名前]欄の上の[ロゴ]と[表示名]はオプションです。[名前]欄より下の項目は、通常はどれも変更しません。

 これで、このUWPアプリを配置したときに、アクティベーションURIが自動的に登録されます。

Visual Studioのマニフェストエディター
マニフェストにプロトコル宣言を追加する手順

プロトコルアクティベーションを処理する

 普通にUWPアプリを起動したときはOnLaunchedメソッドが呼び出されますが、プロトコルアクティベーションではOnActivatedメソッドが呼ばれます。アプリがすでに実行中であってもOnActivatedメソッドが呼び出されます。プロトコル以外の方法でアクティブ化されたときもOnActivatedメソッドは呼び出されるので、メソッド内ではプロトコルアクティベーションかどうかの判定が必要です。

 プロトコルアクティベーションの場合はOnActivatedメソッドに渡される引数がProtocolActivatedEventArgs型(Windows.ApplicationModel.Activation名前空間)なので、そのUriプロパティからアクティベーションURIを取得して、アプリの状態を復元する処理を行います。

 起動時にアプリの状態を復元するには、そのために必要な情報を表す(または、その情報へのキーとなる)文字列をNavigateメソッドの第2引数としてページ遷移し、遷移先で状態を復元します。

 すでに起動している状態でアプリの状態を復元するときは、起動時と同様にしてもよいです。ただし、それでは状態を変更しなくてもよいときでも、画面が初期化されてしまいます。例えば、このサンプルでは、復元するべきユーザーアクティビティと同じWebページをすでに表示していた場合、画面が初期化される(=Webページが再読み込みされ、スクロール位置が初期化される)のは好ましくありません。そこで、すでに起動している状態でプロトコルアクティベーションを受けた場合には、状態を変える必要がなければ変更しないようにする処理を入れた方がよいでしょう。

 以上の処理を記述したコードを次に示します。まずApp.xaml.csの該当部分から。

プロトコルアクティベーションを処理するコード(App.xaml.cs内)
// アクティベーション時に呼び出されるメソッド
protected override void OnActivated(IActivatedEventArgs args)
{
  Frame rootFrame = Window.Current.Content as Frame;
  if (rootFrame == null)
  {
    // 起動していないときにアクティベートされた場合は Frame がないので
    // 新しく Frame を生成しておく
    rootFrame = new Frame();
    rootFrame.NavigationFailed += OnNavigationFailed;
    Window.Current.Content = rootFrame;
  }

  // アクティベートされたプロトコルの種類をチェックして、引数を適切な型にキャストする
  if (args.Kind == ActivationKind.Protocol
      && args is ProtocolActivatedEventArgs protocolEventArgs)
  {
    // プロトコルアクティベーションの場合、その Uri プロパティがアクティベーション URI
    switch (protocolEventArgs.Uri.Host)
    {
      case "url":
        // Query の先頭文字 ('?') を除いた部分が表示すべき URL
        string url = protocolEventArgs.Uri.Query.Substring(1);
        MainPageNavigate(url); // 状態を復元する(ここでは、Webページを表示するだけ)
        break;
      default:
        throw new ArgumentOutOfRangeException();
    }
  }
  Window.Current.Activate();
}

void MainPageNavigate(string url)
{
  Frame rootFrame = Window.Current.Content as Frame;
  if(rootFrame.Content is MainPage mainPage)
    // すでに実行中で、しかも MainPage を表示している場合
    mainPage.Navigate(url);
    // ↑この Navigate メソッドは、表示中のURLと同じURLが渡されたときは表示を変更しない
  else
    // 起動時、または、起動していても MainPage を表示していない場合
    rootFrame.Navigate(typeof(MainPage), url);
}

 続いて、MainPage.xaml.csの該当部分です。

プロトコルアクティベーションを処理するコード(MainPage.xaml.cs内)
// このページに遷移してきたときに呼び出されるメソッド
protected override void OnNavigatedTo(NavigationEventArgs e)
{
  base.OnNavigatedTo(e);

  // 引数に (空でない) 文字列が入っていたら、URL として Web ページを表示する
  if (e.Parameter is string url && !string.IsNullOrWhiteSpace(url))
    Navigate(url);
}

// 表示している Web ページを変更するメソッド
internal async void Navigate(string url)
{
  if (this.WebView1.Source?.ToString() == url)
  {
    // 現在表示している URL と同じなら、何もせずに「タイムライン」への登録だけ行う
    await TimelineLIb.TimelineHelper.Current.AddToTimelineAsync(url, GetCardType());
  }
  else
  {
    // 現在表示している URL と異なっているなら、その Web ページを表示する
    this.UrlTextBox.Text = url;
    this.WebView1.Navigate(new Uri(url));
    // ↑ Web ページの表示に成功すると「タイムライン」への登録が行われる
  }
}

次のページ
「ユーザーアクティビティ」カードをデザインする方法

この記事は参考になりましたか?

UWPアプリ開発の最前線連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10790 2019/11/10 21:09

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー