[WinRT] デスクトップで閲覧しているURLをSurface RTに送る – Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/4718
の逆向きパターンで、タブレットPCからデスクトップのほうにURLを送ります。
こっちのほうは、比較的簡単?で、タブレットPCで動作しているブラウザ(IE10)から共有を使って、ストアアプリに送信、そのストアアプリからデスクトップアプリに通信させます。簡易HTTPサーバーを立てるところは、前回と同じなので流用してます。というか同じアプリに乗せています。
■簡易HTTPサーバー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /// /// フォームロード時 /// /// /// 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 シリアライズを使って実装しますが、ひとまずこれで使い勝手を確認。
■共有ターゲットの実装
ブラウザから「共有」の対象になるために、連携するストアアプリを共有ターゲットにします。
追加で「共有コントラクト ターゲット」を追加してから、以下の部分を修正。
□共有コントラクトを開いたとき
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 をタップしたとき
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 をブラウザで開く。
という流れができます。
■サンプルソース
サンプルソースはこちらで。
仕組みはこんな感じ。