[WinRT] デスクトップで閲覧しているURLをSurface RTに送る – Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/4718
の逆向きパターンで、タブレットPCからデスクトップのほうにURLを送ります。
こっちのほうは、比較的簡単?で、タブレットPCで動作しているブラウザ(IE10)から共有を使って、ストアアプリに送信、そのストアアプリからデスクトップアプリに通信させます。簡易HTTPサーバーを立てるところは、前回と同じなので流用してます。というか同じアプリに乗せています。
■簡易HTTPサーバー
/// /// フォームロード時 /// /// /// private void Form1_Load(object sender, EventArgs e) { listener = new HttpListener(); listener.Prefixes.Add("http://*:8090/"); listener.Start(); // 受信待ちタスク Task tsk = new Task( () => { while (true) { var cont = listener.GetContext(); var req = cont.Request; var res = cont.Response; if (req.RawUrl.StartsWith("/GetUrl")) { Debug.WriteLine(string.Format("req {0}", req.RawUrl)); var tw = new StreamWriter(res.OutputStream); tw.Write(_text); tw.Close(); res.Close(); } else if (req.RawUrl.StartsWith("/PutUrl") == true) { Debug.WriteLine(string.Format("req {0}", req.RawUrl)); var text = req.RawUrl.Replace("/PutUrl/", ""); text = System.Uri.UnescapeDataString(text); textBox1.Text = text; var tw = new StreamWriter(res.OutputStream); tw.Write("OK"); tw.Close(); res.Close(); } else { var tw = new StreamWriter(res.OutputStream); tw.Write("ERROR"); tw.Close(); res.Close(); } } }); tsk.Start(); }
同じ8090ポートを使って、/GetUrl の場合はデスクトップからタブレットPCへ、/PutUrl の場合はタブレットPCからデスクトップへ通信をします。
まあ、先行きは XML シリアライズを使って実装しますが、ひとまずこれで使い勝手を確認。
■共有ターゲットの実装
ブラウザから「共有」の対象になるために、連携するストアアプリを共有ターゲットにします。
追加で「共有コントラクト ターゲット」を追加してから、以下の部分を修正。
□共有コントラクトを開いたとき
public async void Activate(ShareTargetActivatedEventArgs args) { this._shareOperation = args.ShareOperation; // ビュー モデルを使用して、共有されるコンテンツのメタデータを通信します var shareProperties = this._shareOperation.Data.Properties; var thumbnailImage = new BitmapImage(); this.DefaultViewModel["Title"] = shareProperties.Title; this.DefaultViewModel["Description"] = shareProperties.Description; this.DefaultViewModel["Image"] = thumbnailImage; this.DefaultViewModel["Sharing"] = false; this.DefaultViewModel["ShowImage"] = false; this.DefaultViewModel["Comment"] = String.Empty; this.DefaultViewModel["SupportsComment"] = true; Window.Current.Content = this; Window.Current.Activate(); // ブラウザからURLを共有する if (this._shareOperation.Data.Contains(StandardDataFormats.Uri)) { var uri = await this._shareOperation.Data.GetUriAsync(); this.DefaultViewModel["Comment"] = uri.ToString(); } // 共有されるコンテンツの縮小版イメージをバックグラウンドで更新します if (shareProperties.Thumbnail != null) { var stream = await shareProperties.Thumbnail.OpenReadAsync(); thumbnailImage.SetSource(stream); this.DefaultViewModel["ShowImage"] = true; } }
□共有コントラクトで Share をタップしたとき
private async void ShareButton_Click(object sender, RoutedEventArgs e) { this.DefaultViewModel["Sharing"] = true; this._shareOperation.ReportStarted(); // TODO: this._shareOperation.Data を使用して共有シナリオに適した // 作業を実行します。通常は、カスタム ユーザー インターフェイス要素を介して // このページに追加されたカスタム ユーザー インターフェイス要素を介して // this.DefaultViewModel["Comment"] if (this._shareOperation.Data.Contains(StandardDataFormats.Uri)) { // テキストデータを保存 var text = this.DefaultViewModel["Comment"] as string; string url = "http://mars:8090/PutUrl/" + System.Uri.EscapeUriString(text); HttpClient cl = new HttpClient(); var res = await cl.GetAsync(new Uri(url)); } this._shareOperation.ReportCompleted(); }
実は、Active がなくていきなり share してもいいんですが、まあ、テンプレートのままで使ってみます。
こうすることで、
- ブラウザで閲覧する。
- チャームで「共有」を開いて GoRTApp を選択する。
- URL を確認してデスクトップに URL を通知する。
- デスクトップアプリのほうで、URL をブラウザで開く。
という流れができます。
■サンプルソース
サンプルソースはこちらで。
仕組みはこんな感じ。