Поделиться через


Активация приложения переднего плана с помощью голосовых команд с помощью Кортаны

Предупреждение

Эта функция больше не поддерживается в обновлении Windows 10 мая 2020 г. (версия 2004, имя кода "20H1").

См. статью Кортана в Microsoft 365 о том, как Кортана преобразует современные возможности повышения производительности.

Помимо использования голосовых команд в Кортаны для доступа к системным функциям, вы также можете расширить Кортана с функциями и функциями из приложения. С помощью голосовых команд приложение можно активировать на переднем плане и действие или команду, выполняемую в приложении.

Когда приложение обрабатывает голосовую команду на переднем плане, она принимает фокус и Кортана закрывается. Если вы предпочитаете, вы можете активировать приложение и выполнить команду в качестве фоновой задачи. В этом случае Кортана сохраняет фокус, и ваше приложение возвращает все отзывы и результаты с помощью холста Кортаны и голоса Кортаны .

Голосовые команды, требующие дополнительного контекста или ввода пользователем (например, отправка сообщения конкретному контакту), лучше всего обрабатываются в приложении переднего плана, а базовые команды (например, перечисление предстоящих поездок) можно обрабатывать в Кортаны через фоновое приложение.

Если вы хотите активировать приложение в фоновом режиме с помощью голосовых команд, см. статью "Активация фонового приложения в Кортаны" с помощью голосовых команд.

Примечание.

Голосовая команда — это одно высказывание с определенным намерением, определенным в файле определения голосовой команды (VCD), направленное на установленное приложение через Кортана.

Файл VCD определяет одну или несколько голосовых команд с уникальным намерением.

Определения голосовых команд могут отличаться в сложности. Они могут поддерживать что-нибудь из одного ограниченного речевых фрагментов в коллекцию более гибких, речевых фрагментов естественного языка, все обозначающие одно и то же намерение.

Чтобы продемонстрировать функции приложения переднего плана, мы будем использовать приложение планирования и управления поездками с именем Adventure Works из примера голосовой команды Кортаны.

Чтобы создать новую поездку Adventure Works без Кортаны, пользователь запустит приложение и перейдите на страницу "Новая поездка ". Чтобы просмотреть существующую поездку, пользователь запустит приложение, перейдите на страницу предстоящих поездок и выберите поездку.

Используя голосовые команды через Кортана, пользователь может просто сказать: "Adventure Works добавьте поездку" или "Добавить поездку в Adventure Works", чтобы запустить приложение и перейти на страницу "Новая поездка ". В свою очередь, сказав: "Adventure Works, показать мою поездку в Лондон" запустит приложение и перейдите на страницу сведений о поездке, показанную здесь.

Снимок экрана: запуск приложения переднего плана Кортаны

Ниже приведены основные шаги по добавлению функций голосовой команды и интеграции Кортаны с приложением с помощью ввода речи или клавиатуры:

  1. Создайте VCD-файл. Это XML-документ, который определяет все произнесенные команды, которые пользователь может сказать, инициировать действия или вызывать команды при активации приложения. См . элементы и атрибуты VCD версии 1.2.
  2. Зарегистрируйте наборы команд в VCD-файле при запуске приложения.
  3. Обработайте команду активации по голосовой связи, навигацию в приложении и выполнение команды.

Совет

Необходимые условия

Если вы не знакомы с разработкой приложений универсальная платформа Windows (UWP), ознакомьтесь с этими разделами, чтобы ознакомиться с технологиями, описанными здесь.

Рекомендации по работе с пользователем

Ознакомьтесь с рекомендациями по проектированию Кортаны, чтобы узнать, как интегрировать приложение с Кортаной и речью , чтобы получить полезные советы по проектированию полезного и привлекательного приложения с поддержкой речи.

Создание решения с проектом в Visual Studio

  1. Запустите Microsoft Visual Studio 2015.

    Откроется начальная страница Visual Studio 2015.

  2. В меню Файл выберите Создать>Проект.

    Откроется диалоговое окно Создание проекта. В левой области диалогового окна можно выбрать тип шаблонов для отображения.

  3. В левой области разверните установленные > шаблоны Visual C# > Windows, а затем выберите группу универсальных шаблонов>. В центральной области диалогового окна отображается список шаблонов проектов для приложений универсальная платформа Windows (UWP).

  4. В центральной области выберите шаблон пустого приложения (универсального приложения Windows).

    Шаблон пустого приложения создает минимальное приложение UWP, которое компилирует и выполняется, но не содержит элементов управления пользовательского интерфейса или данных. Элементы управления добавляются в приложение в рамках этого руководства.

  5. В текстовом поле "Имя" введите имя проекта. В этом примере используется AdventureWorks.

  6. Нажмите кнопку ОК, чтобы создать проект.

    Microsoft Visual Studio создает проект и отображает его в Обозреватель решений.

Добавление ресурсов изображений в проект и их указание в манифесте приложения

Приложения UWP могут автоматически выбирать наиболее подходящие изображения на основе определенных параметров и возможностей устройства (высокая контрастность, эффективные пиксели, языковой стандарт и т. д.). Все, что вам нужно сделать, — предоставить образы и убедиться, что для разных версий ресурсов используется соответствующее соглашение об именовании и организация папок в проекте приложения. Если вы не предоставляете рекомендуемые версии ресурсов, специальные возможности, локализацию и качество изображения, может страдать в зависимости от настроек пользователя, возможностей, типа устройства и расположения.

Дополнительные сведения о ресурсах изображений для факторов высокой контрастности и масштабирования см. в рекомендациях по ресурсам плиток и значков.

Вы именуете ресурсы с помощью квалификаторов. Квалификаторы ресурсов — это модификаторы папок и имени файла, определяющие контекст, в котором должна использоваться определенная версия ресурса.

Стандартное соглашение об именовании .foldername/qualifiername-value[_qualifiername-value]/filename.qualifiername-value[_qualifiername-value].ext Например, images/logo.scale-100_contrast-white.pngкоторый можно ссылаться в коде, используя только корневую папку и имя файла: images/logo.png Узнайте , как именовать ресурсы с помощью квалификаторов.

Мы рекомендуем пометить язык по умолчанию в файлах ресурсов строки (например en-US\resources.resw) и коэффициент масштабирования по умолчанию на изображениях (например logo.scale-100.png, если в настоящее время не планируется предоставлять локализованные или несколько ресурсов разрешения). Однако рекомендуется предоставить ресурсы для 100, 200 и 400 коэффициентов масштабирования.

Внимание

Значок приложения, используемый в области заголовка холста Кортаны , — это значок Square44x44Logo, указанный в файле Package.appxmanifest.

Создание VCD-файла

  1. В Visual Studio щелкните правой кнопкой мыши имя основного проекта, выберите "Добавить > новый элемент". Добавьте XML-файл.
  2. Введите имя VCD-файла (например, "AdventureWorksCommands.xml") и нажмите кнопку "Добавить".
  3. В Обозреватель решений выберите VCD-файл.
  4. В окне "Свойства" задайте для действия "Сборка" значение Content, а затем задайте для копирования выходной каталог, чтобы Копировать, если это еще больше.

Изменение файла VCD

Добавьте элемент VoiceCommands с атрибутом xmlns, указывающим на https://schemas.microsoft.com/voicecommands/1.2.

  1. Для каждого языка, поддерживаемого приложением, создайте элемент CommandSet , содержащий голосовые команды, поддерживаемые приложением.

    Можно объявить несколько элементов CommandSet, каждый из которых имеет другой атрибут xml:lang, чтобы приложение использовалось на разных рынках. Например, приложение для США может иметь набор команд для английского языка и набор команд для испанского языка.

    Внимание

    Чтобы активировать приложение и инициировать действие с помощью голосовой команды, приложение должно зарегистрировать VCD-файл, содержащий набор команд с языком, который соответствует языку речи, выбранному пользователем для своего устройства. Язык речи находится в разделе "Параметры > языка > распознавания речи".>

  2. Добавьте элемент Command для каждой команды, которую требуется поддерживать. Каждая команда , объявленная в VCD-файле , должна содержать следующие сведения:

    • Атрибут AppName , который приложение использует для идентификации голосовой команды во время выполнения.
    • Пример элемента, содержащего фразу, описывающую, как пользователь может вызвать команду. Кортана показывает этот пример, когда пользователь говорит: "Что можно сказать?", "Справка" или нажмите кнопку "Просмотреть больше".
    • Элемент ListenFor , содержащий слова или фразы, которые приложение распознает как команду. Каждый элемент ListenFor может содержать ссылки на один или несколько элементов PhraseList , содержащих определенные слова, относящиеся к команде.

Примечание.

Элементы ListenFor нельзя изменить программным способом. Однако элементы PhraseList, связанные с элементами ListenFor, могут быть программно изменены. Приложения должны изменять содержимое Объекта PhraseList во время выполнения на основе набора данных, созданного в качестве пользователя, использующего приложение. См . динамические изменения списков фраз Кортаны VCD.

Элемент Feedback, содержащий текст Кортаны для отображения и выступления при запуске приложения.

Элемент Navigate указывает, что голосовая команда активирует приложение на переднем плане. В этом примере showTripToDestination команда является задачей переднего плана.

Элемент VoiceCommandService указывает, что голосовая команда активирует приложение в фоновом режиме. Значение атрибута Target этого элемента должно соответствовать значению атрибута Name элемента uap:AppService в файле package.appxmanifest. В этом примере команды — это фоновые задачи, whenIsTripToDestination cancelTripToDestination которые указывают имя службы приложений как AdventureWorksVoiceCommandService.

Дополнительные сведения см. в справочнике по элементам и атрибутам VCD версии 1.2 .

Ниже приведена часть VCD-файла, который определяет голосовые команды en-us для приложения 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>

Установка команд VCD

Приложение должно запуститься один раз, чтобы установить VCD.

Примечание.

Данные голосовой команды не сохраняются во всех установках приложений. Чтобы убедиться, что данные голосовой команды для приложения остаются неизменными, рассмотрите возможность инициализации файла VCD при каждом запуске или активации приложения или сохранении параметра, указывающего, установлен ли VCD в данный момент.

В файле app.xaml.cs:

  1. Добавьте следующую директиву using:

    using Windows.Storage;
    
  2. Пометьте метод OnLaunched с помощью асинхронного модификатора.

    protected async override void OnLaunched(LaunchActivatedEventArgs e)
    
  3. Вызовите InstallCommandDefinitionsFromStorageFileAsync в обработчике OnLaunched, чтобы зарегистрировать голосовые команды, которые система должна распознать.

В примере Adventure Works сначала мы определим объект StorageFile .

Затем мы вызываем GetFileAsync , чтобы инициализировать его с помощью файла "AdventureWorksCommands.xml".

Затем этот объект StorageFile передается в 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());
}

Обработка активации и выполнение голосовых команд

Укажите способ реагирования приложения на последующие активации голосовой команды (после запуска по крайней мере один раз и установки наборов голосовых команд).

  1. Убедитесь, что приложение активировано голосовой командой.

    Переопределите событие Application.OnActivated и проверьте, является ли IActivatedEventArgs.Тип VoiceCommand.

  2. Определите имя команды и то, что было произнесено.

    Получите ссылку на объект VoiceCommandActivatedEventArgs из IActivatedEventArgs и запросите свойство Result для объекта SpeechRecognitionResult.

    Чтобы определить, что сказал пользователь, проверьте значение текста или семантические свойства распознанной фразы в словаре SpeechRecognitionSemanticInterpretation.

  3. Выполните соответствующее действие в приложении, например переход на нужную страницу.

В этом примере мы вернемся к VCD на шаге 3. Изменение VCD-файла.

Получив результат распознавания речи для голосовой команды, мы получим имя команды из первого значения в массиве RulePath . Поскольку VCD-файл определил несколько возможных голосовых команд, необходимо сравнить значение с именами команд в VCD и выполнить соответствующее действие.

Наиболее распространенным действием, которое может предпринять приложение, является переход на страницу с содержимым, соответствующим контексту голосовой команды. В этом примере мы переходим на страницу TripPage и передаваем значение голосовой команды, способом ввода команды и распознанной фразой "назначение" (если применимо). Кроме того, приложение может отправить параметр навигации в SpeechRecognitionResult при переходе на страницу.

Вы можете узнать, говорила ли голосовая команда, запущенная приложением, или ли она была введена в виде текста, из словаря SpeechRecognitionSemanticInterpretation.Properties с помощью ключа commandMode . Значение этого ключа будет либо голосом, либо текстом. Если значение ключа — "голос", рассмотрите возможность использования синтеза речи (Windows.Media.SpeechSynthesis) в приложении, чтобы предоставить пользователю речевой отзыв.

Используйте speechRecognitionSemanticInterpretation.Properties, чтобы узнать содержимое, произнесенное в ограничениях PhraseList или PhraseTopic элемента ListenFor. Ключ словаря — это значение атрибута Label элемента PhraseList или PhraseTopic. Здесь мы покажем, как получить доступ к значению фразы {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();
}