微软推出小娜已经有一段时间了,最近恰好在研究其用法,就随便写点记录一下自己的心得。
在研究时参考了@王博_Nick的博客:http://www.cnblogs.com/sonic1abc/p/3868729.html,在此先表示感谢。
闲话不多说,让我们开始吧。
要将语音命令功能添加到应用中需要三个步骤:
1. 创建语音命令定义 (VCD) 文件。这是一个 XML 文档,可以定义在激活应用时用户可说出以启动操作的所有语音命令。
首先向项目中添加一个新的VCD文件,
创建的新文件如下:
以下对各个标签稍作说明:
VoiceCommands是VCD文件的开头,不可缺少。新建的VCD文件默认为Windows Phone 8.0的模板,若要适用于Cortana,需把VoiceCommands后的1.0改为1.1。
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.1">
改为1.1后将不能定义PhraseList标签,取而代之的是PhraseTopic。相比之下,PhraseTopic更为灵活,它可以表示用户所说的任何内容,而PhraseList只能表示Item中列举的内容。
CommandSet表示命令集,并定义了命令的语言。要支持中文命令,需修改xml:lang属性为zh-CN。
<CommandSet xml:lang="zh-CN">
CommandPrefix表示命令前缀,也就是对Cortana喊出命令之前要先喊这个词,除了喊前缀之外,也可以直接喊应用的名字。CommandPrefix在文件中是唯一的。如应用名叫Application,CommandPrefix的值为App,就可以对Cortana喊: Application(App) xxx命令。
Example里是写给用户的提示信息,也就是告诉用户应用接受哪些语音命令。Cortana中的提示会把CommandSet和Command下的Example进行组合显示。
以微信为例:
Command表示各个具体语音命令,ListenFor中指定命令的格式,如: [来] 玩等级 {level} [的游戏]。中括号中的内容是可选的命令,可喊可不喊,Cortana自动识别;大括号中的内容表示应用需进行处理的内容,且里面的变量名需要被定义为PhraseTopic。
Feedback表示Cortana打开应用前会播放的语音内容,如果不想听的话可以用符号来代替...Navigate表示导航到应用中的页面名称,也就是接收到该条命令后Cortana会直接打开应用的对应页面。
<Command Name="Search"> <Example>搜索xx</Example> <ListenFor>搜[索] {keyword} </ListenFor> <ListenFor>查找 {keyword} </ListenFor> <ListenFor>查 {keyword} </ListenFor> <Feedback>...</Feedback> <Navigate Target="SearchPage.xaml"/> </Command> <PhraseTopic Label="keyword" Scenario="Search"> </PhraseTopic>
2. 将代码添加到你的应用以在带有电话语音功能的 VCD 文件中注册命令集。
可以在应用程序启动时向系统注册VCD文件,注册的方法也很简单。如果你的应用想同时支持8.0和8.1,就需要判断系统版本,来加载不同的VCD文件。
1 private const string Wp81VcdPath = "ms-appx:///VoiceCommandDefinition81.xml"; 2 private const string Wp80VcdPath = "ms-appx:///VoiceCommandDefinition80.xml"; 3 4 public async void RegisterVcd() 5 { 6 var using81OrAbove = ((Environment.OSVersion.Version.Major >= 8) 7 && (Environment.OSVersion.Version.Minor >= 10)); 8 var vcdPath = using81OrAbove ? Wp81VcdPath : Wp80VcdPath; 9 10 try 11 { 12 //向系统注册VCD文件 13 await VoiceCommandService.InstallCommandSetsFromFileAsync(new Uri(vcdPath)); 14 } 15 catch (Exception ex) 16 { 17 Debug.WriteLine(ex.HResult + ex.Message); 18 } 19 }
3. 将代码添加到应用以处理语音命令激活、导航并执行该命令。
应用通过Cortana启动时,页面的NavigationContext属性中含有叫做“voiceCommandName”的参数,该参数的值对应VCD文件中定义的Command标签的Name属性。然后根据不同的命令做出不同的处理。
我自己的做法是封装一个语音处理的帮助类,然后通过发出不同的事件。
/// <summary> /// 语音指令的处理方法,在监听语音命令事件后调用,若不是通过语音命令启动程序,则会向系统注册语音命令文件(VCD file) /// </summary> /// <param name="context">调用该方法时所在页面NavigationContext</param> public static void CommandProcess(NavigationContext context) { _commandContext = context; string commandName;
if (_commandContext.QueryString.TryGetValue("voiceCommandName", out commandName)) { HandleCommand(commandName); } } private static void HandleCommand(string commandName) { string content; if (_commandContext.QueryString.TryGetValue("keyword", out content) && !string.IsNullOrEmpty(content)) { switch (commandName) { case "PageSwitch": OnPageConvertCommandExecuted(content); break; case "WordCopy": OnLanguageCopyCommandExecuted(content); break; case "Search": OnSearchCommandExecuted(content); break; case "OpenFunction": OnOpenThingsCommandExecuted(content); break; } } }
然后在对应的页面中订阅事件
protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); if (e.NavigationMode == NavigationMode.New) { VoiceCommandHelper.WordCopyCommandExecuted += VoiceCommandHelper_WordCopyCommandEventExecuted; VoiceCommandHelper.OpenFunctionCommandExecuted += VoiceCommandHelper_OpenFunctionCommandEventExecuted; VoiceCommandHelper.CommandProcess(NavigationContext); } }
参考资料:
Quickstart: Voice commands (XAML)
MSDN的源码下载:
MSDN Voice Search for Windows Phone 8.1
我自己的源码:http://pan.baidu.com/s/1ntjyR37
望各位看官多拍砖