近くにある病院の場所をキャラクターが音声で教えてくれるアプリを作る

次に、ソリューション・エクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト2 (MainWindow.xaml.vb)
Option Strict On ‘ コンピュータの地理的位置にアクセスできるようにするクラスの含まれる、Windows.Devices.Geolocation名前空間を ‘ インポートします。 Imports Windows.Devices.Geolocation ‘ Bing Mapsに関するクラスの含まれる、Bing.Maps名前空間をインポートします。 Imports Bing.Maps Imports Windows.UI ‘ アプリケーションウィンドウやウィンドウ対話を作成し管理するサポートと、ウィンドウ上の入力イベントを処理する ‘ クラスの含まれる、Windows.UI.Core名前空間をインポートします。 Imports Windows.UI.Core ‘ 最新のHTTPアプリケーション用のプログラミング インターフェイスを提供するクラスの含まれる、 ‘ System.Net.Http名前空間をインポートします。 Imports System.Net.Http Imports Windows.UI.Popups ‘ HospitalInfoクラス内に文字列型の「病院名」、「住所」プロパティを定義しておきます。 Public Class HospitalInfo Public Property 病院名 As String Public Property 住所 As String End Class Public NotInheritable Class MainPage Inherits Page ‘ 現在の地理的位置にアクセスするクラスである、Geolocatorクラスのメンバー変数myGeolocatorを宣言します。 Private myGeolocator As Geolocator ‘ Windowsランタイムコアイベントメッセージディスパッチャを提供するクラスである、 ‘ CoreDispatcherクラスのメンバー変数、myCoreDispacherを宣言します。 Private myCoreDispacher As CoreDispatcher ‘ YahooのアプリケーションIDで初期化された、メンバー定数変数AppIDを宣言します。 Const AppID As String = " YahooのアプリケーションID" ‘ GoogleのAPI Keyで初期化された、メンバー定数変数GoogleAppIDを宣言します。 Const GoogleAppID As String = " GoogleのAPI Key" Private flag As Boolean = False Private myCoodinatePosition As String = String.Empty Private myAddressCoodinatePosition As String = String.Empty Private myUri As String = String.Empty Private myAddressLatitude As String Private myAddressLongitude As String Private myAddressUri As String ‘ MediaElementクラス型のメンバー変数myMediaを宣言します。 Private myMedia As MediaElement
ページがアクティブになった時の処理
場所にアクセスし、場所が変更された時や、Geolocatorの機能が変更された時に発生する各イベントで、イベントハンドラを実行するDataShowメソッドを実行します。
Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
DataShow()
End Sub
場所にアクセスし、場所が変更された時や、Geolocatorの機能が変更された時に発生する各イベントで、イベントハンドラを実行する処理。
myGeolocatorオブジェクトが作成されていない場合は、新しいGeolocatorクラスのインスタンスmyGeolocatorオブジェクトを作成します。
場所認識の精度レベルを表す、DesiredAccuracy プロパティにはDefaultを指定しておきます。
Default以外にHighがありますが、パフォーマンスが低下する恐れがありますので、Defaultを指定しています。
Window.Current.CoreWindow.Dispatcherで、現在アクティブになっている、ウィンドウの内部コアオブジェクトのイベントディスパッチャを取得して、myCoreDispacherで参照します。
AddHandlerステートメントで、場所が更新された時のPositionChangedイベント時のイベントハンドラ、myGeolocator_PositionChangedを追加します。
同じく、AddHandlerステートメントで、更新された場所を提供するGeolocatorの機能が変更された時に発生する、StatusChanged時のイベントハンドラ、myGeolocator_StatusChangedを追加します。
Private Sub DataShow()
If myGeolocator Is Nothing = True Then
myGeolocator = New Geolocator
myGeolocator.DesiredAccuracy = PositionAccuracy.Default
myCoreDispacher = Window.Current.CoreWindow.Dispatcher
End If
AddHandler myGeolocator.PositionChanged, AddressOf myGeolocator_PositionChanged
AddHandler myGeolocator.StatusChanged, AddressOf myGeolocator_StatusChanged
End Sub
場所が変更された時の処理
myCoreDispacher.RunAsyncメソッドで、イベントディスパッチャを実行し、ディスパッチされたイベントの結果を非同期に返します。ディスパッチャの優先順位は標準のNormalを指定しています。
緯度と経度のデータや都市の住所データを含めることができるGeoPositionクラス型の変数posを宣言し、PositionChangedイベントに関連付けられた場所データを取得します。
Clearメソッドで、地図内を一度クリアしておきます。
新しいPushpinクラスのインスタンスmyPinオブジェクトを作成します。ピンの背景色を「Crimson」に指定します。
新しいLocationクラスのインスタンスmyLocationオブジェクトを作成します。Locationクラスは、地図上の場所の標高と座標値を含むクラスです。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがTrueであった場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。その場合は、Locationを、メンバー変数myAddressLatitudeに格納された緯度の値と、myAddressLongitudeに格納された経度の値で初期化します。
それ以外の場合は、現在位置の緯度(pos.Coordinate.Point.Position.Latitude)と経度(pos.Coordinate.Point.Position.Longitude)で初期化します。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内にピンの位置を設定します。
myMapにAddメソッドでピンを追加します。
SetViewメソッドで、指定された中心部に位置、ズーム レベル、方位、およびピッチにマップビューを設定します。この場合myLocationの位置に16レベルでズームインします。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがTrueであった場合、つまり、現在位置の緯度(pos.Coordinate.Point.Position.Latitude)と経度(pos.Coordinate.Point.Position.Longitude)が取得されている場合の処理です。
メンバー変数myAddressUriに「Yahoo!ローカルサーチAPI」のアドレスを格納します。
引数latにpos.Coordinate.Point.Position.Latitudeの緯度の値を指定して、lonにpos.Coordinate.Point.Position.Longitudeの経度の値を指定します。
AppidにはYahooのアプリケーションIDを指定します。
そうでない場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。その場合は、Locationを、メンバー変数myAddressLatitudeに格納された緯度の値と、myAddressLongitudeに格納された経度の値で初期化します。
新しいHttpClientクラスのインスタンスmyAddressHttpClientオブジェクトを作成します。
HttpClientクラスは、URIで識別されるリソースにHTTP要求を送信し、そのリソースからHTTP応答を受信するための基本クラスが含まれています。
XML要素を表すXElementクラス型変数、xmldocを宣言します。
GetStringAsyncメソッドでmyAddressUriの結果を文字列として返し、変数myCurrentAddressに格納します。
GetStringAsyncメソッドは、指定URIにGET要求を送信し、非同期操作で応答本体を文字列として返すメソッドです。
返される文字列はXML形式になっています。このXMLのルート要素には、名前空間や不要な属性が定義されていて、内容を取得する際の邪魔(-_-;)になりますので、Replace関数で、ルート要素(
XElement.Parseメソッドで置換された結果のXMLが格納されている、myCurrentAddressを文字列として読み込みます。
読み込んだXMLから
要素の内容を取得して、変数myAddressに格納しておきます。新しいStackPanelのインスタンスmyAddressStackPanelオブジェクトを作成します。
Marginプロパティに「5」を指定して余白を設けます。
背景色を「Navy」に指定します。
このStackPanelオブジェクトのインスタンスを、非表示としておきます。
新しいTextBlockのインスタンスmyAddressTextBlockオブジェクトを作成します。文字色を「Red」に指定します。
文字サイズに「24」を指定し、パディングに「5」を指定します。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがFalse であった場合は(つまり通常の処理をしていた場合)、myAddressTextBlockに変数myAddressと文字列「辺り」を連結して表示します。それ以外の場合は、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。その場合は、WatermarkTextBoxに入力された値と文字列「辺り」を連結して表示します。
myStackPanelオブジェクトにAddメソッドで住所の設定された、myAddressTextBlockを追加します。
SetValueメソッドでmyAddressStackPanelのZIndexPropertyに20を指定します。myAddressStackPanelが前面に表示されます。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがFalseであった場合、つまり通常の処理を行っていた場合は、MapLayerクラスのSetPositionメソッドで、マップレイヤー内にmyAddressStackPanelオブジェクトの位置を設定し、Locationを現在位置の緯度と経度で初期化して指定します。それ以外の場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。MapLayerクラスのSetPositionメソッドで、マップレイヤー内にmyAddressStackPanelオブジェクトの位置を設定し、Locationをメンバー変数myAddressLatitudeが格納している緯度とmyAddressLongitudeが格納している経度で初期化して設定します。
MapLayerクラスは、地図上の要素の位置を保持しているマップレイヤーを表すクラスです。
myMapにAddメソッドでmyAddressStackPanelオブジェクトを追加します。
myAddressStackPanelは最初の状態では非表示になっているのでわかりませんが、ピンの位置にStackPanelオブジェクトが表示されることになります。
AddHandlerステートメントでピンをタップした時のイベントハンドラを追加します。
イベントハンドラ内では、myAddressStackPanelオブジェクトを表示状態にします。
AddHandlerステートメントでmyAddressStackPanelをタップした時のイベントハンドラを追加します。イベントハンドラ内では、myAddressStackPanelオブジェクトを非表示状態にします。
ブール型のメンバー変数flagの値で条件分岐を行います。FlagがTrueであった場合、つまり、マウスを右クリックして表示される住所を入力するボックスに住所を入力して、「OK」ボタンがクリックされた場合、ということです。
病院の情報を取得するGoogleのWeb APIのURLを設定します。
「location」には緯度と経度をカンマで区切って格納している、メンバー数myAddressCoodinatePositionの値を指定します。
「radius」には範囲(メートル単位)を指定します。ここでは1000を指定して1Kmとしています。
「types」には、何を目的に検索するかを指定します。ここでは「Hospital」を指定しています。
この「types」には|(パイプ)で区切って複数の値を指定できます。指定できる値の一覧は下記のURLを参照してください。
> https://developers.google.com/places/documentation/supported_types
「Sensor」には場所の要求が位置センサー(GPS など)を使用してデバイスから来たかどうかを示す値を、trueまたはfalseで指定します。ここでは「true」を指定しています。
「language」には「ja」を「key」にはGoogleより取得した「APIKey」を指定します。
「OK」ボタンがクリックされていない場合は、locationに現在位置の緯度と経度をカンマで区切った値を格納している、メンバー変数myCoodinatePositionの値を指定します。
検索結果は最大で20件までの情報を取得して表示します。これらの式を変数myUriに格納しておきます。TitleTextBlockにWatermarkTextBlockに入力された値、または現在位置の住所を格納しているmyAddress変数の値と、文字列「辺り」を連結して表示します。
新しいHttpClientのインスタンスmyHttpClientを作成します。
GetStringAsyncメソッドでGoogleの Web APIの式を格納しているmyUriの内容を読み取り、返ってくるXMLを変数resultHospitalに格納します。
XElement.ParseメソッドでresultHospitalが格納しているXMLの内容を、文字列として読み込みます。
HospitalInfoクラス型である新しいリストのインスタンスmyHospitalInfoオブジェクトを作成します。
Descendantsメソッドで、全ての
変数noの値を1ずつ増加させます。この値は、これから作成する「Webで表示」ボタンの、どのボタンがクリックされたかの判定に使用します。
新しいImageのインスタンスmyImageオブジェクトを作成します。Widthに「70」、Heightに「137」と指定し、Sourceプロパティにソリューション・エクスプローラー内のImagesフォルダ内にある「syoko1.png」を指定します。
新しいStackPanelのインスタンスsyokoStackPanelオブジェクトを作成します。背景色に「DarkGreen」を指定し、AddメソッドでmyImageオブジェクトを追加します。
新しいPushPinクラスのインスタンスhospitalPinオブジェクトを作成します。
背景色に「Crimson」を指定し、Textプロパティに1ずつ増加する変数noの値を指定します。
ピンの表面に連番が表示されます。
地理的位置に関連付けされた緯度と経度で初期化された、新しいLocationクラスのインスタンスhospitalLocationオブジェクトを作成します。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内に病院のピンの位置を設定します。myMapにAddメソッドで病院の位置にピンを追加します。
新しいStackPanelのインスタンスresultStackPanelオブジェクトを作成し、Orientationに「Horizontal」と指定しておきます。
新しいStackPanelのインスタンスmyStackPanelオブジェクトを作成します。
Marginに「5」、背景色に「Navy」を指定し、非表示としておきます。
新しいTextBlockのインスタンスmyNameTextBlockを作成します。
文字色は「Red」、Widthに「400」、文字の回り込みは可、文字サイズは「24」、パディングは「5」と指定します。
Textプロパティには、文字列「病院名」と
新しいTextBlockのインスタンスaddressTextBlockを作成します。
文字色は「Beige」、Widthに「400」、文字の回り込みは可、文字サイズは「20」、パディングは「5」と指定します。
Textプロパティには、文字列「住所」と
HositalInfoクラスの「病院」プロパティに連番と、
新しいButtonのインスタンスmyButtonを作成します。
Contentプロパティに「Webで表示」と指定します。
Tagプロパティに変数noの値を指定します。どのButtonがクリックされたかの判定に使用します。
キャラクタに読み上げさせる文章の内容をメンバー変数readingAddressに格納しておきます。
SetValueメソッドで、myStackPanelのZIndexPropertyに変数noの値を指定します。myStackPanelがPushPinよりも前面に表示されるようになります。
myStackPanelオブジェクトにAddメソッドで、myNameTextBlock、addressTextBlock、myButtonを追加します。
resultStackPanelオブジェクトに、AddメソッドでmyStackPanelオブジェクト、syokoStackPanelオブジェクトを追加します。
resultStackPanelオブジェクトは非表示としておきます。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内にresultStackPanelの位置を設定します。
myMapにAddメソッドでresultStackPanelを追加します。
AddHandlerステートメントで、病院の位置を表すピンがタップされた時のイベントハンドラを追加します。イベントハンドラ内では以下の処理を行います。
resultStackPanelオブジェクトが表示状態になり、病院の情報とキャラクタが表示されます。
メンバー変数myMediaを、MediaElement1で初期化しておきます。
音声機能へのアクセスを提供する、新しいSpeechSynthesizerのインスタンス、synthオブジェクトを作成します。
SynthesizeTextToStreamAsyncメソッドで、指定した文字列から、音声出力を非同期に生成します。
SetSourceメソッドで、指定されたストリームおよびMIME型を使用してSourceプロパティを設定します。Playメソッドで音声を再生します。
音声にどんな言語で、どのような声で喋らすかは、SpeechSynthesizerのVoiceプロパティで参照できます。下記のURLを参照してください。
> http://msdn.microsoft.com/en-us/library/windows.media.speechsynthesis.speechsynthesizer.voice.aspx
上記URLを見るとJapanese JA は性別が「Female」で、名前は「Haruka」という女性が読み上げるようです。
非同期処理で行われるため、イベントハンドラの先頭にAsyncを追加します。
AddHandlerステートメントで、病院の情報を表示した、resultStackPanelがタップされた時のイベントハンドラを追加します。
音声の読み上げを中止します。resultStackPanelオブジェクトが非表示になります。
AddHandlerステートメントで、Buttonがクリックされた時のイベントハンドラを追加します(Webで表示がクリックされた時の処理です)。
クリックされたButtonのTagの値を変数indexに格納します。数値にキャストしたindexの値をmyIndexに格納します。-1しているのは、ピンの表面に表示される連番は1から20まで表示されますが、XML要素のインデックスは0から始まるため-1しています。
変数mySendAddressにmyIndexに位置する
これらの値はUri.EscapeDataStringメソッドでエスケープ表現に変換しておきます。
Windows.System.Launcher.LaunchUriAsyncメソッドで、指定されたURIのURIスキーム名に関連付けられている既定のアプリケーション(この場合はIE11のブラウザ)を起動します。
この記述方法では、Windows ストアの認定の要件「2.4 アプリで提供されるプライマリ エクスペリエンスはアプリ内で行われなければならない」に抵触し、ストアの審査には通りませんが、審査員のコメント欄に、「このアプリの目的は病院の位置をBing Maps上に表示させて、キャラクタに読み上げさせることにあります。ブラウザでの表示はあくまでも補助的手段です。」と記述しておけば、大体認定されますので、お試しください。
Try~Catch~End Tryで例外処理を行っています。例外が発生した場合はErrorShowプロシージャを実行します。
最後にGridView1のItemsSourceプロパティにmyHospitalInfoオブジェクトを追加します。これで、マウスの右クリックをした際に、アプリケーションバー内に病院の一覧が表示されます。
非同期処理で行われるためメソッドの先頭にAsyncを追加します。
Private Async Sub myGeolocator_PositionChanged(sender As Geolocator, args As PositionChangedEventArgs)
Dim myLatitude As String = String.Empty
Dim myLongitude As String = String.Empty
Dim no As Integer = 0
Await myCoreDispacher.RunAsync(CoreDispatcherPriority.Normal, Async Sub()
Dim pos As Geoposition = args.Position
myMap.Children.Clear()
Dim myPin As New Pushpin
myPin.Background = New SolidColorBrush(Colors.Crimson)
Dim myLocation As Location
If flag = True Then
myLocation = New Location(CDbl(myAddressLatitude), CDbl(myAddressLongitude))
Else
'Windows 8.1の新形式
myLocation = New Location(CDbl(pos.Coordinate.Point.Position.Latitude), CDbl(pos.Coordinate.Point.Position.Longitude))
End If
MapLayer.SetPosition(myPin, myLocation)
myMap.Children.Add(myPin)
myMap.SetView(myLocation, 16)
If flag = False Then
myAddressUri = String.Format("http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder?lat={0}&lon={1}&appid={2}", pos.Coordinate.Point.Position.Latitude, pos.Coordinate.Point.Position.Longitude, AppID)
Else
myAddressUri = String.Format("http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder?lat={0}&lon={1}&appid={2}", myAddressLatitude, myAddressLongitude, AppID)
End If
Dim myAddressHttpClient As New HttpClient
Dim myCurrentAddress As String = String.Empty
Dim xmldoc As XElement
Try
myCurrentAddress = Await myAddressHttpClient.GetStringAsync(myAddressUri)
myCurrentAddress = myCurrentAddress.Replace("<YDF firstResultPosition=" & ChrW(34) & "1" & ChrW(34) & " totalResultsAvailable=" & ChrW(34) & "1" & ChrW(34) & " totalResultsReturned=" & ChrW(34) & "1" & ChrW(34) & " xmlns=" & ChrW(34) & "http://olp.yahooapis.jp/ydf/1.0" & ChrW(34) & ">", "<YDF>")
xmldoc = XElement.Parse(myCurrentAddress)
Dim myAddress = xmldoc.Descendants("Address").Value
Dim myAddressStackPanel As New StackPanel
myAddressStackPanel.Margin = New Thickness(5)
myAddressStackPanel.Background = New SolidColorBrush(Colors.Navy)
myAddressStackPanel.Visibility = Xaml.Visibility.Collapsed
Dim myAddressTextBlock As New TextBlock
myAddressTextBlock.Foreground = New SolidColorBrush(Colors.Red)
myAddressTextBlock.FontSize = 24
myAddressTextBlock.Padding = New Thickness(5)
If flag = False Then
myAddressTextBlock.Text = myAddress & " 辺り"
Else
myAddressTextBlock.Text = WatermarkTextBox1.Text & " 辺り"
End If
myAddressStackPanel.Children.Add(myAddressTextBlock)
myAddressStackPanel.SetValue(Canvas.ZIndexProperty, 20)
If flag = False Then
'Windows 8.1の新形式
MapLayer.SetPosition(myAddressStackPanel, New Location(CDbl(pos.Coordinate.Point.Position.Latitude), CDbl(pos.Coordinate.Point.Position.Longitude)))
Else
MapLayer.SetPosition(myAddressStackPanel, New Location(CDbl(myAddressLatitude), CDbl(myAddressLongitude)))
End If
myMap.Children.Add(myAddressStackPanel)
AddHandler myPin.Tapped, Sub()
myAddressStackPanel.Visibility = Xaml.Visibility.Visible
End Sub
AddHandler myAddressStackPanel.Tapped, Sub()
myAddressStackPanel.Visibility = Xaml.Visibility.Collapsed
End Sub
If flag = True Then
myUri = String.Format("https://maps.googleapis.com/maps/api/place/nearbysearch/xml?location={0}&radius=1000&types=hospital|dentist|doctor&sensor=true&language=ja&key={1}", myAddressCoodinatePosition, GoogleAppID) ‘ (B)
TitleTextBlock.Text = WatermarkTextBox1.Text & " 辺りの1Km範囲内の病院を表示"
Else
myCoodinatePosition = pos.Coordinate.Point.Position.Latitude & "," & pos.Coordinate.Point.Position.Longitude
myUri = String.Format("https://maps.googleapis.com/maps/api/place/nearbysearch/xml?location={0}&radius=1000&types=hospital|dentist|doctor&sensor=true&language=ja&key={1}", myCoodinatePosition, GoogleAppID)
TitleTextBlock.Text = myAddress & " 辺りの1Km範囲内の病院を表示"
End If
Dim myHttpClient As New HttpClient
Dim resultHospital = Await myHttpClient.GetStringAsync(myUri)
Dim httpDoc As XElement = XElement.Parse(resultHospital)
Dim myHospitalInfo As New List(Of HospitalInfo)
For Each result In From c In httpDoc.Descendants("result") Select c
no += 1
Dim myImage As New Image
With myImage
.Width = 70
.Height = 137
.Stretch = Stretch.UniformToFill
.Source = New BitmapImage(New Uri("ms-appx:///Images/syoko1.png", UriKind.Absolute))
End With
Dim syokoStackPanel As New StackPanel
syokoStackPanel.Background = New SolidColorBrush(Colors.DarkGreen)
syokoStackPanel.Children.Add(myImage)
Dim hospitalPin As New Pushpin
hospitalPin.Background = New SolidColorBrush(Colors.Navy)
hospitalPin.Text = no.ToString
myLongitude = result.Element("geometry").Element("location").Element("lng").Value
myLatitude = result.Element("geometry").Element("location").Element("lat").Value
Dim hospitalLocation = New Location(CDbl(myLatitude), CDbl(myLongitude))
MapLayer.SetPosition(hospitalPin, hospitalLocation)
myMap.Children.Add(hospitalPin)
Dim resultStackPanel As New StackPanel
resultStackPanel.Orientation = Orientation.Horizontal
Dim myStackPanel As New StackPanel
myStackPanel.Margin = New Thickness(5)
myStackPanel.Background = New SolidColorBrush(Colors.Navy)
Dim myNameTextBlock As New TextBlock
myNameTextBlock.Foreground = New SolidColorBrush(Colors.Red)
myNameTextBlock.Width = 400
myNameTextBlock.TextWrapping = TextWrapping.Wrap
myNameTextBlock.FontSize = 24
myNameTextBlock.Padding = New Thickness(5)
myNameTextBlock.Text = no.ToString & ":" & "【病院名】=" & result.Element("name").Value
Dim addressTextBlock As New TextBlock
addressTextBlock.Foreground = New SolidColorBrush(Colors.Beige)
addressTextBlock.Width = 400
addressTextBlock.TextWrapping = TextWrapping.Wrap
addressTextBlock.FontSize = 20
addressTextBlock.Padding = New Thickness(5)
addressTextBlock.Text = "【住所】=" & result.Element("vicinity").Value
myHospitalInfo.Add(New HospitalInfo With {.病院名 = no.ToString & ":【病院名】=" & result.Element("name").Value, .住所 = "【住所】=" & result.Element("vicinity").Value})
Dim myButton As New Button
With myButton
.Content = "Webで表示"
.Tag = no.ToString
End With
Dim readingAddress As String = no.ToString & "ばんめ、病院めいは" & result.Element("name").Value & "です。住所は" & result.Element("vicinity").Value & "です。詳細はウェブで確認してください。"
myStackPanel.SetValue(Canvas.ZIndexProperty, no)
myStackPanel.Children.Add(myNameTextBlock)
myStackPanel.Children.Add(addressTextBlock)
myStackPanel.Children.Add(myButton)
resultStackPanel.Children.Add(myStackPanel)
resultStackPanel.Children.Add(syokoStackPanel)
resultStackPanel.Visibility = Xaml.Visibility.Collapsed
MapLayer.SetPosition(resultStackPanel, New Location(CDbl(myLatitude), CDbl(myLongitude)))
myMap.Children.Add(resultStackPanel)
resultStackPanel.SetValue(Canvas.ZIndexProperty, no)
AddHandler hospitalPin.Tapped, Async Sub()
resultStackPanel.Visibility = Xaml.Visibility.Visible
myImage.Visibility = Xaml.Visibility.Visible
myMedia = Me.MediaElement1
Dim synth = New Windows.Media.SpeechSynthesis.SpeechSynthesizer
Dim stream = Await synth.SynthesizeTextToStreamAsync(readingAddress)
myMedia.SetSource(stream, stream.ContentType)
myMedia.Play()
End Sub
AddHandler resultStackPanel.Tapped, Sub()
myMedia.Stop()
resultStackPanel.Visibility = Xaml.Visibility.Collapsed
End Sub
AddHandler myButton.Click, Async Sub(mySender As Object, myArgs As RoutedEventArgs)
Dim index = DirectCast(mySender, Button).Tag
Dim myIndex = CInt(index) - 1
Dim mySendAddress = httpDoc.Descendants("vicinity")(myIndex).Value & " " & httpDoc.Descendants("name")(myIndex).Value
Await Windows.System.Launcher.LaunchUriAsync(New Uri("http://www.bing.com/search?q=" & Uri.EscapeDataString(mySendAddress), UriKind.Absolute))
End Sub
Next
GridView1.ItemsSource = myHospitalInfo
Catch
ErrorShow()
End Try
End Sub)
End Sub近くの病院をキャラクターが音声で教えてくれるアプリ
『Windows 8.1+Visual Studio 2013によるWindows ストア・アプリ開発実例集』 第9回のサンプルプログラムです。


