[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 をブラウザで開く。
という流れができます。
■サンプルソース
サンプルソースはこちらで。
仕組みはこんな感じ。


