Windows Phoneによるタイル通知の送受信

2011年9月16日(金)
PROJECT KySS

このサンプルは、Microsoft のプッシュ通知サービスを使って、タイル通知を送受信するサンプルです。

このサンプルは3つのプログラムから構成されています。タイル通知チャネルを生成して通知イベントに接続するWindows Phone 7.1のプログラム、通知チャネルをサーバーに保存するASP.NETプログラム、通知チャネルを取得してタイルのUI情報を、Windows Phoneに送信するWPFプログラムの3つです。

このプログラムで実装する機能の動作を、下記に解説しておきます。

最初に、Windows Phoneのプログラムを実行します。チャネルURIが表示されますので、[OK]をクリックします。チャネルURIをサーバーに保存したメッセージが表示されます。この画面でエラーが表示されることもありますが、サーバーにはチャネルURIは保存されていますので、[OK]をクリックします。

「Start」アイコンをクリックし、→アイコンをクリックして、WP7_TileNotificationをホールドし、「スタート画面に追加」を選択します。すると、WP7_TileNotificationのタイルが表示されます(図1)。

図1:WP7_TileNotificationをホールドし、「スタート画面に追加」を選択すると、WP7_TileNotificationのタイルが表示される(右図2枚)(クリックで拡大)

この状態から次に、WPFのプログラムを起動します。実行すると、「画像の選択」、数値を入力する「Count」、背景に表示されるメッセージを入力する「BackContent」、タイトルを表示する「Title」を入力する画面が表示されます。一番先頭の画像を選択し、Countに2、BackContentに「今日は蒸し暑い。クーラー付けよう」、Titleに「今日の天気」と入力して[タイルに通知を送る]ボタンをクリックします(図2)。

図2:画像を選択し、入力欄にデータを入力した(クリックで拡大)

図2の状態から、[タイルに通知を送る]をクリックすると、Windows PhoneエミュレーターのWP7_TileNotificationのタイルが、設定したUIに置き換わります(図3)。

図3:エミュレーターのタイルが、WPF側で設定したUIに変わった(クリックで拡大)

サンプル一式は、会員限定特典としてダウンロードできます。記事末尾をご確認ください。
※サンプル実行でエラーが発生した場合は、「ソリューションのビルド」を実行後、再度、デバッグ開始を行ってください

画像をいろいろ選択して、入力ボックス内の値を変更してお試しください。ただ、3回目になると、タイルにUIが反映されるまでに、かなり時間を要します(原因は不明です)。決してハングアップではありませんので、そのまま待機しておくと復帰してUIが反映されます。

もうひとつのASP.NETのファイルはサーバーに配置し、チャネルURIを保存させるのに使用しています。

まず初めに、Windows Phone 7.1のプロジェクトを作成します。

プロジェクトの作成

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

ソリューションエクスプローラー内のWP71_TileNotificationの直下に、PNG画像を追加します。今回はImageフォルダ内には配置していません。また、追加したPNG画像を選択して、プロパティウィンドウから「ビルドアクション」に「コンテンツ」を指定してください。デフォルトでは「Resource」になっています。「Resource」ではタイルに画像が反映されませんので、必ず「コンテンツ」を指定します。

これらの画像ファイルは、ダウンロードされたサンプルファイルには追加済みです。

MainPage.xamlの編集

x:NameがPageTitleというTextBlockコントロールのTextプロパティに「Tile Notification」と指定します。書き出されるXAMLコードは省略します。

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

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

リスト1 (MainPage.xaml.vb)

Option Strict On
Imports Microsoft.Phone.Controls

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

Imports System.IO

ネットワークで使用されるプロトコルに対し、プログラミング インターフェースを提供するクラスの含まれる、System.Net名前空間をインポートします。
Imports System.Net

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

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

HttpNotificationChannelクラス型のmyPushChannel変数を宣言します。HttpNotificationChannelクラスは、Microsoftプッシュ通知サービスとプッシュ クライアント間の通知チャネルを作成し、また、生の通知のための新しいサブスクリプションを作成するクラスです。
KySS_TileChannelという文字列をmyChannelName変数に格納しておきます。
HttpNotificationChannel.Findメソッドで、先に作成しておいた通知チャネル(KySS_TileChannel)を検索して使用します
検索した通知チャネルがない場合は、KySS_TileChannelで初期化された新しいHttpNotificationChannelを生成します。
AddHandlerメソッドで、通知チャネルに関連付けられた URI を返す、ChannelUriUpdateイベントに、PushChannel_ChannelUriUpdatedイベントハンドラを追加します。
AddHandlerメソッドで、HttpNotificationChannelクラスを使用した時、何か予期しない動作が発生した場合に起きる、ErrorOccurredイベントに、PushChannel_ErrorOccurredイベントハンドラを追加します。
HttpNotificationChannelクラスのOpenメソッドで、Microsoftのプッシュ通知サービスを伴った、通知チャネルを開きます。
BindToShellTileメソッドで、HttpNotificationChannel クラスのインスタンスに、通知サブスクリプションを伴った、デフォルトのタイルをバインドします。
検索した通知チャネルがある場合は、AddHandlerメソッドで、通知チャネルに関連付けられた URI を返す、ChannelUriUpdateイベントに、PushChannel_ChannelUriUpdatedイベントハンドラを追加し、AddHandlerメソッドで、HttpNotificationChannelクラスを使用した時、何か予期しない動作が発生した場合に起きる、ErrorOccurredイベントに、PushChannel_ErrorOccurredイベントハンドラを追加します。
ChannelUriプロパティで、現在のアクティブな通知チャネルのURIを表示します。
現在のアクティブな通知チャネル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 = "KySS_TileChannel"
    myPushChannel = HttpNotificationChannel.Find(myChannelName)
    If myPushChannel Is Nothing = True Then
      myPushChannel = New HttpNotificationChannel(myChannelName)
      AddHandler myPushChannel.ChannelUriUpdated, AddressOf PushChannel_ChannelUriUpdated
      AddHandler myPushChannel.ErrorOccurred, AddressOf PushChannel_ErrorOccurred
      myPushChannel.Open()
      myPushChannel.BindToShellTile()
    Else
      AddHandler myPushChannel.ChannelUriUpdated, AddressOf PushChannel_ChannelUriUpdated
      AddHandler myPushChannel.ErrorOccurred, AddressOf PushChannel_ErrorOccurred
 
      MessageBox.Show(String.Format("チャネルのUriは={0}", myPushChannel.ChannelUri.ToString()))
      SendUriToServer(myPushChannel.ChannelUri.ToString())
    End If
  End Sub

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

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

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

エラーが発生した場合、エラーの内容を表示するには、Dispatcherが関連付けられているスレッドで、デリゲートを実行する必要があります。これには、非同期処理であるBeginInvokeメソッドを使用します。
  Private Sub PushChannel_ErrorOccurred(sender As Object, e As NotificationChannelErrorEventArgs)
    Dispatcher.BeginInvoke(Sub()
                              MessageBox.Show(String.Format("エラー= {0}.  {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イベントに、イベントハンドラを追加します。イベントハンドラ内では、アップロードした結果を表示します。
※サーバーに配置した、TileNotification_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/TileNotification_NET/Default.aspx", UriKind.Absolute), myChannelUri)
    End Sub
  End Class

次にアクティブなチャネルURIをサーバーに保存するASP.NETを作成します。

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

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