Installing a VCD

,

Installation of a VCD is done programmatically and can be performed anywhere in your app, as demonstrated in the following example:

string path = "ms-appx:///Speech/VoiceCommands/VoiceCommands.xml";
Uri commandFileUri = new Uri(path, UriKind.Absolute);
await VoiceCommandService.InstallCommandSetsFromFileAsync(commandFileUri);

The ms-appx:/// prefix represents the install directory of the app. The VoiceCommandService InstallCommandSetsFromFileAsync method follows the asynchronous pattern, allowing you to wait for the method’s completion without blocking the UI thread.

When the VCD has been installed, the user is then able to launch your app by tapping and holding the hardware Windows button on the device and by uttering a registered command for your app.

To verify that the VCD has been correctly installed, use the question mark (?) button to navigate to the “What Can I Say?” screen, as shown in Figure 23.1. If the VCD file has been installed correctly, your app is displayed on the “What Can I Say?” screen.

Image

FIGURE 23.1 The question mark button presents the “What Can I Say?” screen.

Tapping on your app’s title brings up the list of commands defined in the VCD file.

Command information is passed to your app using a query string appended to the command’s Navigate Target URL attribute, as defined in the VCD.

The sample’s VoiceCommandView page OnNavigatedTo method calls the viewmodel’s Initialize method, passing it the navigation context’s query string dictionary, like so:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    ViewModel.Initialize(NavigationContext.QueryString);
}

The Initialize method attempts to retrieve the weather command set. If the command set is not located, it indicates that the VCD has yet to be installed. See Listing 23.15. You look at retrieving a command set in a moment.

When the query string contains a ‘voiceCommandName’ key, it indicates that a voice command has been activated.

The text for the entire recognized phrase is included as the value of the ‘reco’ query string parameter. In addition, each phrase list value is provided as a parameter of the same name. Thus, the value of the City phrase list can be retrieved using the key ‘City’.

LISTING 23.15. VoiceCommandViewModel.Initialize Method


public async Task Initialize(IDictionary<string, string> queryStringDictionary)
{
    VoiceCommandSet commandSet = GetWeatherCommandSet();

    if (commandSet == null)
    {
        const string path = "ms-appx:///Speech/VoiceCommands/VoiceCommands.xml";
        Uri commandFileUri = new Uri(path, UriKind.Absolute);
        await VoiceCommandService.InstallCommandSetsFromFileAsync(commandFileUri);

        commandSet = GetWeatherCommandSet();
        commandSet.UpdatePhraseListAsync("City", woeDictionary.Keys);
    }

    string voiceCommandName;
    if (queryStringDictionary.TryGetValue("voiceCommandName", out voiceCommandName)
        && voiceCommandName == "ShowWeather")
    {
        string city;
        if (queryStringDictionary.TryGetValue("City", out city))
        {
            UpdateWeather(city);
        }
    }
    else
    {
        SayWelcome();
    }
}


A command set defined in a VCD can be retrieved from the InstalledCommandSets property of the VoiceCommandService. In the following excerpt, LINQ is used to retrieve the weather command set via the viewmodel’s GetWeatherCommandSet method:

VoiceCommandSet GetWeatherCommandSet()
{
    VoiceCommandSet commandSet
        = (from pair in VoiceCommandService.InstalledCommandSets
            where pair.Key == "WeatherCommandSet"
            select pair.Value).SingleOrDefault();
    return commandSet;
}

Having the city name allows the app to query the Yahoo! Weather web service. The web service uses a RESTful API and does not require a developer API key, so it should work out-of-the-box for you. The only piece of information needed by the web service is a weather location. This is specified using a Yahoo! WOEID (Where On Earth Identifier), which is a predefined number that maps to a physical place on the globe.

To query the web service, you perform an HTTP GET on the following address: http://weather.yahooapis.com/forecastrss?w=1234

1234 is replaced by a valid WOEID.

Temperature values are, by default, returned in degrees Fahrenheit. This can be switched to Celsius using the query string parameter and value “u=c”.

You can look up WOEIDs for specific locations using various third-party websites, such as http://woeid.rosselliot.co.nz/lookup/ or http://sigizmund.info/woeidinfo/.

The sample Weather Voice app uses a small set of hard-coded locations. The viewmodel’s UpdateWeather method uses a WebClient object and a dictionary of predefined WOEIDs and city names to query the Yahoo! Weather API. See Listing 23.16.

LISTING 23.16. VoiceCommandViewModel.UpdateWeather Method


async Task UpdateWeather(string city)
{
    CityName = city;

    string woeID;
    if (!woeDictionary.TryGetValue(city, out woeID))
    {
        MessageService.ShowMessage("Unknown city.");
        return;
    }

    Console.WriteLine(woeID);

    const string weatherUrl = "http://weather.yahooapis.com/forecastrss?u=c&w=";
    Uri uri = new Uri(weatherUrl + woeID, UriKind.Absolute);

    webClient.DownloadStringAsync(uri);
}


The WebClient’s DownloadStringCompleted event handler retrieves the weather information that is provided as an RSS document, as shown in the following excerpt:

void HandleWebClientDownloadStringCompleted(
    object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Cancelled || e.Error != null)
    {
        MessageService.ShowWarning("Unable to retrieve weather information.");
        return;
    }

    string resultText = e.Result;

    UpdateFromRssResult(resultText);
}

The viewmodel’s UpdateFromRssResult attempts to parse the RSS response. The RSS contains a lot of information, including forecast information, which is ignored in this sample. Only the current temperate and conditions are retrieved from the yweather:condition element. The following is an example of the pertinent element:

<yweather:condition  text="Partly Cloudy"  code="30"
                     temp="72"  date="Tue, 11 Sep 2012 3:50 pm CEST" />

Because the condition element is prefixed with the namespace yweather, to resolve the value using the XDocument API, the element must be combined with an XNamespace value, as shown in Listing 23.17.

LINQ is used to retrieve the weather information, and an anonymous type is created containing the value of the temperature and the weather description. The viewmodel’s Temperature and WeatherDescription properties are updated.

LISTING 23.17. VoiceCommandViewModel.UpdateFromRssResult Method (excerpt)


async Task UpdateFromRssResult(string resultText)
{
    XDocument document = XDocument.Parse(resultText);

    XNamespace xNamespace = "http://xml.weather.yahoo.com/ns/rss/1.0";

    var weatherItem
        = (from condition in document.Descendants(xNamespace + "condition")
                        select new
                        {
                            Text = condition.Attribute("text").Value,
                            Temperature = condition.Attribute("temp").Value
                        }).SingleOrDefault();

    if (weatherItem != null)
    {
        WeatherDescription = weatherItem.Text;
        Temperature = weatherItem.Temperature + 'u2103';

        ...
    }
}


The VoiceCommandView.xml page contains three TextBlocks that display the city name, the temperature, and the weather description, as shown in the following excerpt:

<TextBlock Text="{Binding CityName, FallbackValue=Unknown}"
            Style="{StaticResource GridRowTextStyle}" />
<TextBlock Text="{Binding Temperature, FallbackValue=C}"
            Style="{StaticResource GridRowTextStyle}"
            FontSize="{StaticResource PhoneFontSizeHuge}"
            Grid.Row="1" />
<TextBlock Text="{Binding WeatherDescription, FallbackValue=Unknown}"
            Style="{StaticResource GridRowTextStyle}"
            VerticalAlignment="Top"
            Grid.Row="2"/>

After navigating to the VoiceCommandView.xaml page, the user is able to request the weather conditions from one of the predefined locations. Holding down the hardware Windows button and stating “Weather Zurich Switzerland” displays the page shown in Figure 23.2.

Image

FIGURE 23.2 VoiceCommandView displays the weather conditions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.146.173