Windows PhoneによるToastとRaw通知の送受信

2011年9月26日(月)
PROJECT KySS

プロジェクトの作成

VS 2010のメニューから[ファイル(F)/新規作成(N)/プロジェクト(P)]を選択します。次に、「Windows Phone アプリケーション」を選択して、「名前(N)」に任意のプロジェクト名を指定します。ここでは「WP71_RawNotification」という名前を付けています。Windows Phoneのバージョンは7.1を選択します。

MainPage.xamlの編集

x:NameがPageTitleというTextBlockコントロールのTextプロパティに「Raw Notification」と指定します。

書き出されるXAMLコードは省略します。

ソリューションエクスプローラー内のMainPage.xamlを展開し、MainPage.xaml.vbをダブルクリックして、リスト3のコードを記述します。このリスト3のコードは「第5回:Windows Phoneによるタイル通知の送受信」や、今回のToast Notificationとほとんど同じです。コードが異なる箇所のみ掲載し、解説します。そのほかについては第5回を参考にしてください。

日本語表示設定

「Windows PhoneによるToast通知の送受信」を参照してください。

リスト3 (MainPage.xaml)

~コード略~
Partial Public Class MainPage
  Inherits PhoneApplicationPage

~コード略~

ページが読み込まれた時の処理

AddHandlerメソッドで、生の通知を受信した時に発生するイベントである、HttpNotificationReceivedイベントに、PushChannel_HttpNotificationReceivedイベントハンドラを追加します。
  Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    ~コード略~
      If myPushChannel Is Nothing = True Then
     ~コード略~  
        AddHandler myPushChannel.HttpNotificationReceived, AddressOf PushChannel_HttpNotificationReceived
        myPushChannel.Open()
      Else
        ~コード略~
        AddHandler myPushChannel.HttpNotificationReceived, AddressOf PushChannel_HttpNotificationReceived
        ~コード略~
    End If
  End Sub

通知チャネルに関連付けられた URI を返すイベント

  Private Sub PushChannel_ChannelUriUpdated(sender As Object, e As NotificationChannelUriEventArgs)
    ~コード略~
  End Sub

何か予期しない動作が発生した場合に起きるイベント

  Private Sub PushChannel_ErrorOccurred(sender As Object, e As NotificationChannelErrorEventArgs)
    ~コード略~
  End Sub

生の通知を受信した時に発生するイベント

通知データ本体で初期化された、StreamReaderのインスタンスである、myReaderオブジェクトを生成します。
ReadToEndメソッドで通知データの内容を読み取り、文字列型変数myMessageに格納しておきます。StreamReaderをCloseメソッドで閉じます。
取得した内容(myMessage変数の値)を、現在の時刻(DateTime.Now.ToShortTimeString)と一緒に表示します。{1}にはvbCrLfの改行が入ります。取得した内容をMessageBox.Showで表示するには、Dispatcherが関連付けられているスレッドで、デリゲートを実行する必要があります。これには、非同期処理であるBeginInvokeメソッドを使用します。
  Private Sub PushChannel_HttpNotificationReceived(sender As Object, e As HttpNotificationEventArgs)
    Dim myMessage As String = String.Empty
 
    Dim myReader As StreamReader = New StreamReader(e.Notification.Body)
    myMessage = myReader.ReadToEnd
    myReader.Close()
    Dispatcher.BeginInvoke(Sub()
                              MessageBox.Show(String.Format("通知受信{0}{1}{2}", DateTime.Now.ToShortTimeString, vbCrLf, myMessage))
                           End Sub)
  End Sub

アクティブなチャネルURIをサーバーに送る処理(引数としてアクティブなチャネルURIを指定)

  Private Sub SendUriToServer(myChannelUri As String)
        ~コード略~
  End Sub
End Class

通知チャネルを取得して生情報を送信するWPFプログラム

VS2010メニューから「ファイル(F)/新規作成(N)/プロジェクト(P) 」と選択し、「インストールされたテンプレート」から、「Windows」を選択します。右に表示されるパネルから「WPFアプリケーション」を選択します。「名前(N)」に「WPF_RawNotification」と指定し、[OK]ボタンをクリックします。

コントロールのレイアウト

まず、Windowのプロパティから[レイアウト]パネルにあるWidthに562、Heightに223と指定します。この値は読者が自由に設定してください。

次に、ツールボックスからMainWindow.xamlのデザイン画面上に、TextBlockを2個、TextBoxを2個、Buttonを1個配置します。各コントロールの配置とNameは図6を参照してください。

図6:各コントロールを配置した(クリックで拡大)

書き出されるXAMLコードは省略します。

ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックして、リスト4のコードを記述します。

ロジックコードを記述する

リスト4  (MainWindow.xaml.vb)

Option Strict On
Imports System.Net
Imports System.IO
Imports System.Text

Class MainWindow
  getUriというメンバ変数を宣言します。
  Dim getUri As String = String.Empty

メインウィンドウが読み込まれた時の処理

新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。WebClientクラスは、データの送受信用のメソッドを提供するクラスです。
String またはUriとして指定したリソースをダウンロードする、DownloadStringAsyncメソッドで、サーバー上のchannelUri.txtをダウンロードします。第5回で、サーバーにアップしているTileNotification_NETのDefault.aspxで保存されたチャネルURIを取得します。
AddHandlerメソッドで、非同期のリソース ダウンロード操作の完了時に発生する、DwonloadStringCompletedイベントに、イベントハンドラを追加します。メンバ変数getUriにダウンロードした結果を格納します。チャネルURIが格納されます。
サーバー上に配置した、TileNotification_NETのASP.NETファイルへのアクセス許可や、IISの設定は各自が行ってください。
  Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    Dim myWebClient As New WebClient
 
    AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
                    If resultArgs.Error Is Nothing = False Then
                           MessageBox.Show("Channelファイルが見つかりません")
                           Exit Sub
                    Else
                           getUri = resultArgs.Result
                    End If
          End Sub
    myWebClient.DownloadStringAsync(New Uri("サーバーのURI/TileNotification_NET/SaveData/channelUri.txt", UriKind.Absolute))
  End Sub

[生データを送る]ボタンがクリックされた時の処理

HttpWebRequestクラス型のmyWebRequestオブジェクト変数を宣言し、WebRequest.Createメソッドで、指定したURI(getUri) で新しいWebRequest のインスタンスを初期化し、DirectCastで、HttpWebRequestクラスにキャストします。HttpWebRequestクラスは、URIへの要求を行うWebRequestクラスの 、HTTP 固有の実装を提供するクラスです。
HttpWebRequestクラスのMethodプロパティに「POST」を指定します。
変数value1にvalueTextBox1の値を、value2変数にvalueTextBox2の値を格納します。
Visual Basicの埋め込み式を用いて、XML 要素リテラルでrawXmlData要素を作成しています。埋め込み式の構文は<%= expression %>で、ASP.NET で使用される構文と同じです。
<Value1>要素の値には、value1変数の値を埋め込みます。<Value2>要素の値には、value2変数の値を埋め込みます。
XElement.ParseメソッドでrawXmlDataの内容を文字列として読み込みます。
送信する通知のデータ本体を設定します。読み込んだXMLデータを、Encoding.UTF8.GetBytesメソッドでUTF8のバイトシーケンスにエンコードし、Byte型のmyNotificationMessage変数に格納します。
HttpRequestクラスのContentlengthにUTF8のバイトシーケンスにエンコードしたバイト数を指定します。ContentTypeにはtext/xml、HeadersにはAddメソッドで、「"X-NotificationClass", "3"」を追加します。X-NotificationClassヘッダには、いつデバイスに通知するかを設定できます。Tile通知の場合は”1”、Toast通知の場合は”2”、Raw通知の場合は”3”を指定します。
要求データを書き込むために使用する Stream オブジェクトmyStreamを宣言します。 StreamクラスのWriteメソッドでByte型のmyNotificationMessageを書き込みます。Writeメソッドの書式は下記の通りです。

Write(バイト配列,バイトのコピーを開始する位置でインデックスは0から,書き込むバイト数)

Closeメソッドで、Streamを閉じます。これでWindows PhoneにRaw通知がなされます。
  Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
    Dim myWebRequest As HttpWebRequest = DirectCast(WebRequest.Create(getUri), HttpWebRequest)
    myWebRequest.Method = "POST"
    Dim value1 As String = valueTextBox1.Text
    Dim value2 As String = valueTextBox2.Text
    Dim rawXmlData As XDocument = <?xml version="1.0" encoding="utf-8"?>
                              <root>
                                     <Value1><%= value1 %></Value1>
                                     <Value2><%= value2 %></Value2>
                              </root>
    Dim roadRawData As XElement = XElement.Parse(rawXmlData.ToString)
 
    Dim myNotificationMessage As Byte() = Encoding.UTF8.GetBytes(roadRawData.ToString)
 
    With myWebRequest
      .ContentLength = myNotificationMessage.Length
      .ContentType = "text/xml"
      .Headers.Add("X-NotificationClass", "3")
    End With
 
    Dim myStream As Stream = myWebRequest.GetRequestStream()
    myStream.Write(myNotificationMessage, 0, myNotificationMessage.Length)
    myStream.Close()
  End Sub
End Class

図7:Toast Notificationを実機で動かした(クリックで拡大)

図8:Raw Notificationを実機で動かした(クリックで拡大)
  • 「Windows PhoneによるToastとRaw通知の送受信」サンプルプログラム_1

  • 「Windows PhoneによるToastとRaw通知の送受信」サンプルプログラム_2

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています