在现代技术环境中,通过个人助理完成工作变得越来越普遍。无论是Windows的Cortana、iOS的Siri还是Android的Google Now,这些个人助理都能帮助用户快速完成任务。今天,将重点介绍Cortana,并展示如何将其集成到应用程序中。Cortana最初是随Windows Phone 8.1推出的,现在也可用于运行Windows 10操作系统的设备。在Windows 10设备上,用户可以通过Cortana执行任务,并且任务结果会显示在Cortana画布上。此外,用户还可以通过在画布上输入来完成任务,以保持隐私,或者避免在公共场合大声呼唤Cortana。用户可以通过简单地说“嘿Cortana”与Cortana进行交互,并呈现Cortana画布。
可以使用Cortana在前台运行应用程序,然后使用应用程序进行操作。如果使用Cortana在前台运行应用程序,那么Cortana能做的并不多。但是,当使用Cortana在后台运行应用程序并通过Cortana画布与应用程序交互时,乐趣才真正开始。让来实现这一点。创建了一个简单的待办事项应用程序。可以从文章底部提供的链接中获取应用程序的源代码。以下是应用程序的预览:
可以添加待办事项,检查它们是否完成,也可以从应用程序中永久删除它们。想象一下,使用Cortana在不运行应用程序的情况下获取待办事项,只需说“嘿Cortana,简单待办事项,显示待办任务。”
要使应用程序在后台运行,需要一个Windows运行时组件。添加自己的类并实现IBackgroundTask
接口。它有一个Run
方法,当应用程序在后台激活时,该方法将被运行。以下是VoiceCommandService
类,它实现了IBackgroundTask
接口。
public sealed class VoiceCommandService : IBackgroundTask
{
private BackgroundTaskDeferral _deferral;
private VoiceCommandServiceConnection _voiceServiceConnection;
public async void Run(IBackgroundTaskInstance taskInstance)
{
var triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
if (triggerDetails?.Name == "SimpleTodoVoiceCommandService")
{
_deferral = taskInstance.GetDeferral();
var cancelledTokenSource = new CancellationTokenSource();
_voiceServiceConnection = VoiceCommandServiceConnection.FromAppServiceTriggerDetails(triggerDetails);
var voiceCommand = await _voiceServiceConnection.GetVoiceCommandAsync();
switch (voiceCommand.CommandName)
{
case "todoBackgroundCommandList":
var command = voiceCommand.SpeechRecognitionResult.SemanticInterpretation.Properties["command"][0];
if (command == "pending")
await ShowPendingTasks();
break;
default:
LaunchAppInForeground();
break;
}
taskInstance.Canceled += (s, e) =>
{
cancelledTokenSource.Cancel();
_deferral.Complete();
};
_voiceServiceConnection.VoiceCommandCompleted += (sender, args) =>
{
cancelledTokenSource.Cancel();
_deferral.Complete();
};
}
}
}
源代码包含了其余的代码(请从上面的链接下载)。在这里,获取激活后台任务的语音命令。然后,将命令与语音命令定义文件中定义的PhraseList
进行匹配。由于应用程序能够显示待办任务,命令应该与PhraseList
中的第一个命令匹配。以下是语音命令定义文件:
<?xml version="1.0" encoding="utf-8"?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.2">
<CommandSet xml:lang="en-us" Name="MySimpleTodoCommandSet_en-us">
<CommandPrefix>
My Simple To do
</CommandPrefix>
<Example>
My Simple To do, show pending tasks
</Example>
<Command Name="todoBackgroundCommandList">
<Example>
show pending tasks
</Example>
<ListenFor>
{command} task[s]
</ListenFor>
<Feedback>
Executing specific command
</Feedback>
<VoiceCommandService Target="SimpleTodoVoiceCommandService" />
</Command>
<PhraseList Label="command">
<Item>
pending
</Item>
</PhraseList>
</CommandSet>
</VoiceCommands>
在这里,在命令前缀节点中定义了应用程序标识符,Cortana将通过它识别应用程序。例如,“嘿Cortana,打开简单待办事项”将打开应用程序在前台。此外,可以在语音命令定义文件中拥有多个Command
节点,每个节点都有一个ListenFor
节点。在该节点中,放置期望的命令的占位符。这些占位符将被PhraseList
中匹配的值替换。还可以定义类似的CommandSet
并设置用户可以与Cortana交互的CommandSet
的语言。请记住,Cortana并不支持所有语言。因此,如果设置的语言不受支持,应用程序可能无法给提供想要的确切结果。
现在,将组件库项目的引用添加到主Windows应用程序项目中。接下来,需要在App.xaml.cs
类中注册语音命令定义,使用以下简单代码。如果需要在应用程序中进行深度链接,需要覆盖OnActivated
方法。所有这些都可以在上面的源代码中找到。
private async Task RegisterVoiceCommands()
{
var storageFile = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///MySimpleTodoCommands.xml"));
await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(storageFile);
}