Windows 10 по 10. Выпуск #3. Использование Кортаны для взаимодействия с пользователями
В этом выпуске нашей серии статей Windows 10 по 10 мы расскажем, о том, как расширить опыт взаимодействия с вашим приложением в Windows 10 на те моменты, когда приложение даже не запущено. Тема прошлой статьи, — живые плитки и уведомления, — раскрывала один из возможных путей, сегодня мы посмотрим, как для этой задачи использовать Кортану, персональную помощницу в Windows 10. В качестве основы для приводимых фрагментов кода мы будем использовать пример AdventureWorks, доступный на GitHub.
В данной статье, мы постараемся разобраться, что же собой представляет Кортана, как сделать так, чтобы она поддержала осмысленное взаимодействие с вашими пользователями, что необходимо сделать для интеграции Кортаны в приложение, и далее рассмотрим два способа (из многих), как ваше приложение может взаимодействовать с пользователями в зависимости от сценария.
Что собой представляет Кортана?
Одна из самых интересных возможностей Windows 10 – это персональная помощница Кортана, ранее доступная в Windows Phone. Кортана – это ключевой элемент для общения с Windows 10 на естественном языке. С помощью Кортаны пользователи могут взаимодействовать с Windows (как с самой ОС, так и с вашими приложениями), используя привычный голосовой способ общения с другими людьми.
К примеру, подумайте о вопросах, ответы на которые может дать только ваше приложение и которые человек мог бы задать голосом Кортане: «когда моя следующая поездка?», «найди радиостанцию», «доступен ли Джек?». В свою очередь ваше приложение может ответить на такие вопросы, предоставив ответ Кортане для произнесения и отображения.
Или представьте себе задачи, которые человек мог бы попросить Кортану сделать в контексте вашего приложения: «отмени мою поездку в Лондон», «запомни эту радиостанцию», «напиши Джеку, что я буду позже».
Голосовые команды могут предоставить быстрый доступ к информации внутри приложения. Это своего рода глубокие ссылки в вашем приложении. Также как вы сегодня создаете плитки, чтобы предоставить быстрый доступ к содержимому вашего приложения, вы можете использовать голосовые команды, как быстрый способ «заглянуть» внутрь приложения. И аналогично тому, как вы делаете возможным закрепить ближайшую поездку, созданную в приложении, на экране Пуск, вы также можете разрешить пользователю использовать голосовую команду для Кортаны для доступа к той же самой поездке. Такая возможность сделает ваших пользователей более продуктивными, а взаимодействие с приложением более доступным.
Расширяя Кортану, вы можете улучшить взаимодействие с вашими пользователями и порадовать их возможностью совершать действия быстрыми голосовыми командами. Впрочем, так как это статья не о пользовательских возможностях Кортаны, давайте разберемся, как с ней интегрироваться.
Хей, Кортана, давай поговорим
Так как взаимодействие с Кортаной опирается на голос, то создаваемый опыт взаимодействия должен быть наиболее приближен к естественному диалогу. На MSDN вы найдете общее руководство по дизайну для Кортаны с рекомендациями по построению опыта взаимодействия. Для достижения наилучшего результата, советуем следовать следующим принципам: эффективность, релевантность, ясность и доверие.
Что они означают на практике?
- Эффективность: меньше – это лучше. Будьте кратки и старайтесь сократить количество слов, не теряя при этом смысла.
- Релевантность: не отклоняйтесь от темы. Если я попросил добавить мою любимую песню ABBA в плейлист, не надо мне заодно сообщать о низком заряде батареи. Лучше подтвердите, что через мгновение я смогу насладиться ABBA. :)
- Ясность: диалог должен соответствовать аудитории. Используйте нормальный повседневный язык вместо жаргона, понятного узкой группе людей.
- Доверие: ответы должны аккуратно отображать, что происходит, и уважать предпочтения пользователей. Если ваше приложение не выполнило задачу, не говорите, что сделали это. Также не стоит возвращать для воспроизведения фразы, которые с точки зрения пользователя не стоило бы произносить вслух.
Заодно вам стоит подумать о локализации взаимодействия с Кортаной, особенно, если вы уже локализовали остальную часть приложения и сделали его глобально доступным. Кортана на сегодня доступна в США, Великобритании, Китае, Франции, Италии, Германии и Испании (анонс про расширение на дополнительные рынки). Локализация поможет вам побудить пользователей чаще использовать Кортану для взаимодействия с вашим приложением.
Учим Кортану, на что нужно отвечать
Кортана использует файл с определениями голосовых команд (Voice Command Definition, VCD), чтобы понять, как именно пользователь может взаимодействовать с вашим приложением, используя голос. Данный файл может быть готовым XML-файлом или генерироваться из кода (вам нужно будет заполнить набор команд в VCD-файле при первом запуске). Ниже приведен пример VCD-файла:
<?xml version="1.0" encoding="utf-8"?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.1">
<CommandSet xml:lang="en-us" Name="AdventureWorksCommandSet_en-us">
<CommandPrefix> Adventure Works, </CommandPrefix>
<Example> Show trip to London </Example>
<Command Name="showTripToDestination">
<Example> show trip to London </Example>
<ListenFor RequireAppName="BeforeOrAfterPhrase"> show trip to {destination} </ListenFor>
<Feedback> Showing trip to {destination} </Feedback>
<Navigate/>
</Command>
<PhraseList Label="destination">
<Item> London </Item>
<Item> Dallas </Item>
</PhraseList>
</CommandSet>
<!-- Other CommandSets for other languages -->
</VoiceCommands>
При активации приложения из события запуска приложения OnLaunched вам нужно вызвать метод InstallCommandSetsFromStorageFileAsync, чтобы зарегистрировать команды, которые Кортана должна распознавать. Имейте в виду, что если устройство восстанавливается из бекапа и ваше приложение переустанавливается, то голосовые команды не восстанавливаются автоматически. Чтобы убедиться, что данные с описанием голосовых команд остаются нетронутыми, вы можете инициализировать VCD-файл при каждом запуске или активации приложения. Но лучше хранить настройку, указывающую, установлен ли уже VCD-файл, и проверять именно этот параметр. Ниже простой пример кода, показывающий, как установить VCD-файл из приложения:
var storageFile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///CortanaVcd.xml"));
await Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager.InstallCommandSetsFromStorageFileAsync(storageFile);
Добавляем динамичность
Теперь, когда вы знакомы с основами, мы можем добавить немного разнообразия во время выполнения. Ниже пример динамичного переключения VCD-файла, который нужно загрузить:
private Windows.ApplicationModel.VoiceCommands.VoiceCommnadDefinition.VoiceCommandSet commandSetEnUs;
if (Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager.InstalledCommandSets.TryGetValue("AdventureWorksCommandSet_en-us", out commandSetEnUs))
{
// this code will fully replace the destination list
await commandSetEnUs.SetPhraseListAsync("destination", new string[] {"Chicago", "Seattle", "New York", "Phoenix"});
}
Как мое приложение будет взаимодействовать с Кортаной?
Есть несколько способов, как ваше приложение может общаться с Кортаной. Вот три наиболее типичных пути:
- Запуск приложения из Кортаны. Помимо того, чтобы просто запустить приложение, вы также можете указать «глубокую» ссылку или команду для выполнения внутри приложения.
- Простое взаимодействие внутри интерфейса Кортаны (обычно это сохранение/запрос данных через фоновый процесс).
- Взаимодействие между пользователем и приложение внутри Кортаны.
Запуск приложения
Если у вас сложная задача и вы хотите, чтобы пользователь перешел напрямую в ваше приложение, использовать для этого Кортану – отличная идея! Так как некоторые сложные задачи в реальности могут быть быстрее и аккуратнее выполнены через голосовые команды, это может действительно помочь пользователям.
protected override void OnActivated(IActivatedEventArgs e)
{
// Was the app activated by a voice command?
if (e.Kind != Windows.ApplicationModel.Activation.ActivationKind.VoiceCommand)
{
return;
}
var commandArgs = e as Windows.ApplicationModel.Activation.VoiceCommandActivatedEventArgs;
var navigationParameterString = "";
Windows.ApplicationModel.VoiceCommands.VoiceCommand.SpeechRecognitionResult speechRecognitionResult = commandArgs.Result;
// Get the name of the voice command and the text spoken
string voiceCommandName = speechRecognitionResult.RulePath[0];
string textSpoken = speechRecognitionResult.Text;
// The commandMode is either "voice" or "text", and it indicates how the voice command was entered by the user.
// Apps should respect "text" mode by providing feedback in a silent form.
string commandMode = this.SemanticInterpretation("commandMode", speechRecognitionResult);
switch (voiceCommandName)
{
case "showTripToDestination":
// Access the value of the {destination} phrase in the voice command
string destination = speechRecognitionResult.SemanticInterpretation.Properties["destination"][0];
// Create a navigation parameter string to pass to the page
navigationParameterString = string.Format("{0}|{1}|{2}|{3}",
voiceCommandName, commandMode, textSpoken, destination);
// Set the page where to navigate for this voice command
navigateToPageType = typeof(TripPage);
break;
default:
// There is no match for the voice command name. Navigate to MainPage
navigateToPageType = typeof(MainPage);
break;
}
if (this.rootFrame == null)
{
// App needs to create a new Frame, not shown
}
if (!this.rootFrame.Navigate(navigateToPageType, navigationParameterString))
{
throw new Exception("Failed to create voice command page");
}
}
Простое взаимодействие внутри Кортаны для сохранения или запроса данных
Теперь, когда к Кортане подключен ваш VCD-файл, и вы знаете, как осуществлять базовое взаимодействие, давайте посмотрим, как делать более сложные операции. К примеру, вы хотите, чтобы Кортана показала пользователю некоторые данные или наоборот их сохранила. На сайте MSDN есть подробная инструкция по настройке фоновых задач для Кортаны. Вот краткое резюме:
- Создайте проект Windows Runtime Component в вашем решении
- Создайте новый класс, реализующий интерфейс IBackgroundTask, который будет работать как сервис приложения
- В манифейсте вашего UWP-приложения (Package.appxmanifest) добавьте новое расширение для созданного сервиса. Этот шаг подробно описан в MSDN.
Ниже приведен пример фрагмента файла Package.appxmanifest:
<Package>
<Applications>
<Application>
<Extensions>
<Extension Category="windows.appService"
EntryPoint=
"AdventureWorks.VoiceCommands.AdventureWorksVoiceCommandService">
<AppService Name="AdventureWorksVoiceCommandService"/>
</Extension>
</Extensions>
<Application>
<Applications>
</Package>
После запуска фоновый сервис приложения имеет 0.5 секунды на вызов метода ReportSuccessAsync. Кортана использует данные, предоставленные приложением, для демонстрации и произнесения голосом ответа, указанного в VCD-файле. Если приложение тратит на возврат результата больше, чем полсекунды, Кортана вставит промежуточный экран, как показано ниже. Кортана отображает временный экран до тех пор, пока приложение не вернет результат через ReportSuccessAsync, но не более 5 секунд. Если приложение не вызвало метод ReportSuccessAsync или любой из методов VoiceCommandServiceConnection для предоставления информации Кортане, пользователь получит сообщение об ошибке и вызов сервиса будет отменен.
Вот простой пример кода для реализации IBackgroundTask в сервисе приложения:
using Windows.ApplicationModel.Background;
namespace AdventureWorks.VoiceCommands
{
public sealed class AdventureWorksVoiceCommandService : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
//
// TODO: Insert code
//
_deferral.Complete();
}
}
}
Взаимодействие внутри Кортаны
К этому моменту вы познакомились с основами и готовы реализовать еще более плотное взаимодействие с Кортаной. Приложение может запросить разные типы экрана для поддержки той или иной функциональности:
- Удачное завершение
- Промежуточный
- Прогресс
- Подтверждение
- Неопределенность
- Ошибка
Давайте рассмотрим подробнее один из этих сценариев: неопределенность. Иногда случается так, что у вашего приложения есть несколько вариантов, которые оно может вернуть. В таких ситуациях вам нужно разрешить неуверенность, что же делать дальше. Например, если пользователь выбирал музыку и нужно было решить, что играть дальше: ABBA, Nickelback или White Snake, Кортана может помочь сделать выбор. Фрагмент кода ниже из примера Adventure Works показывает, как разрешить появившуюся в рамках сервиса приложения неопределенность:
// Create a VoiceCommandUserMessage for the initial question.
var userPrompt = new VoiceCommandUserMessage();
userPrompt.DisplayMessage = "Which one do you want to cancel?";
userPrompt.SpokenMessage = "Which Chicago trip do you wanna cancel?";
// Create a VoiceCommandUserMessage for the second question,
// in case Cortana needs to reprompt.
var userReprompt = new VoiceCommandUserMessage();
userReprompt.DisplayMessage = “Which one did you want to cancel?”;
userReprompt.SpokenMessage = "Which one did you wanna to cancel?";
// Create the list of content tiles to show the selection items.
var destinationsContentTiles = new List<VoiceCommandContentTile>();
// create your VoiceCommandContentTiles
for(int i=0; i < 5; i++)
{
var destinationTile = new VoiceCommandContentTile();
destinationTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
// The AppContext is optional.
// Replace this value with something specific to your app.
destinationTile.AppContext = "id_Vegas_00" + i;
destinationTile.Title = "Tech Conference";
destinationTile.TextLine1 = "May " + i + "th";
destinationsContentTiles.Add(destinationTile);
}
// Create the disambiguation response.
var response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt, destinationsContentTiles);
// Request that Cortana shows the disambiguation screen.
var voiceCommandDisambiguationResult = await voiceServiceConnection.RequestDisambiguationAsync(response);
if (voiceCommandDisambiguationResult != null)
{
// Use the voiceCommandDisambiguationResult.SelectedItem to take action.
// Call Cortana to present the next screen in .5 seconds
// and avoid a transition screen.
}
Подводим итоги
Мы надеемся, что теперь вы лучше понимаете, насколько легко в ваше приложение можно добавить интеграцию с Кортаной и тем самым улучшить опыт взаимодействия для ваших пользователей. От простого запуска приложения и вплоть до сложных моделей взаимодействия даже без запуска приложения – во всех случаях Кортана действительно может оказаться полезной. Чтобы воспользоваться преимуществами интеграции с Кортаной, вы можете начать с самого простого – добавить новый способ работы с глубокими ссылками в вашем приложении.
Если вы чувствуете, что работа с Кортаной на практике может добавить ценность вашему приложению, не стесняйтесь это реализовать. Как только вы обновите свое приложение, не забудьте заявить о себе в программе DVLUP в номинации “Adding Cortana to your app”, чтобы получить очки и XP за обновление приложения. Расскажите нам, что вы сделали, через твиттер @WindowsDev с хештегом #Win10x10 – мы будем рады узнать, что разработчики создают под Windows.
Дополнительные материалы
Ниже мы приводим несколько ссылок с полезной дополнительной информацией о расширении Кортаны: