PR

Windows Phoneによるメッセージの受信

2011年11月4日(金)
PROJECT KySS

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

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

リスト2 (MainPage.xaml.vb)

Option Strict On
Microsoft のプッシュ通知サービスから、通知を受信するためのクラスの含まれる、Microsoft.Phone.Notification名前空間をインポートします。
Imports Microsoft.Phone.Notification

Imports System.Text
Imports System.Xml.Linq

messageInfoクラス内に「送信日時」、「内容」のプロパティを定義しておきます。
Public Class messageInfo
  Property 送信日時 As String
  Property 内容 As String
End Class

Partial Public Class MainPage
  Inherits PhoneApplicationPage
  
  ' Constructor
  Public Sub New()
    InitializeComponent()
  End Sub

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

HttpNotificationChannelクラス型のmyPushChannel変数を宣言します。HttpNotificationChannelクラスは、Microsoftプッシュ通知サービスとプッシュ クライアント間の通知チャネルを作成し、また、生の通知のための新しいサブスクリプションを作成するクラスです。
KySSToastSampleChannelという文字列をmyChannelName変数に格納しておきます。
HttpNotificationChannel.Findメソッドで、先に作成しておいた通知チャネル(KySSToastSampleChannel)を検索して使用します
検索した通知チャネルがない場合は、KySSToastSampleChannelで初期化された新しいHttpNotificationChannelを生成します。
AddHandlerステートメントで、通知チャネルに関連付けられた URI を返す、ChannelUriUpdateイベントに、PushChannel_ChannelUriUpdatedイベントハンドラを追加します。
AddHandlerステートメントで、HttpNotificationChannelクラスを使用した時、何か予期しない動作が発生した場合に起きる、ErrorOccurredイベントに、PushChannel_ErrorOccurredイベントハンドラを追加します。
HttpNotificationChannelクラスのOpenメソッドで、Microsoftのプッシュ通知サービスを伴った、通知チャネルを開きます。
BindToShellToastメソッドで、HttpNotificationChannel クラスのインスタンスに、トースト通知サブスクリプションをバインドします。
検索した通知チャネルがある場合は、AddHandlerステートメントで、通知チャネルに関連付けられた URI を返す、ChannelUriUpdateイベントに、PushChannel_ChannelUriUpdatedイベントハンドラを追加し、AddHandlerステートメントで、HttpNotificationChannelクラスを使用した時、何か予期しない動作が発生した場合に起きる、ErrorOccurredイベントに、PushChannel_ErrorOccurredイベントハンドラを追加します。
現在のアクティブな通知チャネルURIを引数にSendUriToServerプロシージャを実行します。
  Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim myPushChannel As HttpNotificationChannel
    Dim myChannelName As String = "KySSToastSampleChannel"
    myPushChannel = HttpNotificationChannel.Find(myChannelName)
 
    If myPushChannel Is Nothing = True Then
      myPushChannel = New HttpNotificationChannel(myChannelName)
      AddHandler myPushChannel.ChannelUriUpdated, AddressOf myPushChannel_ChanelUriUpdated
      AddHandler myPushChannel.ErrorOccurred, AddressOf myPushChannel_ErrorOccured
      myPushChannel.Open()
      myPushChannel.BindToShellToast()
    Else
      AddHandler myPushChannel.ChannelUriUpdated, AddressOf myPushChannel_ChanelUriUpdated
      AddHandler myPushChannel.ErrorOccurred, AddressOf myPushChannel_ErrorOccured
      SendUriToServer(myPushChannel.ChannelUri.ToString())
    End If
  End Sub

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

現在のアクティブな通知チャネルのURIを表示したり、アクティブなURIを引数にSendUriToServerプロシージャを実行したりするには、Dispatcherが関連付けられているスレッドで、デリゲートを実行する必要があります。これには、非同期処理であるBeginInvokeメソッドを使用します。
  Private Sub myPushChannel_ChanelUriUpdated(sender As Object, e As NotificationChannelUriEventArgs)
    Dispatcher.BeginInvoke(Sub()
                              SendUriToServer(e.ChannelUri.ToString())
                           End Sub)
  End Sub

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

エラーが発生した場合、エラーの内容を表示するには、Dispatcherが関連付けられているスレッドで、デリゲートを実行する必要があります。これには、非同期処理であるBeginInvokeメソッドを使用します。
  Private Sub myPushChannel_ErrorOccured(sender As Object, e As NotificationChannelErrorEventArgs)
    Dispatcher.BeginInvoke(Sub()
                              MessageBox.Show(String.Format("Push Notification {0} Errorが発生。{1}{2}{3}", e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData))
                           End Sub)
  End Sub

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

新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。WebClientクラスは、データの送受信用のメソッドを提供するクラスです。EncodingプロパティにUTF8を指定し、HeadersのContent-Typeに「application/x-www-form-urlencoded」と指定します。
UploadStringAsyncメソッドで、アクティブなチャネルURI(myChannelUri)をサーバーにアップロードし、サーバー上のDefault.aspxを実行します。アップするサーバーのURIは各自のURIに変更してください。UploadStringAsyncメソッドは、指定したリソースに指定した文字列(この場合、アクティブなチャネルURI)をアップロードします。
AddHanderステートメントで、非同期の文字列アップロード操作の完了時に発生する、UploadStringCompletedイベントに、イベントハンドラを追加します。イベントハンドラ内では、アップロードした結果を表示します。
※サーバーに配置した、ChannelUri_NETのASP.NETファイルのアクセス許可やIISの設定等については、各自が行ってください。
  Private Sub SendUriToServer(myChannelUri As String)
    Dim myWebClient As New WebClient
    With myWebClient
      .Encoding = System.Text.Encoding.UTF8
      .Headers("content-type") = "application/x-www-form-urlencoded"
    End With
 
    AddHandler myWebClient.UploadStringCompleted, Sub(resultSender As Object, resultArgs As UploadStringCompletedEventArgs)
                                                  MessageBox.Show(resultArgs.Result)
                                                End Sub
    myWebClient.UploadStringAsync(New Uri("サーバーのURI/ChannelUri_NET/Default.aspx", UriKind.Absolute), myChannelUri)
  End Sub

[メッセージの更新]ボタンがクリックされた時の処理

新しいWebClientのインスタンスmyWebClientオブジェクトを生成します。WebClientクラスは、データの送受信用のメソッドを提供するクラスです。
DownloadStringAsyncメソッドで、サーバー上のmessageInfo.xmlをダウンロードします。ダウンロードするサーバーのURIは各自のURIに変更してください。DownloadStringAsyncメソッドは、String または Uri として指定したリソース(この場合messageInfo.xml)をダウンロードします。常に新しいファイルをダウンロードできるよう引数に現在の時間、分、秒を持たせています。
AddHandlerステートメントで、リソースを文字列としてダウンロードする非同期操作が完了するたびに発生する、DownLoadStringAsyncメソッドに、イベントハンドラを追加します。イベントハンドラ内では以下の処理を実行します。
エラーが発生した場合は警告メッセージを表示します。
ダウンロードした結果をXElement.Parseメソッドで文字列として読み込みます。messageInfoクラス型の新しいリストであるmyMessageInfoを作成します。
Descendants メソッドで、子孫要素である全ての <情報> 要素のコレクションに対して、各要素を変数 result に格納しながら、messageInfo クラスの「送信日時」に<送信日時>要素の値を、「内容」に<内容>要素の値を指定し、myMessageInfoオブジェクトに追加していきます。ListBoxのItemsSourceプロパティにmyMessageInfoオブジェクトを指定します。これで、ListBoxにmessageInfo.xmlに保存されているデータが表示されます。
  Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
    Dim myWebClient As New WebClient
    AddHandler myWebClient.DownloadStringCompleted, Sub(resultSender As Object, resultArgs As DownloadStringCompletedEventArgs)
                       If resultArgs.Error Is Nothing = False Then
                                     MessageBox.Show("XMLファイルが見つかりません")
                                     Exit Sub
                       Else
                             Dim myDoc As XElement = XElement.Parse(resultArgs.Result)
                             Dim myMessageInfo As New List(Of messageInfo)
                             For Each result In From c In myDoc.Descendants("情報") Select c
                                 With myMessageInfo
                                   .Add(New messageInfo With {.送信日時 = result.Element("送信日時").Value,
                                                              .内容 = result.Element("内容").Value})
                                   End With
                                 Next
                                   ListBox1.ItemsSource = myMessageInfo
                             End If
                       End Sub
    myWebClient.DownloadStringAsync(New Uri(String.Format("サーバーのURI/Message_NET/SaveData/messageInfo.xml?myTime={0}", DateTime.Now.ToLongTimeString), UriKind.Absolute))
  End Sub
End Class

通知チャネルを取得してトースト情報を送信し、メッセージをサーバーに保存するWPFプログラム

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

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

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

次に、ツールボックスからMainWindow.xamlのデザイン画面上に、TextBoxを1個、Buttonを2個配置します。要素のTitleプロパティに「メッセージ入力」と指定します。

要素のBackground(背景色)に緑系統色を指定します。TextBlockのAcceptReturnプロパティにチェックを入れて、TextBoxコントロール内でEnter キーを押すと、改行できるようにしておきます。長文が入力された時のために、VerticalScrollBarVisibilityにVisibleを指定して、垂直スクロールバーが表示されるようにします。ButtonのContentプロパティに[OK]と[送信]と指定します。[送信]ボタンは、初期状態では、IsEnabledのチェックを外し、クリック不可としておきます(図6)。

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

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

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

  • 「Windows Phoneによるメッセージの受信」サンプルプログラム

四国の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メルマガ会員のサービス内容を見る

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