這兩天進羣(53078485)找大咖的童鞋比較多,只是大咖比較忙,目前Demo還沒有要到,這裏先給大家轉載一篇Aran大咖的博客學習下,以下是原文:
Win10開發中最具有系統特色的功能點絕對少不了集成Cortana語音指令,其實Cortana語音指令在以前的wp8/8.1時就已經存在了,發展到了Win10,Cortana最明顯的進步就是開始支持調用App 的App Service。當然App Service也是Win10 App的新特性之一,通過調用App Service就可以在App沒有前臺運行的時候爲Cortana提供數據交互。這樣一來Cortana就具有了兩種App交互方式:
- Cortana語音指令與前臺App的交互
- Cortana語音指令與後臺服務的交互
今天我們以前先看看Cortana與前臺App的交互,與前臺App的交互允許Cortana通過特定的語音指令來喚起App,並傳遞給App用戶想要的是怎樣的信息,App被喚起後通過用戶的語音指令參數就可以判斷接下來要做怎樣的處理。
下面我們做一個App來集成Cortana,通過語音指令來啓動App並根據參數來響應不同的用戶請求,先看效果圖:
Ok 開工!
創建VCD語音指令文件
在項目中添加一個xml文件並輸入文件名,我這裏創建的爲VoiceCommandsFile.xml
編輯VCD文件
針對App的實際情況,可以創建不同語言的指令集CommandSet,
Win10使用的是V1.2的語音指令模板,具體的模板使用詳情可訪問:https://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/dn706593.aspx
每個VCD文件中聲明的Command都必須包含以下信息:
- AppName元素,應用程序用於Cortana中的語音識別的名稱
- Example元素,告訴用戶該App所支持的語音指令的描述
- ListenFor 元素,監聽並識別用戶的指令,每個Command都至少有一個該元素
- Feedback 元素,指令識別成功後的反饋
- Navigate 元素,聲明語音指令將在前臺啓動應用。和VoiceCommandService互斥
- VoiceCommandService 元素,聲明語音指令將啓動後臺應用
VCD文件示例:
<?xml version="1.0" encoding="utf-8"?>
<!--UWP使用的是語音命令v1.2模板 wp8.1是v1.1 wp8是v1.0-->
<!--等多V1.2模板詳情請訪問:https://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/dn706593.aspx-->
<!--可以創建多個 CommandSet 元素,每個都帶有不同的 xml:lang 屬性以使你的應用可用於不同的市場。
例如,用於美國的應用可能有一個英語版本的 CommandSet 和一個西班牙語版本的 CommandSet-->
<!--
-每個CommandSet代表一種語言的語音指令,
-每個Command代表一種指定情景下的語音指令,每個CommandSet可以包含多種語音使用情景
-Example 會出現在Cortana -> App 幫助界面中,提示用戶可以怎麼使用該語音場景
-ListenFor 表示Cortana要監聽的語音語法,每個命令都需要具有至少一個 ListenFor 元素
-Feedback 指識別語音命令成功時,Cortana將顯示該元素內的內容
-Navigate 用於指示語音命令將在前臺啓動應用,如果語音命令改在後臺啓動應用,則指定VoiceCommandService
-VoiceCommandService 標籤表示Cortana要啓用後臺應用服務來處理用戶需求,
例: <VoiceCommandService Target="BusQueryService"/> Target填寫後臺應用服務的名稱
-->
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.2">
<CommandSet xml:lang="zh-cn" Name="set">
<AppName>小祕</AppName>
<Example> 打開主頁 或 查詢航班 </Example>
<Command Name="OpenMainPage">
<Example>打開主頁</Example>
<ListenFor>打開主頁</ListenFor>
<Feedback>正在啓動航班助手……</Feedback>
<Navigate />
</Command>
<Command Name="QueryFlight">
<Example> 查詢去西雅圖的航班 </Example>
<ListenFor >[搜索]去{City}[的]航班</ListenFor>
<ListenFor >[查詢]去{City}[的]航班</ListenFor>
<Feedback> 正在查詢去{City}的航班 </Feedback>
<Navigate />
</Command>
<Command Name="NavToPage">
<Example> 跳轉到某個界面 </Example>
<ListenFor >[跳轉]到{Destination}界面</ListenFor>
<Feedback> 正在跳轉到{Destination}界面 </Feedback>
<Navigate />
</Command>
<!--PhraseList用來定義一組語音字符,指定相應規定的字符,用來消除歧義-->
<!--使用 PhraseList 限制識別適用於一組相對較小的單詞。當單詞組過大(例如數百個單詞)或者根本不應被限制時,
請使用 PhraseTopic 元素和 Subject 元素來優化語音識別結果的相關性,從而增強可擴展性。-->
<PhraseList Label="Destination">
<Item>設置</Item>
<Item>關於</Item>
</PhraseList>
<!--可以提高識別率,內部屬性Subject可指定該關鍵字類型,比如 城市名 姓名 地址 等類型-->
<PhraseTopic Label="City" Scenario="Natural Language">
<Subject>City/State</Subject>
</PhraseTopic>
</CommandSet>
<!-- 其他語言的 CommandSet -->
</VoiceCommands>
上面例子中我們定義了三種Command指令,分別是"打開主頁","查詢去某城市的航班","跳轉到某個界面"。
ListenFor元素可以存在多個,其中認爲可忽略的詞可以用[]符號進行修飾。
PhraseList用來定義一組語音字符,指定相應規定的字符,用來消除歧義, 使用 PhraseList 限制識別適用於一組相對較小的單詞。當單詞組過大(例如數百個單詞)或者根本不應被限制時,要使用 PhraseTopic 元素和 Subject 元素來優化語音識別結果的相關性,從而增強可擴展性。
PhraseTopic可以提高識別率,內部屬性Subject可指定該關鍵字類型,比如 城市名 姓名 地址 等類型
安裝VCD命令文件
我們的App安裝後必須運行一次才能安裝VCD指令集,我們可以在App的OnLaunched中調用下面方法去註冊並激活語音指令集,代碼如下:
/// <summary>
/// 註冊語音指令
/// </summary>
private async Task InsertVoiceCommands()
{
await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(
await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///VoiceCommandsFile.xml")));
}
處理語音指令
在VCD程序集安裝正確的情況下,Cortana的幫助界面就會出現我們的App的語音指令集的調用說明:
通過相應的語音指令,Cortana就會啓動我們的App,我們需要在App中重寫OnActivated事件,判斷用戶使用的是哪個語音指令,並實現相應的邏輯,代碼如下:
protected override void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
// 如果程序不是因爲語音命令而激活的,就不處理
if (args.Kind != ActivationKind.VoiceCommand) return;
//將參數轉爲語音指令事件對象
var vcargs = (VoiceCommandActivatedEventArgs)args;
// 分析被識別的命令
var res = vcargs.Result;
// 獲取被識別的命令的名字
var cmdName = res.RulePath[0];
Type navType = null;
string propertie = null;
//判斷用戶使用的是哪種語音指令
switch (cmdName)
{
case "OpenMainPage":
navType = typeof(MainPage);
break;
case "QueryFlight":
navType = typeof(QueryPage);
//獲取語音指令的參數
propertie = res.SemanticInterpretation.Properties["City"][0];
break;
case "NavToPage":
//獲取語音指令的參數
propertie = res.SemanticInterpretation.Properties["Destination"][0];
//根據 propertie 參數決定跳轉到指定界面,這裏就不判斷了
navType = typeof(QueryPage);
break;
}
//獲取頁面引用
var root = Window.Current.Content as Frame;
if (root == null)
{
root = new Frame();
Window.Current.Content = root;
}
root.Navigate(navType, propertie);
// 確保當前窗口處於活動狀態
Window.Current.Activate();
}
Ok,至此代碼部分已經完工,可以通過Cotrana語音指令啓動我們的App了,這種啓動方式爲前臺啓動,下篇文章中將介紹Cortana調用App後臺service是如何實現的。