.NET Gadgeteerで温度計 - Push NotificationでWP7に通知
昨日(2/8)のUX-TVでお見せした、.NET Gadgeteerで計測した温度を、Push NotificationでWP7端末に通知する方法を解説します。
このポストを試す前に、https://blogs.msdn.com/b/hirosho/archive/2012/02/07/tipsfordotnetgadgeteerwiththermometerandlcd.aspx を予め読んでおいてください。
準備として、https://msdn.microsoft.com/ja-jp/library/ff431744(VS.92).aspx から、”トースト通知のサンプル”をダウンロードしておいてください。
前のポストで作成したプロジェクトに、Push Notificationを送信する機能を担当するクラスを追加します。
using System.Net;
class PushNotificationSender
{
public string PushChannel
{
get;
set;
}
public void Send(string text1, string text2)
{
HttpWebRequest request = HttpWebRequest.Create(PushChannel) as HttpWebRequest;
request.Method = "POST";
string toastMessage =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>" + text1 + "</wp:Text1>" +
"<wp:Text2>" + text2 + "</wp:Text2>" +
"<wp:Param>/PageVisit.xaml?NavigatedFrom=Toast Notification</wp:Param>" +
"</wp:Toast> " +
"</wp:Notification>";
byte[] msg = System.Text.Encoding.UTF8.GetBytes(toastMessage);
request.ContentLength = msg.Length;
request.ContentType = "text/xml";
request. Headers.Add("X-WindowsPhone-Target", "toast");
request.Headers.Add("X-NotificationClass", "2");
try
{
using (var stream = request.GetRequestStream())
{
stream.Write(msg, 0, msg.Length);
stream.Close();
}
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
}
}
.NETでHTTPによるネットワークプログラミングをやったことがある方なら皆さんご存知の、HttpWebRequestクラスが.NET Micro Frameworkにはほぼそのままの形で用意されています。個々に挙げたコードは、Windows Phone 7のトースト通知アプリのPush Notification送信側のコード(サンプルの中のSendToastプロジェクト)をほぼそのまま利用しています。このコードだけで、Push Notificationを送る仕組みは出来上がりです。
次に、このクラスを使って温度を通知するコードを紹介します。ここでは、タッチスクリーンLCDをタッチしたら、Push Notificationを送信するものとします。
Programクラスの、ProgramStarted()メソッドの中で、WPFサブセットAPIにより、UI構築するコードに、パネルをタッチした時に呼ばれるハンドラを登録します。
display.WPFWindow.Background = new SolidColorBrush(Color.Black);
StackPanel panel = new StackPanel(Orientation.Vertical);
display.WPFWindow.Child = panel;
degreeText = new Text();
degreeText.TextAlignment = TextAlignment.Center;
degreeText.ForeColor = Colors.Blue;
degreeText.Font = Resources.GetFont(Resources.FontResources.NinaB);
panel.Children.Add(degreeText);
panel.TouchDown += new Microsoft.SPOT.Input.TouchEventHandler(panel_TouchDown); ← ハンドラの登録
その付近で、PushNotificationSenderクラスのオブジェクトを一つ作成しておきます。
pushSender = new PushNotificationSender()
{
PushChannel = "https://sn1.notify.live.net/throttledthirdparty/01.00/AAGDJDCeI・・・・",
};
PushChannelに代入しているのは、Windows Phone側でトースト通知アプリを実行して出来上がったPush Notification チャネルです。トースト通知アプリのsdkToastNotificationCSプロジェクトをWP7のEmulator、もしくは、実機でデバッグ実行します。MainPage.xaml.csの35行目からのコードのpushChannelの値が確定する部分(38行目にブレークを張ってステップ実行)でURLの値をコピーし、上の文字列にペーストします。
35 // Try to find the push channel.
36 pushChannel = HttpNotificationChannel.Find(channelName);
37
38 // If the channel was not found, then create a new connection to the push service.
39 if (pushChannel == null)
40 {
41 pushChannel = new HttpNotificationChannel(channelName);
そして、ハンドラーコード本体は、
private PushNotificationSender pushSender;
void panel_TouchDown(object sender, Microsoft.SPOT.Input.TouchEventArgs e)
{
pushSender.Send("Gadgeteer Thermometer", degreeText.TextContent);
}
と、下に示しているtimer_Tick(1秒毎にコールされる)でTextに格納している文字列を、Push Notificationで送信するわけです。
void timer_Tick(GT.Timer timer)
{
double degree = thermoIn.ReadVoltage();
degree = degree * 78.0 / 3.3 - 22.0;
Debug.Print("Degree : " + degree);
degreeText.TextContent = degree.ToString();
}
実サービスを考えた場合、Push Notificationのチャネルの受け渡しは、例えば、Windows Azure上に温度データ通知サービスを配置するなどして、Windows Phone 7からChannel URLを予め登録し、Azure上のサービスから.NET Gadgeteerに配信もしくは取りに行くなどすれば、スタイリッシュでしょう。