除了系统集成的可以用于搜索、启动应用程序等语音命令外,在我们的应用程序内部还能自己定义语音指令,使得我们的APP能与语音操控结合得更加完全。
语音指令是通过一个XML文件来定义的。比如,咱小舅子开了家饭店,并取了一个非常雅致的名字——牛逼饭店,因店里的牛肉烧得特特好吃,连皇帝吃了也舍不得回金銮殿。
为了实现“牛逼饭店”应用能实现语音点菜,在“解决方案资源管理器”窗口中找到应用项目,右击项目名,从快捷菜单中依次执行【添加】【新建项】,在新建项对话框中选中“语音命令定义”。
然后输入文件的名字,确定完成语音命令文件添加。
设置这个文件的生成行为为“内容”,“如果较新则复制”。
下面看一下我为牛逼饭殿定义的语音指令。
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.0">
<CommandSet xml:lang="zh-CN">
<CommandPrefix>牛逼饭店</CommandPrefix>
<Example> 饭店主页、我要牛肉、我点白菜 </Example> <Command Name="点菜">
<Example> 我要豆腐,或 我点白菜 </Example>
<ListenFor> 我要{items} </ListenFor>
<ListenFor> 我点{items} </ListenFor>
<Feedback> 好,点菜去 </Feedback>
<Navigate Target="diancai.xaml"/>
</Command> <Command Name="主页">
<Example> 饭店主页 </Example>
<ListenFor> 饭店主页 </ListenFor>
<Feedback> 主页快到了 </Feedback>
<Navigate Target="MainPage.xaml" />
</Command> <PhraseList Label="items">
<Item> 牛肉 </Item>
<Item> 豆腐干 </Item>
<Item> 白菜 </Item>
<Item >火腿</Item>
</PhraseList> </CommandSet>
</VoiceCommands>
这个文件并不复杂,弄清楚其结构就好。
1、根节点为VoiceCommands,并且xmlns必须为http://schemas.microsoft.com/voicecommands/1.0;
2、VoiceCommands下可以包含多个CommandSet节点,每个CommandSet节点表示一个命令集,通常一个命令集表示一种语言,如为英文定义一个命令集,为中文也定义一个。通过xml:lang特性来指定语言,xml:lang="zh-CN"表示语音指令集为中文;
3、CommandPrefix节点是可选的,是CommandSet的子级,只能有一个。别小看CommandPrefix节点,它的作用大得很,如果应用的名字为“牛逼饭店v3.0.0.11”,这样我们朗读起来很痛苦,系统也未必能识别,这时候,如果通过CommandPrefix元素定义一个别名,如<CommandPrefix>牛逼饭店</CommandPrefix>,只要我们对着手机话筒大声说出“牛逼饭店”,系统就会找到牛逼饭店v3.0.0.11应用程序了,知道了吧,这就是CommandPrefix的用途。
4、Example在CommandSet和子Command元素中都能包含;在CommandSet中使用,用于说明整个命令集的操作方法,如果用在Command中,就用于单个命令的示例,示例是用来告诉用户,对着手机应该如何表白。
5、CommandSet下面可以放多个Command元素,表示单个命令。记得要通过Name特性为指令命名,而且在当前命令集中,不要出现相同的命令。命令中可以有Example元素,告诉用户如何使用语音操作。可以包含多个ListenFor元素,该元素表示语音识别系统应当注意聆这些话,比如牛逼饭店中,点菜命令的一个ListenFor为“我要{items}”,即语音系统会注意听“我要大白菜”,“我要豆腐渣”等语句,{items}是啥,后面会说到。
6、Feedback元素是指当语音系统听出命令后的回应,比如我说“我要吃西瓜”,系统识别成功后会返馈一句“西瓜多得是,随便啃。”,如牛逼饭店应用中的<Feedback> 好,点菜去 </Feedback>,当识别成功后,系统会发出一句“好,点菜去”。
7、Navigate元素表示当命令识别成功后,应导航到哪个页面并传递参数。
8、CommandSet中可包含多个PhraseList,PhraseList元素用来定义一组短语,比如上面我们提到“我要{items}”,这个items用一对大括号包起来,表示它是一个占位符,一个标签,它是用下面这个短语列表中的词来替换。
<PhraseList Label="items">
<Item> 牛肉 </Item>
<Item> 豆腐干 </Item>
<Item> 白菜 </Item>
<Item >火腿</Item>
</PhraseList>
一定要注意Label一定要与前面{}中的内容匹配,假如我说“我要白菜”,那么听到的命令就是“我要{items}”,而其中的{items}就会被“白菜”所替代。
现在,大家对语音命令的定义应该了解了,牛逼饭店的示例代码我待会上传。
下面给大家演示一个叫“我的情书榜”的应用程序。
1、启动可爱的VS环境,新建一个WP项目(暂用WP8)。
2、在主页MainPage.xaml中输入以下XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Text="欢迎,欢迎,热烈欢迎。"
FontSize="55" TextWrapping="Wrap"/>
</Grid>
3、再向项目添加一个新页面,名为Write.xaml,XAML如下:
<!--LayoutRoot 是包含所有页面内容的根网格-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions> <!--TitlePanel 包含应用程序的名称和页标题-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="新情书" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel> <!--ContentPanel - 在此处放置其他内容-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="35" Text="请输入内容:"/>
<TextBox Grid.Row="1" Margin="0,15,0,5"/>
</Grid>
</Grid>
4、现在,向项目中添加一个语音指令定义文件,命名为cmd.xml。注意要把文件的生成操作设置为“内容”,复制到输出目录设置为“如果较新则复制”。并把文件中工具生成的内容删掉,我们自己写一个语音指令定义集。
<?xml version="1.0" encoding="utf-8"?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.0">
<CommandSet xml:lang="zh-cn">
<CommandPrefix>情书</CommandPrefix>
<Example>情书,或者 写情书。</Example>
<Command Name="write">
<Example>写情书</Example>
<ListenFor>写情书</ListenFor>
<ListenFor>新情书</ListenFor>
<Feedback>去,勇敢地写。</Feedback>
<Navigate Target="Write.xaml"/>
</Command>
<Command Name="main">
<Example>进主页,或 去主页</Example>
<ListenFor>去主页</ListenFor>
<ListenFor>进主页</ListenFor>
<Feedback>欢迎,欢迎。</Feedback>
<Navigate Target="MainPage.xaml"/>
</Command>
</CommandSet>
</VoiceCommands>
为了方便用户说出应用的名字,CommandPrefix指定为“情书”,这样,说出“情书”就可以识别出当前应用。命令集包含两个命令,第一个命令会启动Write.xaml页面,第二个则进入主页。
5、命令文件虽然定义好了,但现在它还不能起作用,需要在运行时安装命令,方法是在App的Launching事件中加入以下代码:
private async void Application_Launching(object sender, LaunchingEventArgs e)
{
await Windows.Phone.Speech.VoiceCommands.VoiceCommandService.InstallCommandSetsFromFileAsync(new Uri("ms-appx:///cmd.xml"));
}
现在,运行应用程序,然后激活系统语音帮助(长按Win键),这时候,语音助手启动,点击右上角的问题,如下图所示。
切换到“应用程序”页,然后会看到我们的应用程序,点击它。
这时候,会看到一些提示的示例文本,大家细心研究就会看到,这些示例文本就是我们在Example节点中定义的文本。
现在你对着手机喊“情书 写情书”,识别后会启动应用程序,然后跳转到Write.xaml页面。
在通过语音操作进入页面时会向页面传递参数,参数包含命令的名字、已识别的内容,可以在页面的OnNavigatedTo方法中处理,具体大家可以参考我上传的牛逼饭店应用。
牛逼饭店示例下载地址:http://files.cnblogs.com/tcjiaan/%E7%89%9B%E9%80%BC%E9%A5%AD%E5%BA%97.rar
怎么样,动手试试吧。
============================================
【后话】
WP 8.1中对应的命名空间在Windows.Media.SpeechRecognition。
安装语音指令文件,使用VoiceCommandManager类的静态方法InstallCommandSetsFromStorageFileAsync,不过要注意该方法的参数是StorageFile对象,而SL for WP中是URI的,同样,可以通过GetFileFromApplicationUriAsync方法来从URI得到文件引用。
var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///cmd.xml"));
await Windows.Media.SpeechRecognition.VoiceCommandManager.InstallCommandSetsFromStorageFileAsync(file);
WP中的语音识别(下):语音指令的更多相关文章
-
WP中的语音识别(上):基本识别
WP 8.1目前许多内容仍处于未确定状态,因此,本文所提及的语音识别,是基于WP8的,在8.1中也差不多,也是使用运行时API来实现,如果大家不知道什么是运行时API,也没关系,不影响学习和开发,因为 ...
-
Win10/UWP开发—使用Cortana语音指令与App的前台交互
Win10开发中最具有系统特色的功能点绝对少不了集成Cortana语音指令,其实Cortana语音指令在以前的wp8/8.1时就已经存在了,发展到了Win10,Cortana最明显的进步就是开始支持调 ...
-
Win10/UWP开发—使用Cortana语音指令启动前台App
这两天进群(53078485)找大咖的童鞋比较多,只是大咖比较忙,目前Demo还没有要到,这里先给大家转载一篇Aran大咖的博客学习下,以下是原文: Win10开发中最具有系统特色的功能点绝对少不了集 ...
-
Linux中/proc目录下文件详解
转载于:http://blog.chinaunix.net/uid-10449864-id-2956854.html Linux中/proc目录下文件详解(一)/proc文件系统下的多种文件提供的系统 ...
-
Linux中/proc目录下文件详解(转贴)
转载:http://www.sudu.cn/info/index.php?op=article&id=302529 Linux中/proc目录下文件详解(一) 声明:可以*转载本文, ...
-
16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16
一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...
-
【Azure Redis 缓存】Azure Cache for Redis 中如何快速查看慢指令情况(Slowlogs)
问题描述 当 Azure Redis 服务器负载过高的情况下,使用时就会遇见连接超时,命令超时,IO Socket超时等异常.为了能定位是那些因素引起的,可以参考微软官方文档( 管理 Azure Ca ...
-
SQL搜索下划线,like中不能匹配下划线的问题
最近在检测天气预报15天查询网 站(http://tqybw.net)时的URL时,发现页面中有很些404页,分析发现,是请求地址的能参数中多了下划线“_”,而rewrite规 则中并没有配这样的规则 ...
-
python中那些双下划线开头得函数和变量--转载
Python中下划线---完全解读 Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用'from module import *'导入 __xxx__ 系统定义名字 __x ...
随机推荐
-
iOS9 UI Tests探索笔记
UI Tests是什么? UI Tests是一个自动测试UI与交互的Testing组件 UI Tests有什么用? 它可以通过编写代码.或者是记录开发者的操作过程并代码化,来实现自动点击某个按钮.视图 ...
-
[Ubuntu] ubuntu10.04系统维护之Wine的安装
在介绍安装wine之前,我想是有必要先介绍一下Wine的.当然,如果是Liunx的高手,我想是没必要看的,但是对于笔者这样的菜鸟级人物还是需要看一下的. Wine是一款Liunx下的模拟器软件,但是W ...
-
定制Centos系统(基于6.x)
1.条件准备: 按照需求,最小化安装Centos原生系统 在安装后的系统中找到/root/install.log与/root/anaconda-ks.cfg文件 ...
-
iOS视图控制器之间delegate传值教程
之前在*上看到一篇讲传值(segue传值和delegate传值)的文章,感觉讲的非常清晰,就将delegate部分翻译了一下.有兴趣能够看看. 原文: http://stack ...
-
BeanPostProcessors (for example: not eligible for auto-proxying),报错解决
最近遇到个问题,springmvc项目debug启动失败 debug启动会卡住不动,run模式启动正常 debug启动输出到下面这行之后,就不会继续输出了 -- :: [INFO]- Bean 'da ...
-
C++的类大小
有以下C++类 #pragma pack(push) #pragma pack(1) class task /*:public OSThread*/{ //public: // void Entry( ...
-
Ubuntu16.10上安装NodeJS6.9.2
1.下载 https://nodejs.org/en/download/ 2.解压 tar -xJf node-v6.9.2-linux-x64.tar.xz 3. 移到通用的软件安装目录 /opt/ ...
-
iOS微信支付demo运行报错解决如下
要接入微信支付的小伙伴,首先要下载一份官方demo(APP微信支付官方Demo下载),然后打开工程,准备大干一场. 1.编译报错 编译的时候居然直接报错了(orz) 错误提示: APP微信支付官方De ...
-
20172329 2018-2019-2 《Java软件结构与数据结构》实验二报告
20172329 2018-2019-2 <Java软件结构与数据结构>实验二报告 课程:<Java软件结构与数据结构> 班级: 1723 姓名: 王文彬 学号:2017232 ...
-
aop注解 spring提供的事务
http://www.cnblogs.com/friends-wf/p/3826893.html 是 自定义的切面,并且添加注解 声明为切面 利用spring提供的事务声明 主要在 service层上 ...