Compartir a través de


Activación de una aplicación en segundo plano en Cortana mediante comandos de voz

Advertencia

Esta característica ya no se admite a partir de la actualización de mayo de 2020 de Windows 10 (versión 2004, nombre de código "20H1").

Consulte Cortana en Microsoft 365 para obtener información sobre cómo Cortana está transformando las experiencias de productividad modernas.

Además de usar comandos de voz en Cortana para acceder a las características del sistema, también puedes ampliar Cortana con características y funcionalidades de la aplicación (como una tarea en segundo plano) mediante comandos de voz que especifican una acción o un comando que se va a ejecutar. Cuando una aplicación controla un comando de voz en segundo plano, no toma el foco. En su lugar, devuelve todos los comentarios y resultados a través del lienzo de Cortana y la voz de Cortana .

Las aplicaciones se pueden activar en primer plano (la aplicación toma el foco) o activarse en segundo plano (Cortana conserva el foco), en función de la complejidad de la interacción. Por ejemplo, los comandos de voz que requieren contexto adicional o entrada de usuario (como enviar un mensaje a un contacto específico) se controlan mejor en una aplicación en primer plano, mientras que los comandos básicos (como enumerar los próximos viajes) se pueden controlar en Cortana a través de una aplicación en segundo plano.

Si quieres activar una aplicación en primer plano mediante comandos de voz, consulta Activar una aplicación en primer plano con comandos de voz a través de Cortana.

Nota:

Un comando de voz es una expresión única con una intención específica, definida en un archivo de definición de comandos de voz (VCD), dirigida a una aplicación instalada a través de Cortana.

Un archivo VCD define uno o varios comandos de voz, cada uno con una intención única.

Las definiciones de comandos de voz pueden variar en complejidad. Pueden admitir cualquier cosa desde una sola expresión restringida a una colección de expresiones de lenguaje natural más flexibles, todas denotando la misma intención.

Usamos una aplicación de planificación y administración de viajes denominada Adventure Works integrada en la interfaz de usuario de Cortana , que se muestra aquí, para mostrar muchos de los conceptos y características que se describen. Para obtener más información, consulta el ejemplo de comandos de voz de Cortana.

Captura de pantalla del inicio de la aplicación en primer plano de Cortana

Para ver un viaje de Adventure Works sin Cortana, un usuario iniciaría la aplicación y navegaría a la página Próximos viajes .

Con los comandos de voz a través de Cortana para iniciar la aplicación en segundo plano, el usuario puede decir, en su lugar, Adventure Works, when is my trip to Las Vegas?. La aplicación controla el comando y Cortana muestra los resultados junto con el icono de la aplicación y otra información de la aplicación, si se proporciona.

Captura de pantalla de Cortana con una consulta básica y una pantalla de resultados mediante la aplicación AdventureWorks en segundo plano

Los pasos básicos siguientes agregan funcionalidad de comando de voz y amplían Cortana con funcionalidad en segundo plano desde la aplicación mediante la entrada de voz o teclado.

  1. Cree un servicio de aplicaciones (consulte Windows.ApplicationModel.AppService) que Cortana invoca en segundo plano.
  2. Cree un archivo VCD. El archivo VCD es un documento XML que define todos los comandos hablados que el usuario puede indicar para iniciar acciones o invocar comandos al activar la aplicación. Consulte Elementos y atributos de VCD v1.2.
  3. Registre los conjuntos de comandos en el archivo VCD cuando se inicie la aplicación.
  4. Controle la activación en segundo plano del servicio de aplicaciones y la ejecución del comando de voz.
  5. Muestra y habla los comentarios adecuados al comando de voz dentro de Cortana.

Sugerencia

Requisitos previos

Si no estás familiarizado con el desarrollo de aplicaciones de Plataforma universal de Windows (UWP), consulta estos temas para familiarizarte con las tecnologías que se describen aquí.

Directrices de experiencia del usuario

Consulta Directrices de diseño de Cortana para obtener información sobre cómo integrar tu aplicación con Cortana y interacciones de voz para obtener sugerencias útiles sobre cómo diseñar una aplicación habilitada para voz útil y atractiva.

Creación de una nueva solución con un proyecto principal en Visual Studio

  1. Inicie Microsoft Visual Studio 2015.
    Aparece la página inicio de Visual Studio 2015.

  2. En el menú Archivo, seleccione Nuevo>Proyecto.
    Se abre el cuadro de diálogo Nuevo proyecto. El panel izquierdo del cuadro de diálogo le permite seleccionar el tipo de plantillas que se van a mostrar.

  3. En el panel izquierdo, expanda Plantillas instaladas > > Visual C# > Windows y, a continuación, elija el grupo de plantillas universales. El panel central del cuadro de diálogo muestra una lista de plantillas de proyecto para aplicaciones de Plataforma universal de Windows (UWP).

  4. En el panel central, seleccione la plantilla Aplicación vacía (Windows universal).
    La plantilla Aplicación en blanco crea una aplicación para UWP mínima que se compila y ejecuta. La plantilla Aplicación en blanco no incluye controles ni datos de la interfaz de usuario. Puede agregar controles a la aplicación mediante esta página como guía.

  5. En el cuadro de texto Nombre , escriba el nombre del proyecto. Ejemplo: Use AdventureWorks.

  6. Haga clic en el botón Aceptar para crear el proyecto.
    Microsoft Visual Studio crea el proyecto y lo muestra en el Explorador de soluciones.

Agregar recursos de imagen al proyecto principal y especificarlos en el manifiesto de aplicación

Las aplicaciones para UWP deben seleccionar automáticamente las imágenes más adecuadas. La selección se basa en configuraciones específicas y funcionalidades del dispositivo (contraste alto, píxeles efectivos, configuración regional, etc.). Debe proporcionar las imágenes y asegurarse de usar la convención de nomenclatura adecuada y la organización de carpetas dentro del proyecto de aplicación para las distintas versiones de recursos.
Si no proporciona las versiones de recursos recomendadas, la experiencia del usuario puede sufrir de las siguientes maneras.

  • Accesibilidad
  • Localización
  • Calidad de la imagen
    Las versiones de recursos se usan para adaptar los siguientes cambios en la experiencia del usuario.
  • Preferencias de usuario
  • Habilidades
  • Tipo de dispositivo
  • Location

Para obtener más información sobre los recursos de imagen para los factores de contraste alto y escala, visite la página Directrices para recursos de icono e icono que se encuentra en msdn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets.

Debe asignar un nombre a los recursos mediante calificadores. Los calificadores de recursos son modificadores de carpeta y nombre de archivo que identifican el contexto en el que se debe usar una versión determinada de un recurso.

La convención de nomenclatura estándar es foldername/qualifiername-value[_qualifiername-value]/filename.qualifiername-value[_qualifiername-value].ext.
Ejemplo: images/logo.scale-100_contrast-white.png, que puede hacer referencia al código con solo la carpeta raíz y el nombre de archivo: images/logo.png.
Para obtener más información, visite la página How to name resources using qualifiers (Cómo asignar nombres a los recursos mediante calificadores) que se encuentra en msdn.microsoft.com/library/windows/apps/xaml/hh965324.aspx.

Microsoft recomienda marcar el idioma predeterminado en los archivos de recursos de cadena (como en-US\resources.resw) y el factor de escala predeterminado en imágenes (como logo.scale-100.png), aunque no planee actualmente proporcionar recursos de resolución localizados o múltiples. Sin embargo, como mínimo, Microsoft recomienda proporcionar recursos para 100, 200 y 400 factores de escala.

Importante

El icono de la aplicación usado en el área de título del lienzo de Cortana es el icono Square44x44Logo especificado en el Package.appxmanifest archivo.
También puede especificar un icono para cada entrada en el área de contenido del lienzo de Cortana . Los tamaños de imagen válidos para los iconos de resultados son:

  • 68w x 68h
  • 68w x 92h
  • 280w x 140h

El icono de contenido no se valida hasta que se pasa un objeto VoiceCommandResponse a la clase VoiceCommandServiceConnection. Si pasa un objeto VoiceCommandResponse a Cortana que incluye un icono de contenido con una imagen que no cumple estas relaciones de tamaño, puede producirse una excepción. 

Ejemplo: La aplicación Adventure Works (VoiceCommandService\\AdventureWorksVoiceCommandService.cs) especifica un cuadrado simple y gris (GreyTile.png) en la clase VoiceCommandContentTile mediante la plantilla de icono TitleWith68x68IconAndText. Las variantes del logotipo se encuentran en VoiceCommandService\\Imagesy se recuperan mediante el método GetFileFromApplicationUriAsync .

var destinationTile = new VoiceCommandContentTile();  

destinationTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
destinationTile.Image = await StorageFile.GetFileFromApplicationUriAsync(
    new Uri("ms-appx:///AdventureWorks.VoiceCommands/Images/GreyTile.png")
);  

Creación de un proyecto de App Service

  1. Haga clic con el botón derecho en el nombre de la solución y seleccione Nuevo > proyecto.

  2. En Plantillas instaladas > > Visual C# > Windows > Universal, seleccione Componente de Windows Runtime. El componente de Windows Runtime es el componente que implementa el servicio de aplicaciones (Windows.ApplicationModel.AppService).

  3. Escriba un nombre para el proyecto y haga clic en el botón Aceptar .
    Ejemplo: VoiceCommandService.

  4. En Explorador de soluciones, seleccione el proyecto y cambie el VoiceCommandService nombre del Class1.cs archivo generado por Visual Studio. Ejemplo: Adventure Works usa AdventureWorksVoiceCommandService.cs.

  5. Haga clic en el botón Sí ; cuando se le pregunte si desea cambiar el nombre de todas las apariciones de Class1.cs.

  6. En el archivo AdventureWorksVoiceCommandService.cs:

    1. Agregue la siguiente directiva using.
      using Windows.ApplicationModel.Background;
    2. Al crear un nuevo proyecto, el nombre del proyecto se usa como espacio de nombres raíz predeterminado en todos los archivos. Cambie el nombre del espacio de nombres para anidar el código de App Service en el proyecto principal. Ejemplo: namespace AdventureWorks.VoiceCommands.
    3. Haga clic con el botón derecho en el nombre del proyecto de App Service en Explorador de soluciones y seleccione Propiedades.
    4. En la pestaña Biblioteca , actualice el campo Espacio de nombres predeterminado con este mismo valor.
      Ejemplo: AdventureWorks.VoiceCommands.
    5. Cree una nueva clase que implemente la interfaz IBackgroundTask. Esta clase requiere un método Run , que es el punto de entrada cuando Cortana reconoce el comando de voz.

    Ejemplo: una clase de tarea en segundo plano básica de la aplicación Adventure Works .

    Nota:

    La propia clase de tarea en segundo plano, así como todas las clases del proyecto de tarea en segundo plano, deben ser clases públicas selladas.

    namespace AdventureWorks.VoiceCommands
    {
        ...
    
        /// <summary>
        /// The VoiceCommandService implements the entry point for all voice commands.
        /// The individual commands supported are described in the VCD xml file. 
        /// The service entry point is defined in the appxmanifest.
        /// </summary>
        public sealed class AdventureWorksVoiceCommandService : IBackgroundTask
        {
            ...
    
            /// <summary>
            /// The background task entrypoint. 
            /// 
            /// Background tasks must respond to activation by Cortana within 0.5 second, and must 
            /// report progress to Cortana every 5 seconds (unless Cortana is waiting for user
            /// input). There is no running time limit on the background task managed by Cortana,
            /// but developers should use plmdebug (https://msdn.microsoft.com/library/windows/hardware/jj680085%28v=vs.85%29.aspx)
            /// on the Cortana app package in order to prevent Cortana timing out the task during
            /// debugging.
            /// 
            /// The Cortana UI is dismissed if Cortana loses focus. 
            /// The background task is also dismissed even if being debugged. 
            /// Use of Remote Debugging is recommended in order to debug background task behaviors. 
            /// Open the project properties for the app package (not the background task project), 
            /// and enable Debug -> "Do not launch, but debug my code when it starts". 
            /// Alternatively, add a long initial progress screen, and attach to the background task process while it runs.
            /// </summary>
            /// <param name="taskInstance">Connection to the hosting background service process.</param>
            public void Run(IBackgroundTaskInstance taskInstance)
            {
              //
              // TODO: Insert code 
              //
              //
        }
      }
    }
    
  7. Declare la tarea en segundo plano como appService en el manifiesto de la aplicación.

    1. En Explorador de soluciones, haga clic con el botón derecho en el Package.appxmanifest archivo y seleccione Ver código.
    2. Busque el elemento Application.
    3. Agregue un Extensions elemento al Application elemento .
    4. Agregue un elemento uap:Extension al elemento Extensions.
    5. Agregue un Category atributo al uap:Extension elemento y establezca el valor del Category atributo en windows.appService.
    6. Agregue un EntryPoint atributo al uap: Extension elemento y establezca el valor del EntryPoint atributo en el nombre de la clase que implementa IBackgroundTask.
      Ejemplo: AdventureWorks.VoiceCommands.AdventureWorksVoiceCommandService.
    7. Agregue un elemento uap:AppService al elemento uap:Extension.
    8. Agregue un Name atributo al uap:AppService elemento y establezca el valor del Name atributo en un nombre para el servicio de aplicaciones, en este caso AdventureWorksVoiceCommandService.
    9. Agregue un segundo uap:Extension elemento al Extensions elemento .
    10. Agregue un Category atributo a este uap:Extension elemento y establezca el valor del Category atributo en windows.personalAssistantLaunch.

    Ejemplo: un manifiesto de la aplicación Adventure Works.

    <Package>
        <Applications>
            <Application>
    
                <Extensions>
                    <uap:Extension Category="windows.appService" EntryPoint="CortanaBack1.VoiceCommands.AdventureWorksVoiceCommandService">
                        <uap:AppService Name="AdventureWorksVoiceCommandService"/>
                    </uap:Extension>
                    <uap:Extension Category="windows.personalAssistantLaunch"/>
                </Extensions>
    
            <Application>
        <Applications>
    </Package>
    
  8. Agregue este proyecto de App Service como referencia en el proyecto principal.

    1. Haga clic con el botón derecho en las referencias.
    2. Seleccione Agregar referencia....
    3. En el cuadro de diálogo Administrador de referencias, expanda Proyectos y seleccione el proyecto de App Service.
    4. Haga clic en el botón Aceptar .

Creación de un archivo VCD

  1. En Visual Studio, haga clic con el botón derecho en el nombre del proyecto principal y seleccione Agregar > nuevo elemento. Agregue un archivo XML.
  2. Escriba un nombre para el archivo VCD.
    Ejemplo: AdventureWorksCommands.xml.
  3. Haga clic en el botón Agregar .
  4. En Explorador de soluciones, seleccione el archivo VCD.
  5. En la ventana Propiedades , establezca Acción de compilación en Contenido y, a continuación, establezca Copiar en el directorio de salida en Copiar si es más reciente.

Editar el archivo VCD

  1. Agregue un VoiceCommands elemento con un xmlns atributo que apunte a https://schemas.microsoft.com/voicecommands/1.2.

  2. Para cada idioma compatible con la aplicación, cree un CommandSet elemento que incluya los comandos de voz admitidos por la aplicación.
    Puedes declarar varios CommandSet elementos, cada uno con un atributo diferente xml:lang para que tu aplicación se use en diferentes mercados. Por ejemplo, una aplicación para el Estados Unidos podría tener un CommandSet para inglés y un CommandSet para español.

    Importante

    Para activar una aplicación e iniciar una acción mediante un comando de voz, la aplicación debe registrar un archivo VCD que incluya un elemento con un CommandSet idioma que coincida con el idioma de voz indicado en el dispositivo del usuario. El idioma de voz se encuentra en Configuración > Del idioma de voz del > sistema>.

  3. Agregue un Command elemento para cada comando que quiera admitir.
    Cada Command uno declarado en un archivo VCD debe incluir esta información:

    • Atributo Name que usa la aplicación para identificar el comando de voz en tiempo de ejecución.

    • Elemento Example que incluye una frase que describe cómo un usuario invoca el comando. Cortana muestra el ejemplo cuando el usuario dice What can I say?, Helpo pulsa Ver más.

    • Elemento ListenFor que incluye las palabras o frases que la aplicación reconoce como un comando. Cada ListenFor elemento puede contener referencias a uno o varios PhraseList elementos que contienen palabras específicas relevantes para el comando.

      Nota:

      ListenFor Los elementos no deben modificarse mediante programación. Sin embargo, los PhraseList elementos asociados a ListenFor los elementos se pueden modificar mediante programación. Las aplicaciones deben modificar el contenido del PhraseList elemento en tiempo de ejecución en función del conjunto de datos generado a medida que el usuario usa la aplicación.

      Para obtener más información, consulte Modificación dinámica de listas de frases de Cortana VCD.

    • Elemento Feedback que incluye el texto para que Cortana muestre y hable mientras se inicia la aplicación.

Un Navigate elemento indica que el comando de voz activa la aplicación en primer plano. En este ejemplo, el showTripToDestination comando es una tarea en primer plano.

Un VoiceCommandService elemento indica que el comando de voz activa la aplicación en segundo plano. El valor del Target atributo de este elemento debe coincidir con el valor del Name atributo del uap:AppService elemento en el archivo package.appxmanifest. En este ejemplo, los whenIsTripToDestination comandos y cancelTripToDestination son tareas en segundo plano que especifican el nombre del servicio de aplicaciones como AdventureWorksVoiceCommandService.

Para obtener más información, consulte la referencia de elementos y atributos de VCD v1.2.

Ejemplo: parte del archivo VCD que define los en-us comandos de voz para la aplicación Adventure Works.

<?xml version="1.0" encoding="utf-8" ?>
<VoiceCommands xmlns="https://schemas.microsoft.com/voicecommands/1.2">
<CommandSet xml:lang="en-us" Name="AdventureWorksCommandSet_en-us">
    <AppName> Adventure Works </AppName>
    <Example> Show trip to London </Example>
    
    <Command Name="showTripToDestination">
        <Example> Show trip to London </Example>
        <ListenFor RequireAppName="BeforeOrAfterPhrase"> show [my] trip to {destination} </ListenFor>
        <ListenFor RequireAppName="ExplicitlySpecified"> show [my] {builtin:AppName} trip to {destination} </ListenFor>
        <Feedback> Showing trip to {destination} </Feedback>
        <Navigate />
    </Command>
      
    <Command Name="whenIsTripToDestination">
        <Example> When is my trip to Las Vegas?</Example>
        <ListenFor RequireAppName="BeforeOrAfterPhrase"> when is [my] trip to {destination}</ListenFor>
        <ListenFor RequireAppName="ExplicitlySpecified"> when is [my] {builtin:AppName} trip to {destination} </ListenFor>
        <Feedback> Looking for trip to {destination}</Feedback>
        <VoiceCommandService Target="AdventureWorksVoiceCommandService"/>
    </Command>
    
    <Command Name="cancelTripToDestination">
        <Example> Cancel my trip to Las Vegas </Example>
        <ListenFor RequireAppName="BeforeOrAfterPhrase"> cancel [my] trip to {destination}</ListenFor>
        <ListenFor RequireAppName="ExplicitlySpecified"> cancel [my] {builtin:AppName} trip to {destination} </ListenFor>
        <Feedback> Cancelling trip to {destination}</Feedback>
        <VoiceCommandService Target="AdventureWorksVoiceCommandService"/>
    </Command>

    <PhraseList Label="destination">
        <Item>London</Item>
        <Item>Las Vegas</Item>
        <Item>Melbourne</Item>
        <Item>Yosemite National Park</Item>
    </PhraseList>
</CommandSet>

Instalación de los comandos de VCD

La aplicación debe ejecutarse una vez para instalar el VCD.

Nota:

Los datos de comandos de voz no se conservan en instalaciones de aplicaciones. Para asegurarse de que los datos del comando de voz de la aplicación permanecen intactos, considere la posibilidad de inicializar el archivo VCD cada vez que se inicie o active la aplicación, o mantenga una configuración que indique si el VCD está instalado actualmente.

En el archivo app.xaml.cs:

  1. Agregue la siguiente directiva using:

    using Windows.Storage;
    
  2. Marque el OnLaunched método con el modificador asincrónico.

    protected async override void OnLaunched(LaunchActivatedEventArgs e)
    
  3. Llame al InstallCommandDefinitionsFromStorageFileAsync método en el OnLaunched controlador para registrar los comandos de voz que se deben reconocer.
    Ejemplo: La aplicación Adventure Works define un StorageFile objeto .
    Ejemplo: llame al GetFileAsync método para inicializar el StorageFile objeto con el AdventureWorksCommands.xml archivo .
    A continuación, el StorageFile objeto se pasa al InstallCommandDefinitionsFromStorageFileAsync método .

    try {
       // Install the main VCD. 
       StorageFile vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync(
             @"AdventureWorksCommands.xml"
       );
    
       await Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);
    
       // Update phrase list.
       ViewModel.ViewModelLocator locator = App.Current.Resources["ViewModelLocator"] as ViewModel.ViewModelLocator;
       if(locator != null) {
             await locator.TripViewModel.UpdateDestinationPhraseList();
         }
     }
     catch (Exception ex) {
         System.Diagnostics.Debug.WriteLine("Installing Voice Commands Failed: " + ex.ToString());
     }
    

Controlar la activación

Especifique cómo responde la aplicación a las siguientes activaciones de comandos de voz.

Nota:

Debes iniciar la aplicación al menos una vez después de instalar los conjuntos de comandos de voz.

  1. Confirme que la aplicación se ha activado mediante un comando de voz.

    Invalide el Application.OnActivated evento y compruebe si IActivatedEventArgs.Kind es VoiceCommand.

  2. Determine el nombre del comando y lo que se habló.

    Obtenga una referencia a un VoiceCommandActivatedEventArgs objeto de IActivatedEventArgs y consulte la Result propiedad de un SpeechRecognitionResult objeto .

    Para determinar lo que dijo el usuario, compruebe el valor de Text o las propiedades semánticas de la frase reconocida en el SpeechRecognitionSemanticInterpretation diccionario.

  3. Realice la acción adecuada en la aplicación, como navegar a la página deseada.

    Nota:

    Si necesita hacer referencia a su VCD, visite la sección Editar el archivo VCD.

    Después de recibir el resultado del reconocimiento de voz para el comando de voz, obtendrá el nombre del comando del primer valor de la RulePath matriz. Dado que el archivo VCD define más de un comando de voz posible, debe comprobar que el valor coincide con los nombres de comando del VCD y realizar la acción adecuada.

    La acción más común para una aplicación es navegar a una página con contenido relevante para el contexto del comando de voz.
    Ejemplo: abra la página TripPage y pase el valor del comando de voz, cómo se ha introducido el comando y la frase de destino reconocida (si procede). Como alternativa, la aplicación puede enviar un parámetro de navegación a SpeechRecognitionResult al navegar a la página TripPage .

    Puedes averiguar si el comando de voz que inició la aplicación se habló realmente o si se ha escrito como texto, desde el SpeechRecognitionSemanticInterpretation.Properties diccionario con la clave commandMode . El valor de esa clave será voice o text. Si el valor de la clave es voice, considere la posibilidad de usar la síntesis de voz (Windows.Media.SpeechSynthesis) en la aplicación para proporcionar al usuario comentarios hablados.

    Use SpeechRecognitionSemanticInterpretation.Properties para averiguar el contenido hablado en las PhraseList restricciones o PhraseTopic de un ListenFor elemento. La clave de diccionario es el valor del Label atributo del PhraseList elemento o PhraseTopic . Ejemplo: el código siguiente para Cómo obtener acceso al valor de la frase {destination} .

    /// <summary>
    /// Entry point for an application activated by some means other than normal launching. 
    /// This includes voice commands, URI, share target from another app, and so on. 
    /// 
    /// NOTE:
    /// A previous version of the VCD file might remain in place 
    /// if you modify it and update the app through the store. 
    /// Activations might include commands from older versions of your VCD. 
    /// Try to handle these commands gracefully.
    /// </summary>
    /// <param name="args">Details about the activation method.</param>
    protected override void OnActivated(IActivatedEventArgs args) {
        base.OnActivated(args);
    
        Type navigationToPageType;
        ViewModel.TripVoiceCommand? navigationCommand = null;
    
        // Voice command activation.
        if (args.Kind == ActivationKind.VoiceCommand) {
            // Event args may represent many different activation types. 
            // Cast the args so that you only get useful parameters out.
            var commandArgs = args as VoiceCommandActivatedEventArgs;
    
            Windows.Media.SpeechRecognition.SpeechRecognitionResult speechRecognitionResult = commandArgs.Result;
    
            // Get the name of the voice command and the text spoken.
            // See VoiceCommands.xml for supported voice commands.
            string voiceCommandName = speechRecognitionResult.RulePath[0];
            string textSpoken = speechRecognitionResult.Text;
    
            // commandMode indicates whether the command was entered using speech or text.
            // Apps should respect text mode by providing silent (text) feedback.
            string commandMode = this.SemanticInterpretation("commandMode", speechRecognitionResult);
    
            switch (voiceCommandName) {
                case "showTripToDestination":
                    // Access the value of {destination} in the voice command.
                    string destination = this.SemanticInterpretation("destination", speechRecognitionResult);
    
                    // Create a navigation command object to pass to the page.
                    navigationCommand = new ViewModel.TripVoiceCommand(
                        voiceCommandName,
                        commandMode,
                        textSpoken,
                        destination
                    );
    
                    // Set the page to navigate to for this voice command.
                    navigationToPageType = typeof(View.TripDetails);
                    break;
                default:
                    // If not able to determine what page to launch, then go to the default entry point.
                    navigationToPageType = typeof(View.TripListView);
                    break;
            }
        }
        // Protocol activation occurs when a card is selected within Cortana (using a background task).
        else if (args.Kind == ActivationKind.Protocol) {
            // Extract the launch context. In this case, use the destination from the phrase set (passed
            // along in the background task inside Cortana), which makes no attempt to be unique. A unique id or 
            // identifier is ideal for more complex scenarios. The destination page is left to check if the 
            // destination trip still exists, and navigate back to the trip list if it does not.
            var commandArgs = args as ProtocolActivatedEventArgs;
            Windows.Foundation.WwwFormUrlDecoder decoder = new Windows.Foundation.WwwFormUrlDecoder(commandArgs.Uri.Query);
            var destination = decoder.GetFirstValueByName("LaunchContext");
    
            navigationCommand = new ViewModel.TripVoiceCommand(
                "protocolLaunch",
                "text",
                "destination",
                destination
            );
    
            navigationToPageType = typeof(View.TripDetails);
        }
        else {
            // If launched using any other mechanism, fall back to the main page view.
            // Otherwise, the app will freeze at a splash screen.
            navigationToPageType = typeof(View.TripListView);
        }
    
        // Repeat the same basic initialization as OnLaunched() above, taking into account whether
        // or not the app is already active.
        Frame rootFrame = Window.Current.Content as Frame;
    
        // Do not repeat app initialization when the Window already has content,
        // just ensure that the window is active.
        if (rootFrame == null) {
            // Create a frame to act as the navigation context and navigate to the first page.
            rootFrame = new Frame();
            App.NavigationService = new NavigationService(rootFrame);
    
            rootFrame.NavigationFailed += OnNavigationFailed;
    
            // Place the frame in the current window.
            Window.Current.Content = rootFrame;
        }
    
        // Since the expectation is to always show a details page, navigate even if 
        // a content frame is in place (unlike OnLaunched).
        // Navigate to either the main trip list page, or if a valid voice command
        // was provided, to the details page for that trip.
        rootFrame.Navigate(navigationToPageType, navigationCommand);
    
        // Ensure the current window is active
        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 speech recognition result to get the semantic interpretation from.</param>
    /// <returns></returns>
    private string SemanticInterpretation(string interpretationKey, SpeechRecognitionResult speechRecognitionResult) {
        return speechRecognitionResult.SemanticInterpretation.Properties[interpretationKey].FirstOrDefault();
    }
    

Control del comando de voz en App Service

Procese el comando de voz en el servicio de aplicaciones.

  1. Agregue las siguientes directivas using al archivo de servicio de comandos de voz.
    Ejemplo: AdventureWorksVoiceCommandService.cs.

        using Windows.ApplicationModel.VoiceCommands;
        using Windows.ApplicationModel.Resources.Core;
        using Windows.ApplicationModel.AppService;
    
  2. Tome un aplazamiento de servicio para que el servicio de aplicaciones no finalice mientras controla el comando de voz.

  3. Confirme que la tarea en segundo plano se está ejecutando como un servicio de aplicaciones activado por un comando de voz.

    1. Convierta IBackgroundTaskInstance.TriggerDetails en Windows.ApplicationModel.AppService.AppServiceTriggerDetails.
    2. Compruebe que IBackgroundTaskInstance.TriggerDetails.Name es el nombre del servicio de aplicaciones en el Package.appxmanifest archivo.
  4. Use IBackgroundTaskInstance.TriggerDetails para crear un objeto VoiceCommandServiceConnection en Cortana para recuperar el comando de voz.

  5. Registre un controlador de eventos para VoiceCommandServiceConnection. VoiceCommandCompleted para recibir una notificación cuando se cierra el servicio de aplicaciones debido a una cancelación de usuario.

  6. Registre un controlador de eventos para que IBackgroundTaskInstance.Canceled reciba una notificación cuando el servicio de aplicaciones se cierre debido a un error inesperado.

  7. Determine el nombre del comando y lo que se habló.

    1. Use VoiceCommand.Propiedad CommandName para determinar el nombre del comando de voz.
    2. Para determinar lo que dijo el usuario, compruebe el valor de Text o las propiedades semánticas de la frase reconocida en el SpeechRecognitionSemanticInterpretation diccionario.
  8. Realice la acción adecuada en el servicio de aplicaciones.

  9. Muestra y habla los comentarios al comando de voz mediante Cortana.

    1. Determine las cadenas que desea que Cortana muestre y hable con el usuario en respuesta al comando de voz y cree un VoiceCommandResponse objeto . Para obtener instrucciones sobre cómo seleccionar las cadenas de comentarios que Cortana muestra y habla, consulte Directrices de diseño de Cortana.
    2. Use la instancia voiceCommandServiceConnection para notificar el progreso o la finalización a Cortana llamando a ReportProgressAsync o ReportSuccessAsync con el VoiceCommandServiceConnection objeto .

    Nota:

    Si necesita hacer referencia a su VCD, visite la sección Editar el archivo VCD.

    public sealed class VoiceCommandService : IBackgroundTask {
        private BackgroundTaskDeferral serviceDeferral;
        VoiceCommandServiceConnection voiceServiceConnection;
    
        public async void Run(IBackgroundTaskInstance taskInstance) {
            //Take a service deferral so the service isn&#39;t terminated.
            this.serviceDeferral = taskInstance.GetDeferral();
    
            taskInstance.Canceled += OnTaskCanceled;
    
            var triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
    
            if (triggerDetails != null &amp;&amp; 
                triggerDetails.Name == "AdventureWorksVoiceServiceEndpoint") {
                try {
                    voiceServiceConnection = 
                    VoiceCommandServiceConnection.FromAppServiceTriggerDetails(
                        triggerDetails);
                    voiceServiceConnection.VoiceCommandCompleted += 
                    VoiceCommandCompleted;
    
                    VoiceCommand voiceCommand = await 
                    voiceServiceConnection.GetVoiceCommandAsync();
    
                    switch (voiceCommand.CommandName) {
                        case "whenIsTripToDestination":
                            {
                                var destination = 
                                voiceCommand.Properties["destination"][0];
                                SendCompletionMessageForDestination(destination);
                                break;
                            }
    
                            // As a last resort, launch the app in the foreground.
                        default:
                            LaunchAppInForeground();
                            break;
                    }
                }
                finally {
                    if (this.serviceDeferral != null) {
                        // Complete the service deferral.
                        this.serviceDeferral.Complete();
                    }
                }
            }
        }
    
        private void VoiceCommandCompleted(VoiceCommandServiceConnection sender,
            VoiceCommandCompletedEventArgs args) {
            if (this.serviceDeferral != null) {
                // Insert your code here.
                // Complete the service deferral.
                this.serviceDeferral.Complete();
            }
        }
    
        private async void SendCompletionMessageForDestination(
            string destination) {
            // Take action and determine when the next trip to destination
            // Insert code here.
    
            // Replace the hardcoded strings used here with strings 
            // appropriate for your application.
    
            // First, create the VoiceCommandUserMessage with the strings 
            // that Cortana will show and speak.
            var userMessage = new VoiceCommandUserMessage();
            userMessage.DisplayMessage = "Here's your trip.";
            userMessage.SpokenMessage = "Your trip to Vegas is on August 3rd.";
    
            // Optionally, present visual information about the answer.
            // For this example, create a VoiceCommandContentTile with an 
            // icon and a string.
            var destinationsContentTiles = new List<VoiceCommandContentTile>();
    
            var destinationTile = new VoiceCommandContentTile();
            destinationTile.ContentTileType = 
                VoiceCommandContentTileType.TitleWith68x68IconAndText;
            // The user taps on the visual content to launch the app. 
            // Pass in a launch argument to enable the app to deep link to a 
            // page relevant to the item displayed on the content tile.
            destinationTile.AppLaunchArgument = 
                string.Format("destination={0}", "Las Vegas");
            destinationTile.Title = "Las Vegas";
            destinationTile.TextLine1 = "August 3rd 2015";
            destinationsContentTiles.Add(destinationTile);
    
            // Create the VoiceCommandResponse from the userMessage and list    
            // of content tiles.
            var response = VoiceCommandResponse.CreateResponse(
                userMessage, destinationsContentTiles);
    
            // Cortana displays a "Go to app_name" link that the user 
            // taps to launch the app. 
            // Pass in a launch to enable the app to deep link to a page 
            // relevant to the voice command.
            response.AppLaunchArgument = string.Format(
                "destination={0}", "Las Vegas");
    
            // Ask Cortana to display the user message and content tile and 
            // also speak the user message.
            await voiceServiceConnection.ReportSuccessAsync(response);
        }
    
        private async void LaunchAppInForeground() {
            var userMessage = new VoiceCommandUserMessage();
            userMessage.SpokenMessage = "Launching Adventure Works";
    
            var response = VoiceCommandResponse.CreateResponse(userMessage);
    
            // When launching the app in the foreground, pass an app 
            // specific launch parameter to indicate what page to show.
            response.AppLaunchArgument = "showAllTrips=true";
    
            await voiceServiceConnection.RequestAppLaunchAsync(response);
        }
    }
    

Una vez activado, app service tiene 0,5 segundos para llamar a ReportSuccessAsync. Cortana muestra y dice una cadena de comentarios.

Nota:

Puede declarar una cadena de comentarios en el archivo VCD. La cadena no afecta al texto de la interfaz de usuario que se muestra en el lienzo de Cortana, solo afecta al texto hablado por Cortana.

Si la aplicación tarda más de 0,5 segundos en realizar la llamada, Cortana inserta una pantalla de entrega, como se muestra aquí. Cortana muestra la pantalla de entrega hasta que la aplicación llama a ReportSuccessAsync o hasta 5 segundos. Si el servicio de aplicaciones no llama a ReportSuccessAsync o a cualquiera de los VoiceCommandServiceConnection métodos que proporcionan a Cortana información, el usuario recibe un mensaje de error y se cancela el servicio de aplicaciones.

Captura de pantalla de Cortana y una consulta básica con pantallas de progreso y resultados mediante la aplicación AdventureWorks en segundo plano