Search code examples
c#uwpcortana

Open App with Cortana UWP


I have a command for Cortana who says a name, but this only works if the App is open. If I pronounce the commands with the closed app, the app opens but does not start the command. How can I actually open the app?

CortanaCommand.xml:

<CommandSet xml:lang="en-us" Name="ExampleAppCommandSet_en-us">
<CommandPrefix> Open name </CommandPrefix>
<Example> Find a name </Example>
<Command Name="FindName">
  <Example> Find name  </Example>
  <ListenFor> Find name </ListenFor>
  <ListenFor> Find name </ListenFor>
  <Feedback> Find name </Feedback>
  <Navigate/>
</Command>

App.xaml.cs (public app):

public App()
    {
        Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
           Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
           Microsoft.ApplicationInsights.WindowsCollectors.Session);
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

App.xaml.cs (OnActivated):

protected override void OnActivated(IActivatedEventArgs e)
    {
        // Was the app activated by a voice command?
        if (e.Kind != Windows.ApplicationModel.Activation.ActivationKind.VoiceCommand)
        {
            return;
        }

        var commandArgs = e as Windows.ApplicationModel.Activation.VoiceCommandActivatedEventArgs;

        var speechRecognitionResult = commandArgs.Result;
        string voiceCommandName = speechRecognitionResult.RulePath[0];
        string textSpoken = speechRecognitionResult.Text;

        Frame rootFrame = Window.Current.Content as Frame;
        MainPage page = rootFrame.Content as MainPage;
        if (page == null)
        {
            return;
        }

        switch (voiceCommandName)
        {
            case "FindName":
                page.FindNameInList();
                break;

            default:
                // There is no match for the voice command name.
                break;
        }
    }

MainPage.xaml.cs:

private async void Page_Loaded(object sender, RoutedEventArgs e)
    {
        var storageFile =
          await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(
            new Uri("ms-appx:///CortanaCommand.xml"));
        await Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager
            .InstallCommandDefinitionsFromStorageFileAsync(storageFile);
    }

    public async void FindNameInList()
    {
        MediaElement mediaElement = new MediaElement();

        // The object for controlling the speech synthesis engine (voice).
        var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();

        // Generate the audio stream from plain text.
        SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Your name, is, Jhon");

        // Send the stream to the media object.
        mediaElement.SetSource(stream, stream.ContentType);
        mediaElement.Play();
    }

Thanks in advance!


Solution

  • You need to register a background task to handle this case.

    The official Cortana voice command sample is for your reference.

    You could check the AdventureWorksVoiceCommandService.cs to learn how to achieve it.