上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比调用前台的App,调用后台任务有个有点就是App不用被启动即可为用户提供服务。

要想使用Cortana调用App后台任务,首先我们需要定义VCD文件,我们依旧使用上篇中的代码,让它支持Cortana调用后台任务。

创建后台任务

新增一个[Windows运行时组件]项目,暂时起名叫做:XiaoMiBackgroundTask

创建一个类,暂且叫做XiaoMiTask,并继承IBackgroundTask

完成如下代码:

  1. //------------------------------------------------------
  2. //
  3. // FileName: XiaoMiTask.cs
  4. // Namespace: XiaoMiBackgroundTask
  5. // Assembly: XiaoMiBackgroundTask
  6. // Description:
  7. // Author: aran_wang
  8. // Created On: 2015-09-10
  9. //------------------------------------------------------
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Diagnostics;
  13. using System.Threading.Tasks;
  14. using Windows.ApplicationModel.AppService;
  15. using Windows.ApplicationModel.Background;
  16. using Windows.ApplicationModel.VoiceCommands;
  17. using Windows.Storage;
  18.  
  19. namespace XiaoMiBackgroundTask
  20. {
  21. /*
  22. VoiceCommandServiceConnection 类是接受Cortana传递过来的信息以及给Cortana回应信息的
  23. 里面有几个重要的方法:
  24. GetVoiceCommandAsync 检索用户的语音命令提交Cortana通过语音或文本。
  25. ReportFailureAsync 发送一个响应,表明Cortana语音命令处理失败了。
  26. ReportProgressAsync 发送一个响应,Cortana在处理语音命令。
  27. ReportSuccessAsync 发送一个响应,Cortana语音命令已成功了。
  28. RequestAppLaunchAsync 发送一个响应,要求Cortana启动前台应用
  29. RequestConfirmationAsync 发送一个响应,指示Cortana语音命令需要确认。
  30. RequestDisambiguationAsync 发送一个响应,表示Cortana语音命令返回多个结果,需要用户选择一个。
  31. */
  32.  
  33. public sealed class XiaoMiTask : IBackgroundTask
  34. {
  35. BackgroundTaskDeferral _taskDerral;
  36. VoiceCommandServiceConnection _serviceConnection;
  37. public async void Run(IBackgroundTaskInstance taskInstance)
  38. {
  39. _taskDerral = taskInstance.GetDeferral();
  40. var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
  41.  
  42. // 验证是否调用了正确的app service
  43. if (details == null || details.Name != "XiaoMiService")
  44. {
  45. _taskDerral.Complete();
  46. return;
  47. }
  48. _serviceConnection = VoiceCommandServiceConnection.FromAppServiceTriggerDetails(details);
  49. // 获取被识别的语音命令
  50. var cmd = await _serviceConnection.GetVoiceCommandAsync();
  51. switch (cmd.CommandName)
  52. {
  53. case "QueryTrain":
  54. var date = cmd.Properties["DateTime"][];
  55. var from = cmd.Properties["From"][];
  56. var to = cmd.Properties["To"][];
  57. await QueryTrain(date, from, to);
  58. break;
  59. case "CancelTrain":
  60. var cancelTrain = cmd.Properties["City"][];
  61. CancelTrain(cancelTrain);
  62. break;
  63. }
  64. _taskDerral.Complete();
  65. }
  66.  
  67. private void CancelTrain(string cancelTrain)
  68. {
  69. //取消火车 交互类似
  70. Debug.WriteLine(cancelTrain);
  71. }
  72.  
  73. private async Task QueryTrain(string date, string from, string to)
  74. {
  75. // msgback是返回给Cortana 要显示的内容
  76. var msgback = new VoiceCommandUserMessage();
  77. // msgRepeat是指当cortana对用户语音指令不明确的时候显示的,一般用来消除用户歧义
  78. // 比如存在让用户选择某个选项时,用户没有按照预期的操作方式去操作,cortana会显示第二消息来告诉一些操作提示信息
  79. var msgRepeat = new VoiceCommandUserMessage();
  80.  
  81. //模拟火车列表,真实情况下需要调用api获取火车信息
  82. var trainList = new List<VoiceCommandContentTile>();
  83. for (var i = ; i < ; i++)
  84. {
  85. trainList.Add(new VoiceCommandContentTile
  86. {
  87. AppContext = i, //用来存储该条Tile的标识 一般存储数据id
  88. ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText,
  89. Image = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Images/300300.jpg")),
  90. Title = $"D{i + 3}8{i * 2}",
  91. TextLine1 = $"出发:{DateTime.Now.AddHours(i)} - 到达:{DateTime.Now.AddHours(i + 2)}"
  92. });
  93. }
  94.  
  95. TrainList:
  96.  
  97. msgback.DisplayMessage = msgback.SpokenMessage = $"我找到了{date}从{from}到{to}的火车列表,请选择:";
  98. msgRepeat.DisplayMessage = msgRepeat.SpokenMessage = "你要告诉我你想预定哪个车次的火车:";
  99. // 把查询到的火车列表发回到Cortana ,注意 列表最多显示10个
  100. var response = VoiceCommandResponse.CreateResponseForPrompt(msgback, msgRepeat, trainList);
  101.  
  102. // 用户选择了哪个项
  103. var selectedRes = await _serviceConnection.RequestDisambiguationAsync(response);
  104.  
  105. //创建咨询用户是否确定要预定该车次的信息
  106. msgback.DisplayMessage = msgback.SpokenMessage = $"您确定要预定 {selectedRes.SelectedItem.Title} 次列车吗?";
  107. msgRepeat.DisplayMessage = msgRepeat.SpokenMessage = "请选择是或者不是";
  108. response = VoiceCommandResponse.CreateResponseForPrompt(msgback, msgRepeat);
  109.  
  110. //返回让用户选择 是 或者 不是 的信息给cortana
  111. var result = await _serviceConnection.RequestConfirmationAsync(response);
  112. //如果用户选择是
  113. if (result.Confirmed)
  114. {
  115. //提示预定成功
  116. msgback.DisplayMessage = msgback.SpokenMessage = $"您成功预定了 {selectedRes.SelectedItem.Title} 次列车,{date}从{from}到{date},{selectedRes.SelectedItem.TextLine1}!";
  117. msgRepeat.DisplayMessage = msgRepeat.SpokenMessage = $"您成功预定了 {selectedRes.SelectedItem.Title} 次列车。";
  118. response = VoiceCommandResponse.CreateResponseForPrompt(msgback, msgRepeat);
  119. }
  120. else
  121. {
  122. goto TrainList;
  123. }
  124. // 返回一个操作成功的指令
  125. await _serviceConnection.ReportSuccessAsync(response);
  126. }
  127. }
  128. }

代码意思就不解释了,写的一手详细的注释不是吗?

回到我们的主程序中,在引用里添加该后台应用服务的引用。

注册App后台服务

打开Package.appxmanifest文件,切换到"声明"选项卡,添加一个应用服务的声明,名称随便填,一会VCD文件里要用到这个名字,这里填写XiaoMiService,别以为是小米的意思哈,哥是米黑,是小秘。入口点填写上面创建的后台服务的"命名空间.类名",截图如下:

编写VCD文件

在vcd语音指令中添加两个新的Command节点,以及定义需要的PhraseTopic,对VCD文件不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互

添加的代码如下:

  1. <Command Name="QueryTrain">
  2. <Example> 查询去某地的火车 </Example>
  3. <ListenFor >查询{DateTime}从{From}到{To}的火车</ListenFor>
  4. <Feedback> 正在查询{DateTime}从{From}到{To}的火车 </Feedback>
  5. <VoiceCommandService Target="XiaoMiService"/>
  6. </Command>
  7.  
  8. <Command Name="CancelTrain">
  9. <Example> 取消去某地的火车 </Example>
  10. <ListenFor >取消去{City}的火车</ListenFor>
  11. <Feedback> 正取消去{City}的火车 </Feedback>
  12. <VoiceCommandService Target="XiaoMiService"/>
  13. </Command>
  14.  
  15. <!--PhraseTopic 可以提高识别率,内部属性Subject可指定该关键字类型,比如 城市名 姓名 地址 等类型-->
  16. <PhraseTopic Label="City" Scenario="Natural Language">
  17. <Subject>City/State</Subject>
  18. </PhraseTopic>
  19. <PhraseTopic Label="From" Scenario="Natural Language">
  20. <Subject>City/State</Subject>
  21. </PhraseTopic>
  22. <PhraseTopic Label="To" Scenario="Natural Language">
  23. <Subject>City/State</Subject>
  24. </PhraseTopic>
  25. <PhraseTopic Label="DateTime" Scenario="Natural Language">
  26. <Subject>Date/Time</Subject>
  27. </PhraseTopic>

上面的Command节点中,使用了VoiceCommandService元素来标注该语音指令是要启动后台任务服务,而后台任务服务名称为XiaoMiService。

注册VCD文件

注册vcd文件上篇文章一毛一样:

  1. /// <summary>
  2. /// 注册语音指令
  3. /// </summary>
  4. private async Task InsertVoiceCommands()
  5. {
  6. await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(
  7. await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///VoiceCommandsFile.xml")));
  8. }

Ok,打开一次App完成VCD语音指令的注册,然后尽情的使用Cortana吧:

推荐一个UWP开发群:53078485 大家可以进来一起学习

Win10/UWP开发—使用Cortana语音与App后台Service交互的更多相关文章

  1. Win10/UWP开发—使用Cortana语音指令与App的前台交互

    Win10开发中最具有系统特色的功能点绝对少不了集成Cortana语音指令,其实Cortana语音指令在以前的wp8/8.1时就已经存在了,发展到了Win10,Cortana最明显的进步就是开始支持调 ...

  2. Win10/UWP开发—使用Cortana语音指令启动前台App

    这两天进群(53078485)找大咖的童鞋比较多,只是大咖比较忙,目前Demo还没有要到,这里先给大家转载一篇Aran大咖的博客学习下,以下是原文: Win10开发中最具有系统特色的功能点绝对少不了集 ...

  3. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

  4. Win10 UWP开发系列:实现Master/Detail布局

    在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...

  5. Win10 UWP开发实现Bing翻译

    微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...

  6. Win10/UWP开发—凭据保险箱PasswordVault

    PasswordVault用户凭据保险箱其实并不算是Win10的新功能,早在Windows 8.0时代就已经存在了,本文仅仅是介绍在UWP应用中如何使用凭据保险箱进行安全存储和检索用户凭据. 那么什么 ...

  7. Win10 UWP 开发系列:使用SQLite

    在App开发过程中,肯定需要有一些数据要存储在本地,简单的配置可以序列化后存成文件,比如LocalSettings的方式,或保存在独立存储中.但如果数据多的话,还是需要本地数据库的支持.在UWP开发中 ...

  8. Win10/UWP开发-Ink墨迹书写

    在UWP开发中,微软提供了一个新型的InkCanvas控件用来让用户能书写墨迹,在新版的Edga浏览器中微软自己也用到了该控件使用户很方便的可以在web上做笔记. InkCanvas控件使用很简单,从 ...

  9. 【Win10 应用开发】集成语音命令

    记得老周以前在写WP8应用开发的文章时,曾经写过语音命令集成的文章,后来8.1的时候“小娜”问世,但考虑到其变化不大,故老周没有补写相应的文章. 今天,老周打算补一下Win 10通用应用开发中,有关语 ...

随机推荐

  1. UIKit - scrollView缩放、滚动

    UIScrollView滚动 三大属性: self.scrollView.pageEnabled = NO  是否分页:n只要将UIScrollView的pageEnabled属性设置为YES,UIS ...

  2. PHP多条件搜索ShopNc实例

    控制器部分代码: if (trim($_GET['keyword']) != '') { //echo $_GET['search_type']; exit(); switch ($_GET['sea ...

  3. 记一次联想A820t救砖线刷

    因为是看着教程刷的(有大神放出教程,只管伸手拿来就好啦)但是照着教程做的过程中出现了一些问题还是值得注意的,在这里总结一下,给新手提供一点建议 教程比较长,我放到博客的文件中,需要的自己下载一下.或者 ...

  4. springMVC中实现servlet依赖注入

    记录一下开发过程中遇到的问题: 首先看一下这个帖子: http://blog.csdn.net/gaogaoshan/article/details/23540129 由于我使用的是springMVC ...

  5. 驱动插ring3线程执行代码

    近日有在写一个小东西 需要在内核态中运行一个WIN32程序 之前提到的插入APC可以满足部分要求 但是一到WIN7 x86平台下就崩溃了WIN7下只能插入第三方的进程 一插入系统进程就崩溃,但是这样满 ...

  6. 一次DB服务器性能低下引发的对Nonpaged Pool Leak问题的诊断

    1. 问题表象+分析 最开始是DB访问性能下降,某个不用Cache.直接到DB的查询10s+都不返回.上去一看,DB Server内存97%,可用内存才100多M. Windows毕竟不是iOS,不留 ...

  7. node模块系统常用命令

    node模块系统常用命令 命令 示例 备注 安装模块 npm install commander 最新版本 npm install commander@1.0.0 指定版本 npm install c ...

  8. 让powershell同时只能运行一个脚本(进程互斥例子)

    powershell,mutex,互斥,进程互斥,脚本互斥 powershell脚本互斥例子,在powershell类别文章中,声明原创唯一. powershell 传教士 原创文章 2016-07- ...

  9. win10下安装USB-Blaster哈希值错误

    插入usb-blaster后,无法安装驱动,一直显示感叹号,更新驱动后显示“文件的哈希值不在指定的目录”这样的错误提示,解决方法如下:1.Windows键+ R,输入shutdown.exe /r / ...

  10. 会游走的TextView

    //自定义的TextView package com.bwie.androidtest; import android.content.Context; import android.graphics ...