Adding Cortana to your Windows 10 App

Aug 21, 2015

cortanawindows-10

The Cortana voice command features integrated into Windows 10 enable developers to give users convenient ways to access data that usually requires several user actions (tapping, swiping, typing, etc.) or time to find (looking through a long list of items or reading a large piece of text). Three examples where this functionality would be helpful are:

  • Case 1 - A hospital: The staff uses Cortana to find the closest open bed for a newly admitted patient
  • Case 2 - A retail store: A sales associate finds whether a product is in stock for a customer
  • Case 3 - A shopper: A shopper tries to find the location of their favorite store in a large shopping mall

Making it more convenient for users to access relevant data will enable apps to drive more value, since users will be able to access the information they seek more quickly.

Adding Cortana voice commands to a Universal Windows Platform (UWP) app requires adding two additional files to a project, adding a few lines of code to the OnLaunch event, overriding the OnActivated method in the App.xaml.cs file, and overriding the OnNavigatedTo method in any other XAML views that will be opened by the commands.

var storageFile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///VoiceCommands.xml"));
await Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(storageFile);

// OPTIONAL!!! Used to dynamically populate the phrase list for a command
Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinition vcDef;
if (Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager.InstalledCommandDefinitions.TryGetValue("CommandSet_en-us", out vcDef))
    await vcDef.SetPhraseListAsync("section", new string[]{"schedule","mail","tasks"});
  • Methods to override
    OnActivated
    Located in the App.xaml.cs file. Specify which XAML page will be navigated to based on the voice command invoked.
/// <summary>
/// OnActivated is the entry point for an application when it is launched via
/// means other than normal user interaction. This includes Voice Commands, URI activation,
/// being used as a share target from another app, etc. Here, we're going to handle the
/// Voice Command activation from Cortana.
/// 
/// Note: Be aware that an older VCD could still be in place for your application if you
/// modify it and update your app via the store. You should be aware that you could get 
/// activations that include commands in older versions of your VCD, and you should try
/// to handle them gracefully.
/// </summary>
/// <param name="args">Details about the activation method, including the activation
/// phrase (for voice commands) and the semantic interpretation, parameters, etc.</param>
protected override void OnActivated(IActivatedEventArgs args)
{
    base.OnActivated(args);
    string section = string.Empty;

    if (args.Kind == ActivationKind.VoiceCommand)
    {
        VoiceCommandActivatedEventArgs voiceArgs = args as VoiceCommandActivatedEventArgs;
        SpeechRecognitionResult speechRecognitionResult = voiceArgs.Result;

        // Access the value of the {section} phrase in the voice command
        section = this.SemanticInterpretation("section", speechRecognitionResult);
    }

    Frame rootFrame = Window.Current.Content as Frame;

    if (rootFrame == null)
    {
        // Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = new Frame();

        rootFrame.NavigationFailed += OnNavigationFailed;

        // Place the frame in the current Window
        Window.Current.Content = rootFrame;
    }

    // Specify what page should be loaded due to the command
    // NOTE: This can be an if or case statement depending on the number of commands
    rootFrame.Navigate(typeof(MainPage), section);

    Window.Current.Activate();
}

/// <summary>
/// Returns the semantic interpretation of a speech result. Returns null if there is no interpretation for
/// that key.
/// </summary>
/// <param name="interpretationKey">The interpretation key.</param>
/// <param name="speechRecognitionResult">The result to get an interpretation from.</param>
/// <returns></returns>
private string SemanticInterpretation(string interpretationKey, SpeechRecognitionResult speechRecognitionResult)
{
    return speechRecognitionResult.SemanticInterpretation.Properties[interpretationKey].FirstOrDefault();
}
OnNavigatedTo
Located in XAML views. Specify how content on the page will be displayed based on the parameters specified in the command.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if (e.Parameter is string && (e.Parameter as string) != string.Empty)
    {
        // Get the parameter value and cast it to the class type it was passed as
        string section = (e.Parameter as string);
        
        // Loading and manipulating content based on the parameter specified
    }
}

Augmenting applications with voice commands would work as verbal shortcuts to improve content consumption by users. By creating data driven apps that enable users to ask specific and useful questions, an app can be more transparent to a user and improve its adoption and usage.

MPT's Tech Blog © 2024