Compartilhar via


Ativar um aplicativo em primeiro plano com comandos de voz por meio da Cortana

Aviso

Não há mais suporte para este recurso a partir da atualização de maio de 2020 do Windows 10 (versão 2004, codinome "20H1").

Além de usar comandos de voz na Cortana para acessar os recursos do sistema, você também pode estender a Cortana com recursos e funcionalidades do seu aplicativo. Usando comandos de voz, seu aplicativo pode ser ativado em primeiro plano e uma ação ou comando executado dentro do aplicativo.

Quando um aplicativo manipula um comando de voz em primeiro plano, ele assume o foco e a Cortana é descartada. Se preferir, você pode ativar seu aplicativo e executar um comando como uma tarefa em segundo plano. Nesse caso, a Cortana mantém o foco e seu aplicativo retorna todos os comentários e resultados por meio da tela da Cortana e da voz da Cortana .

Os comandos de voz que exigem contexto adicional ou entrada do usuário (como enviar uma mensagem para um contato específico) são melhor tratados em um aplicativo em primeiro plano, enquanto os comandos básicos (como listar as próximas viagens) podem ser tratados na Cortana por meio de um aplicativo em segundo plano.

Se você quiser ativar um aplicativo em segundo plano usando comandos de voz, consulte Ativar um aplicativo em segundo plano na Cortana usando comandos de voz.

Observação

Um comando de voz é um único enunciado com uma intenção específica, definido em um arquivo VCD (Definição de Comando de Voz), direcionado a um aplicativo instalado por meio da Cortana.

Um arquivo VCD define um ou mais comandos de voz, cada um com uma intenção exclusiva.

As definições de comando de voz podem variar em complexidade. Eles podem dar suporte a qualquer coisa, desde um único enunciado restrito até uma coleção de enunciados de linguagem natural mais flexíveis, todos denotando a mesma intenção.

Para demonstrar os recursos do aplicativo em primeiro plano, usaremos um aplicativo de planejamento e gerenciamento de viagem chamado Adventure Works do exemplo de comando de voz da Cortana.

Para criar uma nova viagem da Adventure Works sem a Cortana, um usuário iniciaria o aplicativo e navegaria até a página Nova viagem . Para visualizar uma viagem existente, um usuário iniciaria o aplicativo, navegaria até a página Próximas viagens e selecionaria a viagem.

Usando comandos de voz por meio da Cortana, o usuário pode apenas dizer "Adventure Works adicionar uma viagem" ou "Adicionar uma viagem no Adventure Works" para iniciar o aplicativo e navegar até a página Nova viagem . Por sua vez, dizer "Adventure Works, mostre minha viagem a Londres" iniciará o aplicativo e navegará até a página de detalhes da viagem, mostrada aqui.

Captura de tela da Cortana iniciando o aplicativo em primeiro plano

Estas são as etapas básicas para adicionar a funcionalidade de comando de voz e integrar a Cortana ao seu aplicativo usando entrada de fala ou teclado:

  1. Crie um arquivo VCD. Este é um documento XML que define todos os comandos falados que o usuário pode dizer para iniciar ações ou invocar comandos ao ativar seu aplicativo. Consulte Elementos e atributos VCD v1.2.
  2. Registre os conjuntos de comandos no arquivo VCD quando o aplicativo for iniciado.
  3. Manipule a ativação por comando de voz, a navegação no aplicativo e a execução do comando.

Dica

Pré-requisitos

Se você não estiver familiarizado com o desenvolvimento de aplicativos UWP (Plataforma Universal do Windows), dê uma olhada nestes tópicos para se familiarizar com as tecnologias discutidas aqui.

Diretrizes de experiência do usuário

Consulte as diretrizes de design da Cortana para obter informações sobre como integrar seu aplicativo à Cortana e às interações de fala para obter dicas úteis sobre como criar um aplicativo habilitado para fala útil e envolvente.

Criar uma nova solução com projeto no Visual Studio

  1. Inicie o Microsoft Visual Studio 2015.

    A página inicial do Visual Studio 2015 é exibida.

  2. No menu Arquivo, selecione Novo>Projeto.

    A caixa de diálogo Novo Projeto será exibida. O painel esquerdo da caixa de diálogo permite selecionar o tipo de modelos a serem exibidos.

  3. No painel esquerdo, expanda Modelos Instalados > > do Visual C# > Windows e escolha o grupo de modelos Universal . O painel central da caixa de diálogo exibe uma lista de modelos de projeto para aplicativos da Plataforma Universal do Windows (UWP).

  4. No painel central, selecione o modelo Aplicativo em Branco (Universal do Windows).

    O modelo de Aplicativo em Branco cria um aplicativo UWP mínimo que compila e é executado, mas não contém controles ou dados de interface do usuário. Você adiciona controles ao aplicativo ao longo deste tutorial.

  5. Na caixa de texto Nome, digite o nome do projeto. Para este exemplo, usamos "AdventureWorks".

  6. Clique em OK para criar o projeto.

    O Microsoft Visual Studio cria seu projeto e o exibe no Gerenciador de Soluções.

Adicionar ativos de imagem ao projeto e especificá-los no manifesto do aplicativo

Os aplicativos UWP podem selecionar automaticamente as imagens mais apropriadas com base em configurações específicas e recursos do dispositivo (alto contraste, pixels efetivos, localidade e assim por diante). Tudo o que você precisa fazer é fornecer as imagens e garantir que você use a convenção de nomenclatura e a organização de pastas apropriadas no projeto do aplicativo para as diferentes versões de recursos. Se você não fornecer as versões de recursos recomendadas, a acessibilidade, a localização e a qualidade da imagem poderão ser prejudicadas, dependendo das preferências, habilidades, tipo de dispositivo e localização do usuário.

Para obter mais detalhes sobre recursos de imagem para fatores de alto contraste e escala, consulte Diretrizes para ativos de bloco e ícone.

Você nomeia recursos usando qualificadores. Os qualificadores de recursos são modificadores de pasta e nome de arquivo que identificam o contexto no qual uma versão específica de um recurso deve ser usada.

A convenção de nomenclatura padrão é foldername/qualifiername-value[_qualifiername-value]/filename.qualifiername-value[_qualifiername-value].ext. Por exemplo, images/logo.scale-100_contrast-white.png, que pode ser referenciado no código usando apenas a pasta raiz e o nome do arquivo: images/logo.png. Consulte Como nomear recursos usando qualificadores.

Recomendamos que você marque o idioma padrão em arquivos de recurso de cadeia de caracteres (como en-US\resources.resw) e o fator de escala padrão em imagens (como logo.scale-100.png), mesmo que você não planeje fornecer recursos localizados ou de várias resoluções. No entanto, no mínimo, recomendamos que você forneça ativos para fatores de escala de 100, 200 e 400.

Importante

O ícone do aplicativo usado na área de título da tela da Cortana é o ícone Square44x44Logo especificado no arquivo "Package.appxmanifest".

Criar um arquivo VCD

  1. No Visual Studio, clique com o botão direito do mouse no nome do projeto primário e selecione Adicionar > Novo Item. Adicione um arquivo XML.
  2. Digite um nome para o arquivo VCD (por exemplo, "AdventureWorksCommands.xml") e clique em Adicionar.
  3. No Gerenciador de Soluções, selecione o arquivo VCD .
  4. Na janela Propriedades, defina Ação de compilação como Conteúdo e, em seguida, defina Copiar para o diretório de saída como Copiar se for mais recente.

Edite o arquivo VCD

Adicione um elemento VoiceCommands com um atributo xmlns apontando para https://schemas.microsoft.com/voicecommands/1.2.

  1. Para cada idioma compatível com seu aplicativo, crie um elemento CommandSet que contenha os comandos de voz compatíveis com seu aplicativo.

    Você pode declarar vários elementos CommandSet, cada um com um atributo xml:lang diferente para que seu aplicativo seja usado em diferentes mercados. Por exemplo, um aplicativo para os Estados Unidos pode ter um CommandSet para inglês e um CommandSet para espanhol.

    Cuidado

    Para ativar um aplicativo e iniciar uma ação usando um comando de voz, o aplicativo deve registrar um arquivo VCD que contenha um CommandSet com um idioma que corresponda ao idioma de fala selecionado pelo usuário para seu dispositivo. O idioma da fala está localizado em Configurações > Sistema > de Fala > Idioma da Fala.

  2. Adicione um elemento Command para cada comando que você deseja dar suporte. Cada comando declarado em um arquivo VCD deve incluir as seguintes informações:

    • Um atributo AppName que seu aplicativo usa para identificar o comando de voz em runtime.
    • Um elemento Example que contém uma frase que descreve como um usuário pode invocar o comando. A Cortana mostra este exemplo quando o usuário diz "O que posso dizer?", "Ajuda" ou toca em Ver mais.
    • Um elemento ListenFor que contém as palavras ou frases que seu aplicativo reconhece como um comando. Cada elemento ListenFor pode conter referências a um ou mais elementos PhraseList que contêm palavras específicas relevantes para o comando.

Observação

Os elementos ListenFor não podem ser modificados programaticamente. No entanto, os elementos PhraseList associados aos elementos ListenFor podem ser modificados programaticamente. Os aplicativos devem modificar o conteúdo do PhraseList em runtime com base no conjunto de dados gerado à medida que o usuário usa o aplicativo. Consulte Modificar dinamicamente listas de frases VCD da Cortana.

Um elemento Feedback que contém o texto para a Cortana exibir e falar quando o aplicativo é iniciado.

Um elemento Navigate indica que o comando de voz ativa o aplicativo em primeiro plano. Neste exemplo, o showTripToDestination comando é uma tarefa em primeiro plano.

Um elemento VoiceCommandService indica que o comando de voz ativa o aplicativo em segundo plano. O valor do atributo Target desse elemento deve corresponder ao valor do atributo Name do elemento uap:AppService no arquivo package.appxmanifest. Neste exemplo, os whenIsTripToDestination comandos and cancelTripToDestination são tarefas em segundo plano que especificam o nome do serviço de aplicativo como "AdventureWorksVoiceCommandService".

Para obter mais detalhes, consulte a referência de elementos e atributos VCD v1.2.

Aqui está uma parte do arquivo VCD que define os comandos de voz en-us para o aplicativo 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>

Instale os comandos VCD

Seu aplicativo deve ser executado uma vez para instalar o VCD.

Observação

Os dados de comando de voz não são preservados nas instalações do aplicativo. Para garantir que os dados de comando de voz do seu aplicativo permaneçam intactos, considere inicializar o arquivo VCD sempre que o aplicativo for iniciado ou ativado ou mantenha uma configuração que indique se o VCD está instalado no momento.

No arquivo "app.xaml.cs":

  1. Adicione a seguinte diretiva using:

    using Windows.Storage;
    
  2. Marque o método "OnLaunched" com o modificador assíncrono.

    protected async override void OnLaunched(LaunchActivatedEventArgs e)
    
  3. Chame InstallCommandDefinitionsFromStorageFileAsync no manipulador OnLaunched para registrar os comandos de voz que o sistema deve reconhecer.

No exemplo de Adventure Works, primeiro definimos um objeto StorageFile .

Em seguida, chamamos GetFileAsync para inicializá-lo com nosso arquivo "AdventureWorksCommands.xml".

Esse objeto StorageFile é então passado para 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());
}

Manipulação de ativação e execução de comandos por voz

Especifique como seu aplicativo responde às ativações de comando de voz subsequentes (depois que ele tiver sido iniciado pelo menos uma vez e os conjuntos de comandos de voz tiverem sido instalados).

  1. Confirme se seu aplicativo foi ativado por um comando de voz.

    Substitua o evento Application.OnActivated e verifique se IActivatedEventArgs.Kind é o VoiceCommand.

  2. Determine o nome do comando e o que foi falado.

    Obtenha uma referência a um objeto VoiceCommandActivatedEventArgs do IActivatedEventArgs e consulte a propriedade Result para um objeto SpeechRecognitionResult.

    Para determinar o que o usuário disse, verifique o valor de Text ou as propriedades semânticas da frase reconhecida no dicionário SpeechRecognitionSemanticInterpretation .

  3. Execute a ação apropriada em seu aplicativo, como navegar até a página desejada.

Para este exemplo, nos referimos ao VCD na Etapa 3: Editar o arquivo VCD.

Depois de obtermos o resultado do reconhecimento de fala para o comando de voz, obteremos o nome do comando do primeiro valor na matriz RulePath . Como o arquivo VCD definiu mais de um comando de voz possível, precisamos comparar o valor com os nomes dos comandos no VCD e tomar a ação apropriada.

A ação mais comum que um aplicativo pode executar é navegar até uma página com conteúdo relevante para o contexto do comando de voz. Para este exemplo, navegamos até uma página do TripPage e passamos o valor do comando de voz, como o comando foi inserido e a frase de "destino" reconhecida (se aplicável). Como alternativa, o aplicativo pode enviar um parâmetro de navegação para o SpeechRecognitionResult ao navegar até a página.

Você pode descobrir se o comando de voz que iniciou seu aplicativo foi realmente falado ou se foi digitado como texto, no dicionário SpeechRecognitionSemanticInterpretation.Properties usando a chave commandMode. O valor dessa chave será "voice" ou "text". Se o valor da chave for "voz", considere usar a síntese de fala (Windows.Media.SpeechSynthesis) em seu aplicativo para fornecer ao usuário comentários falados.

Use o SpeechRecognitionSemanticInterpretation.Properties para descobrir o conteúdo falado nas restrições PhraseList ou PhraseTopic de um elemento ListenFor . A chave do dicionário é o valor do atributo Label do elemento PhraseList ou PhraseTopic . Aqui, mostramos como acessar o valor da 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 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();
}