UWP 통합 Cortana
최근 에 Cortana 접속 을 해서 간단 한 상호작용 을 하고 있 습 니 다.그동안 일부 문제 가 있 었 고, 현재 UWP 에 관 한 자료 도 비교적 적 고, 다행히 마지막 문 제 는 모두 해결 됐다.
현재 윈도 10 에 서 는 코 타 나 가 프론트 데스크 톱 통합 (애플 리 케 이 션 으로 전환) 과 백 스테이지 통합 (코 타 나 에서 작업 완료) 을 지원 하고 있 으 며, 두 가지 모델 에 대해 각각 소개 한다.
1. VCD 파일 소개
VCD 파일 은 명령 설정 파일 로 VCD 파일 에서 명령 등 정 보 를 정의 할 수 있 습 니 다.VCD 파일 은 다음 과 같은 몇 가지 요소 로 구성 되 어 있 습 니 다.
VoiceCommands: VoiceCommands 의 xmlns 속성 값 은 http://schemas.microsoft.com/voicecommands/1.2, WP 는 1.0 WP 8.1 은 1.1 (잘못 기억 하지 않 으 면), VoiceCommands 는 1 ~ 15 개의 CommandSet 으로 서로 다른 언어 에 대응 하고 있다.
commandSet: 서로 다른 언어 에 대한 명령 입 니 다. xml: lang = "zh - cn"표 지 는 이 명령 이 중국어 에 대응 합 니 다.
commandPrefix: commandSet 의 하위 노드 로 명령 의 접 두 사 를 정의 합 니 다. 보통 명령 으로 구성 되 어 있 습 니 다. commandPrefix 시작 + command 명령 을 실행 합 니 다.
command: 하나의 명령 을 정의 합 니 다.
ListenFor: {scenery} 를 검색 하면 모든 것 을 식별 할 수 있 는 받 아야 할 명령 을 표시 합 니 다. commandPrefix + 검색 + 관광지 명령 입 니 다.{scenery} 은 PhraseTopic 에서 종 류 를 정의 할 수 있 습 니 다.여러 그룹 ListenFor 를 동시에 정의 할 수 있 습 니 다. 예 를 들 어:
{scenary} 검색 {scenary} {scenary} 티켓
피드백: Cortana 식별 명령 을 표시 한 후 응용 코드 를 실행 하기 전에 사용자 에 게 피드백 을 줍 니 다.
VoiceCommandService, Navigate: 두 개 를 선택 할 수 있 지만 하나 가 있어 야 합 니 다.Navigate 는 App 을 시작 하여 작업 을 수행 하 는 데 사 용 됩 니 다. (프론트 통합) VoiceCommandService 는 Cortana 에서 작업 을 수행 하 는 데 사 용 됩 니 다. (백 엔 드 통합)
PhraseTopic: CommandSet 의 하위 노드 로 자리 차지 문자 와 유사 하 다 는 뜻 으로 PhraseTopic 의 장면 을 Subject 로 정의 하여 식별 율 을 높 일 수 있 습 니 다.예 를 들 어 나 는 {city} 에 갈 것 이다.
City/State
VCD 파일 에 대한 더 많은 소 개 는 MSDN 의 문 서 를 볼 수 있 습 니 다.https://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/dn706593.aspx
2. 백 스테이지 통합
백 스테이지 통합 은 애플 리 케 이 션 을 열지 않 고 Cortana 에서 직접 작업 을 수행 할 수 있 습 니 다.다음은 인 스 턴 스 장면 에 대해 어떻게 백 스테이지 가 Cortana 로 통합 되 는 지 설명 할 것 이다.
먼저 UWP 애플 리 케 이 션 Cortana Demo 를 새로 만 들 고 Windows Runtime Component 프로젝트 Cortana Service 를 새로 만 듭 니 다.IBackgroundTask 인 터 페 이 스 를 계승 하 는 Cortana CommandService 를 새로 만 듭 니 다.Cortana Demo 에서 Cortana Service 를 참조 하여 Package. appxmanifest 파일 을 열 고 Application 노드 에 다음 노드 를 추가 합 니 다.
1 <Extensions>
2 <uap:Extension Category="windows.appService" EntryPoint="CortanaDemo.CortanaService.CortanaCommandService">
3 <uap:AppService Name="CortanaCommandService" />
4 uap:Extension>
5 <uap:Extension Category="windows.personalAssistantLaunch"/>
6 Extensions>
동시에 Cortana Demo 에 VCD 파일 Cortana Command. xml 을 추가 하여 명령 을 정의 합 니 다.
xml version="1.0" encoding="utf-8" ?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.2">
<CommandSet xml:lang="zh-cn" Name="AdventureWorksCommandSet_zh-cn">
<CommandPrefix>我要玩CommandPrefix>
<Example>我要玩Example>
<Command Name="ScenerySearch">
<Example>搜索 苏州乐园 Example>
<ListenFor>搜索{destination}ListenFor>
<ListenFor>我要去{destination}ListenFor>
<ListenFor>{destination}的门票ListenFor>
<ListenFor>{destination}ListenFor>
<ListenFor>查找{destination}ListenFor>
<Feedback> 正在搜索{destination}... Feedback>
<VoiceCommandService Target="TCTVoiceCommandService"/>
Command>
<PhraseTopic Label="destination" Scenario="Natural Language">
<Subject>City/StateSubject>
<Subject>City/StateSubject>
PhraseTopic>
<PhraseTopic Label="from" Scenario="Natural Language">
<Subject>City/StateSubject>
PhraseTopic>
<PhraseTopic Label="to" Scenario="Natural Language">
<Subject>City/StateSubject>
PhraseTopic>
<PhraseTopic Label="date" Scenario="Natural Language">
<Subject>Date/TimeSubject>
PhraseTopic>
CommandSet>
VoiceCommands>
동시에 App. xaml. cs 에 다음 코드 를 추가 합 니 다.
var vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync(@"CortanaCommand.xml");
await Windows.ApplicationModel.VoiceCommands.VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);
여기까지 프로젝트 가 완성 되 었 다.다음은 IBackgroundTask 인 터 페 이 스 를 실현 합 니 다.
public async void Run(IBackgroundTaskInstance taskInstance)
{
//异步任务需要获取Deferral。
serviceDeferral = taskInstance.GetDeferral();
taskInstance.Canceled += OnTaskCanceled;
var triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
if (triggerDetails != null && triggerDetails.Name == "CortanaCommandService")
{
try
{
voiceServiceConnection =
VoiceCommandServiceConnection.FromAppServiceTriggerDetails(
triggerDetails);
voiceServiceConnection.VoiceCommandCompleted += OnVoiceCommandCompleted;
VoiceCommand voiceCommand = await voiceServiceConnection.GetVoiceCommandAsync();
// perform the appropriate command.
switch (voiceCommand.CommandName)
{
case "ScenerySearch":
var destination = voiceCommand.Properties["destination"][0];
await SearchSceneryByKey(destination);
break;
default:
LaunchAppInForeground();
break;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Handling Voice Command failed " + ex.ToString());
}
}
}
private async Task SearchSceneryByKey(string destination)
{
#region 查询
//通过destination来从网络查询数据.....
#endregion
var destinationsContentTiles = new List();
foreach (var scenery in result.Item2)
{
destinationsContentTiles.Add(new VoiceCommandContentTile { Title = scenery.sceneryName, TextLine1 = "¥" + scenery.tcPrice, TextLine2 = scenery.address, ContentTileType = VoiceCommandContentTileType.TitleWithText });
}
var userMessage = new VoiceCommandUserMessage
{
DisplayMessage = string.Format("{0}有关的景点", destination),
SpokenMessage = string.Format("找到了{0}条信息,请问您想查看哪一条?", result.Item2.Count)
};
var repeat = new VoiceCommandUserMessage
{
DisplayMessage = "请再说一遍",
SpokenMessage = "不好意思,没听清楚"
};
var response = VoiceCommandResponse.CreateResponseForPrompt(userMessage, repeat, destinationsContentTiles);
var resultd = await voiceServiceConnection.RequestDisambiguationAsync(response);
var selectedScenery = resultd.SelectedItem.AppContext as resScenerysModel;
SceneryVMLocator.SceneryVM.CurrentScenery = new resScenerysModel
{
sceneryId = selectedScenery.sceneryId
};
userMessage = new VoiceCommandUserMessage
{
DisplayMessage = "正在显示景点详情...",
SpokenMessage = "正在显示景点详情..."
};
response = VoiceCommandResponse.CreateResponse(userMessage);
response.AppLaunchArgument = InternalUrlBuilder.Build(ProductType.Scenery, InternalUrlBuilder.Action.details, selectedScenery.sceneryId);
await voiceServiceConnection.RequestAppLaunchAsync(response);
}
이 코드 는 다음 과 같은 기능 이 있 습 니 다.
1. 명령 유형 가 져 오기
2. 네트워크 데이터 조회
3. 사용자 에 게 어떤 것 을 보 여 주 며 물 어보 기
4. 응용 프로그램 시작 에 대한 자세 한 정보
이로써 코 타 나 백 스테이지 통합 이 거의 완성 됐다.
VoiceCommand ServiceConnection 은 다음 과 같은 몇 가지 방법 이 있 습 니 다.
1, GetVoiceCommandAsync: 명령 가 져 오기
2, ReportFailureAsync: 반환 실패
3. Report ProgressAsync: 사용자 에 게 진 도 를 보고 하고 시간 이 오래 걸 리 면 사용자 에 게 현재 작업 정 보 를 되 돌려 야 합 니 다.
4. ReportSuccessAsync: 되 돌아 오 는 작업 이 성공 적 이 고 받 아들 일 필요 가 없습니다.
5. RequestAppLaunchAsync: Cortana 에서 응용 프로그램 을 시작 합 니 다.
6, RequestConfirmation Async: 사용자 에 게 Yes/No 요청 보 내기
7. RequestDisambiguation Async: 여러 개의 데 이 터 를 포함 할 때 사용자 가 선택 할 수 있 습 니 다. 예 를 들 어 몇 개의 관광지 정 보 를 되 돌려 주 고 사용자 에 게 어느 것 을 확인 해 야 하 는 지 물 어보 십시오.
코드 중 두 군데 가 굵게 늘 어 난 것 을 발견 하 셨 는 지 모 르 겠 습 니 다.이 두 곳 은 내 가 개발 할 때 만난 구덩이 다.
1、ContentTileType = VoiceCommandContentTileType.TitleWithText.
데 이 터 를 추가 할 때 제목, 그림 등 다양한 유형의 목록 을 보 여줄 수 있 으 며, 구체 적 인 정 보 는 VoiceCommand ContentTile Type 을 볼 수 있다.
개발 할 때 기본 적 인 관광지 정보 만 보 여주 고 관광지 사진 은 보 여주 지 않 았 기 때문에 처음에 정의 만 내 렸 다.
new VoiceCommandContentTile { Title = scenery.sceneryName, TextLine1 = "¥" + scenery.tcPrice, TextLine2 = scenery.address}
배치 작업 을 할 때 Cortana 는 실 패 를 자주 되 돌려 주 고 가끔 몇 번 의 정 보 를 보 여 주 는 데 성공 하 며 잘못된 정 보 를 보고 하지 않 습 니 다.당시 코 타 나 를 향 해 오후 내 내 소 리 를 질 렀 지만 각종 디 버 깅 이 안 되 었 다.나중에 ContentTile Type 을 설 치 했 습 니 다 = VoiceCommand ContentTileType. Title WithText 가 성공 하 였 습 니 다. 구체 적 인 원인 은 아직 밝 혀 지지 않 았 습 니 다. ContentTileType 의 기본 값 이 icon 이 있 는 지 모 르 겠 습 니 다. image 를 찾 지 못 해 오 류 를 알 립 니 다.
2、
사용자 가 어느 관광 지 를 볼 지 선택 할 때 다음 절차 가 귀 찮 습 니 다. 클 라 이언 트 로 돌아 가 작업 을 해 야 합 니 다. 이 때 RequestAppLaunchAsync 를 호출 하여 클 라 이언 트 를 시작 할 수 있 습 니 다. App. xaml. cs 에서 override OnActivated 방법 으로 시작 인 자 를 받 습 니 다.
protected async override void OnActivated(IActivatedEventArgs args)
{
base.OnActivated(args);
shell = Window.Current.Content as AppShell;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (shell == null)
{
// Create a AppShell to act as the navigation context and navigate to the first page
shell = new AppShell();
// Set the default language
shell.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
shell.AppFrame.NavigationFailed += OnNavigationFailed;
}
// Place our app shell in the current Window
Window.Current.Content = shell;
//读写文件一般比较快,几乎不会影响启动性能
CurrentCity = await IsolatedStorageHelper.Instance.GetLastCity();
Window.Current.Activate();
switch (args.Kind)
{
case ActivationKind.VoiceCommand:
{
break;
}
case ActivationKind.Protocol:
{
var command = args as ProtocolActivatedEventArgs;
Windows.Foundation.WwwFormUrlDecoder decoder = new Windows.Foundation.WwwFormUrlDecoder(command.Uri.Query);
var destination = decoder.GetFirstValueByName("LaunchContext");
new MessageDialog(destination).ShowAsync();
InternalJumper.initNoticeUrl(destination);
break;
}
}
}
RequestAppLaunchAsync 의 시작 형식 은 Protocol 입 니 다. args 를 Protocol Activated EventArgs 로 강제로 변환 하여 Uri 인 자 를 가 져 올 수 있 습 니 다.
그러면 문제 가 발생 했 습 니 다. 개발 과정 에서 Request AppLaunchAsync 를 호출 하여 클 라 이언 트 를 시작 할 때마다 응용 프로그램 이 반 짝 이 고 각종 google, bing 도 자 료 를 찾 지 못 했 습 니 다. 마이크로소프트 demo 줄 코드 와 비교 한 후에 야 권한 을 추가 해 야 실시 간 으로 시작 할 수 있 습 니 다.
중요 한 일 은 세 번, 세 번, 세 번 해 야 한다.
추가 후 완벽 하 게 시작 합 니 다.
비고:
VoiceCommand ContentTile 의 Title 은 구분 성 이 있어 야 합 니 다. RequestDisambiguation Async 를 호출 할 때 오류 가 발생 할 수 있 습 니 다.
2. 프런트 시동
계속...
다음으로 전송:https://www.cnblogs.com/NailClipper/articles/4765771.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
독서 노트문제1: 한 파일에 10000000개의 기록이 포함되어 있으며, 각 기록의 내용은 7자리의 정수이다.기록은 중복되지 않는다.파일 내용을 읽는 프로그램이 필요하고, 이 기록을 정렬한 후 파일을 출력해야 하며, 메모리는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.