Partager via


Activer une application au premier plan à l’aide de commandes vocales via Cortana

Avertissement

Cette fonctionnalité n’est plus prise en charge à partir de la mise à jour Windows 10 Update de mai 2020 (version 2004, nom de code « 20H1 »).

Outre l’utilisation de commandes vocales dans Cortana pour accéder aux fonctionnalités système, vous pouvez également étendre Cortana avec des fonctionnalités et fonctionnalités à partir de votre application. À l’aide de commandes vocales, votre application peut être activée au premier plan et une action ou une commande exécutée dans l’application.

Lorsqu’une application gère une commande vocale au premier plan, elle prend le focus et Cortana est ignorée. Si vous préférez, vous pouvez activer votre application et exécuter une commande en tant que tâche en arrière-plan. Dans ce cas, Cortana conserve le focus et votre application retourne tous les commentaires et résultats via le canevas Cortana et la voix Cortana .

Les commandes vocales qui nécessitent un contexte supplémentaire ou une entrée utilisateur (par exemple, l’envoi d’un message à un contact spécifique) sont mieux gérées dans une application de premier plan, tandis que les commandes de base (telles que la liste des prochains voyages) peuvent être gérées dans Cortana via une application en arrière-plan.

Si vous souhaitez activer une application en arrière-plan à l’aide de commandes vocales, consultez Activer une application en arrière-plan dans Cortana à l’aide de commandes vocales.

Remarque

Une commande vocale est un énoncé unique avec une intention spécifique, définie dans un fichier VCD (Voice Command Definition), dirigé vers une application installée via Cortana.

Un fichier VCD définit une ou plusieurs commandes vocales, chacune avec une intention unique.

Les définitions de commande vocale peuvent varier en complexité. Ils peuvent prendre en charge n’importe quoi d’un énoncé unique et limité à une collection d’énoncés de langage naturel plus flexibles, tout en indiquant la même intention.

Pour illustrer les fonctionnalités de l’application de premier plan, nous allons utiliser une application de planification et de gestion de voyage nommée Adventure Works à partir de l’exemple de commande vocale Cortana.

Pour créer un voyage Adventure Works sans Cortana, un utilisateur lance l’application et accède à la page Nouveau voyage . Pour afficher un voyage existant, un utilisateur lancerait l’application, accédez à la page Des voyages à venir, puis sélectionnez le voyage.

À l’aide de commandes vocales via Cortana, l’utilisateur peut simplement dire « Adventure Works ajouter un voyage » ou « Ajouter un voyage sur Adventure Works » pour lancer l’application et accéder à la page Nouveau voyage . À son tour, dire « Adventure Works, montrer mon voyage à Londres » lancera l’application et accédez à la page de détails trip , illustrée ici.

Capture d’écran de l’application de premier plan de Cortana

Voici les étapes de base pour ajouter des fonctionnalités de commande vocale et intégrer Cortana à votre application à l’aide de la reconnaissance vocale ou de l’entrée clavier :

  1. Créez un fichier VCD. Il s’agit d’un document XML qui définit toutes les commandes parlées que l’utilisateur peut dire pour lancer des actions ou appeler des commandes lors de l’activation de votre application. Consultez les éléments et attributs VCD v1.2.
  2. Inscrivez les jeux de commandes dans le fichier VCD lorsque l’application est lancée.
  3. Gérez la commande d’activation par voix, la navigation au sein de l’application et l’exécution de la commande.

Conseil

Conditions préalables

Si vous débutez avec le développement d’applications plateforme Windows universelle (UWP), consultez ces rubriques pour vous familiariser avec les technologies présentées ici.

Instructions relatives à l’expérience utilisateur

Consultez les instructions de conception de Cortana pour obtenir des informations sur l’intégration de votre application à Cortana et aux interactions vocales pour obtenir des conseils utiles sur la conception d’une application prenant en charge la reconnaissance vocale utile et attrayante.

Créer une solution avec un projet dans Visual Studio

  1. Lancez Microsoft Visual Studio 2015.

    La page de démarrage de Visual Studio 2015 s’affiche.

  2. Dans le menu Fichier, sélectionnez Nouveau>Projet.

    La boîte de dialogue Nouveau projet s’affiche. Le volet gauche de la boîte de dialogue vous permet de sélectionner le type de modèles à afficher.

  3. Dans le volet gauche, développez Modèles installés > Visual C# > Windows, puis sélectionnez le groupe de modèles universels.> Le volet central de la boîte de dialogue affiche une liste de modèles de projet pour les applications plateforme Windows universelle (UWP).

  4. Dans le volet central, sélectionnez le modèle Application vide (Windows universel).

    Le modèle d’application vide crée une application UWP minimale qui compile et s’exécute, mais ne contient aucun contrôle ou données d’interface utilisateur. Vous ajoutez des contrôles à l’application au cours de ce didacticiel.

  5. Dans la zone de texte Nom , tapez le nom de votre projet. Pour cet exemple, nous utilisons « AdventureWorks ».

  6. Cliquez sur OK pour créer le projet.

    Microsoft Visual Studio crée votre projet et l’affiche dans le Explorateur de solutions.

Ajouter des ressources d’image au projet et les spécifier dans le manifeste de l’application

Les applications UWP peuvent sélectionner automatiquement les images les plus appropriées en fonction de paramètres et de fonctionnalités d’appareil spécifiques (contraste élevé, pixels effectifs, paramètres régionaux, etc.). Il vous suffit de fournir les images et de vous assurer que vous utilisez la convention d’affectation de noms et l’organisation de dossiers appropriées au sein du projet d’application pour les différentes versions de ressources. Si vous ne fournissez pas les versions de ressources recommandées, l’accessibilité, la localisation et la qualité de l’image peuvent souffrir, en fonction des préférences, des capacités, du type d’appareil et de l’emplacement de l’utilisateur.

Pour plus d’informations sur les ressources d’image pour les facteurs de contraste et d’échelle élevés, consultez Recommandations pour les ressources de vignette et d’icône.

Vous nommez des ressources à l’aide de qualificateurs. Les qualificateurs de ressources sont des modificateurs de dossier et de nom de fichier qui identifient le contexte dans lequel une version particulière d’une ressource doit être utilisée.

La convention d’affectation de noms standard est foldername/qualifiername-value[_qualifiername-value]/filename.qualifiername-value[_qualifiername-value].ext. Par exemple, images/logo.scale-100_contrast-white.pngqui peut être référencé dans le code en utilisant uniquement le dossier racine et le nom de fichier : images/logo.png. Découvrez comment nommer des ressources à l’aide de qualificateurs.

Nous vous recommandons de marquer la langue par défaut sur les fichiers de ressources de chaîne (par en-US\resources.reswexemple) et le facteur d’échelle par défaut sur les images (par logo.scale-100.pngexemple), même si vous ne prévoyez pas actuellement de fournir des ressources localisées ou plusieurs ressources de résolution. Toutefois, au minimum, nous vous recommandons de fournir des ressources pour 100, 200 et 400 facteurs d’échelle.

Important

L’icône d’application utilisée dans la zone de titre du canevas Cortana est l’icône Square44x44Logo spécifiée dans le fichier « Package.appxmanifest ».

Créer un fichier VCD

  1. Dans Visual Studio, cliquez avec le bouton droit sur le nom de votre projet principal, puis sélectionnez Ajouter > un nouvel élément. Ajoutez un fichier XML.
  2. Tapez un nom pour le fichier VCD (pour cet exemple, « AdventureWorksCommands.xml »), puis cliquez sur Ajouter.
  3. Dans Explorateur de solutions, sélectionnez le fichier VCD.
  4. Dans la fenêtre Propriétés , définissez l’action Générer sur Contenu, puis définissez Copy sur le répertoire de sortie pour Copier si elle est plus récente.

Modifier le fichier VCD

Ajoutez un élément VoiceCommands avec un attribut xmlns pointant vers https://schemas.microsoft.com/voicecommands/1.2.

  1. Pour chaque langue prise en charge par votre application, créez un élément CommandSet qui contient les commandes vocales prises en charge par votre application.

    Vous pouvez déclarer plusieurs éléments CommandSet, chacun avec un attribut xml :lang différent afin que votre application soit utilisée sur différents marchés. Par exemple, une application pour le États-Unis peut avoir un CommandSet pour l’anglais et un CommandSet pour l’espagnol.

    Attention

    Pour activer une application et lancer une action à l’aide d’une commande vocale, l’application doit inscrire un fichier VCD qui contient un CommandSet avec une langue qui correspond à la langue vocale sélectionnée par l’utilisateur pour son appareil. La langue vocale se trouve dans La langue vocale du système > > de > paramètres.

  2. Ajoutez un élément Command pour chaque commande que vous souhaitez prendre en charge. Chaque commande déclarée dans un fichier VCD doit inclure les informations suivantes :

    • Attribut AppName que votre application utilise pour identifier la commande vocale au moment de l’exécution.
    • Élément Example qui contient une expression décrivant comment un utilisateur peut appeler la commande. Cortana montre cet exemple lorsque l’utilisateur indique « Que puis-je dire ? », « Aide » ou appuyez sur Afficher plus.
    • Élément ListenFor qui contient les mots ou expressions que votre application reconnaît en tant que commande. Chaque élément ListenFor peut contenir des références à un ou plusieurs éléments PhraseList qui contiennent des mots spécifiques pertinents pour la commande.

Remarque

Les éléments ListenFor ne peuvent pas être modifiés par programmation. Toutefois, les éléments PhraseList associés aux éléments ListenFor peuvent être modifiés par programmation. Les applications doivent modifier le contenu de PhraseList au moment de l’exécution en fonction du jeu de données généré à mesure que l’utilisateur utilise l’application. Voir Modifier dynamiquement les listes d’expressions VCD Cortana.

Élément Feedback qui contient le texte de Cortana à afficher et à parler à mesure que l’application est lancée.

Un élément Navigate indique que la commande vocale active l’application au premier plan. Dans cet exemple, la showTripToDestination commande est une tâche de premier plan.

Un élément VoiceCommandService indique que la commande vocale active l’application en arrière-plan. La valeur de l’attribut Target de cet élément doit correspondre à la valeur de l’attribut Name de l’élément uap :AppService dans le fichier package.appxmanifest. Dans cet exemple, les commandes et cancelTripToDestination les whenIsTripToDestination commandes sont des tâches en arrière-plan qui spécifient le nom du service d’application comme « AdventureWorksVoiceCommandService ».

Pour plus d’informations, consultez les éléments et attributs VCD v1.2.

Voici une partie du fichier VCD qui définit les commandes vocales en-us pour l’application 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>

Installer les commandes VCD

Votre application doit s’exécuter une fois pour installer le VCD.

Remarque

Les données de commande vocale ne sont pas conservées dans les installations d’application. Pour vous assurer que les données de commande vocale pour votre application restent intactes, envisagez d’initialiser votre fichier VCD chaque fois que votre application est lancée ou activée, ou de conserver un paramètre qui indique si le VCD est actuellement installé.

Dans le fichier « app.xaml.cs » :

  1. Ajoutez la directive using suivante :

    using Windows.Storage;
    
  2. Marquez la méthode « OnLaunched » avec le modificateur asynchrone.

    protected async override void OnLaunched(LaunchActivatedEventArgs e)
    
  3. Appelez InstallCommandDefinitionsFromStorageFileAsync dans le gestionnaire OnLaunched pour inscrire les commandes vocales que le système doit reconnaître.

Dans l’exemple Adventure Works, nous définissons d’abord un objet StorageFile .

Nous appelons ensuite GetFileAsync pour l’initialiser avec notre fichier « AdventureWorksCommands.xml ».

Cet objet StorageFile est ensuite passé à InstallCommandDefinitionsFromStorageFileAsync.

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());
}

Gérer l’activation et exécuter les commandes vocales

Spécifiez la façon dont votre application répond aux activations de commande vocale suivantes (après son lancement au moins une fois et que les jeux de commandes vocales ont été installés).

  1. Vérifiez que votre application a été activée par une commande vocale.

    Remplacez l’événement Application.OnActivated et vérifiez si IActivatedEventArgs.Kind is VoiceCommand.

  2. Déterminez le nom de la commande et ce qui a été parlé.

    Obtenez une référence à un objet VoiceCommandActivatedEventArgs à partir de l’IActivatedEventArgs et interrogez la propriété Result pour un objet SpeechRecognitionResult.

    Pour déterminer ce que l’utilisateur a dit, vérifiez la valeur du texte ou les propriétés sémantiques de l’expression reconnue dans le dictionnaire SpeechRecognitionSemanticInterpretation.

  3. Effectuez les actions appropriées dans votre application, telles que la navigation vers la page souhaitée.

Pour cet exemple, nous renvoyons au VCD à l’étape 3 : modifiez le fichier VCD.

Une fois que nous obtenons le résultat de la reconnaissance vocale pour la commande vocale, nous obtenons le nom de la commande à partir de la première valeur du tableau RulePath . Comme le fichier VCD a défini plusieurs commandes vocales possibles, nous devons comparer la valeur aux noms de commandes dans le VCD et effectuer l’action appropriée.

L’action la plus courante qu’une application peut effectuer consiste à accéder à une page contenant du contenu correspondant au contexte de la commande vocale. Pour cet exemple, nous accédons à une page TripPage et transmettons la valeur de la commande vocale, la façon dont la commande a été entrée et l’expression « destination » reconnue (le cas échéant). L’application peut également envoyer un paramètre de navigation à SpeechRecognitionResult lors de la navigation vers la page.

Vous pouvez déterminer si la commande vocale qui a lancé votre application a été réellement parlée, ou si elle a été tapée en tant que texte, à partir du dictionnaire SpeechRecognitionSemanticInterpretation.Properties à l’aide de la clé commandMode. La valeur de cette clé est « voix » ou « text ». Si la valeur de la clé est « voix », envisagez d’utiliser la synthèse vocale (Windows.Media.SpeechSynthesis) dans votre application pour fournir à l’utilisateur des commentaires parlés.

Utilisez SpeechRecognitionSemanticInterpretation.Properties pour connaître le contenu parlé dans les contraintes PhraseList ou PhraseTopic d’un élément ListenFor. La clé de dictionnaire est la valeur de l’attribut Label de l’élément PhraseList ou PhraseTopic . Ici, nous montrons comment accéder à la valeur de l’expression {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 can represent many different activation types. 
        // Cast it so we can get the parameters we care about 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 we can't determine what page to launch, go to the default entry point.
                navigationToPageType = typeof(View.TripListView);
                break;
        }
    }
    // Protocol activation occurs when a card is clicked within Cortana (using a background task).
    else if (args.Kind == ActivationKind.Protocol)
    {
        // Extract the launch context. In this case, we're just using 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. We let the destination page check if the 
        // destination trip still exists, and navigate back to the trip list if it doesn't.
        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 we were launched via any other mechanism, fall back to the main page view.
        // Otherwise, we'll hang 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 we're expecting 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();
}