UWP Cortana 未注册应用命令
本文关键字:应用 命令 注册 Cortana UWP | 更新日期: 2023-09-27 18:36:53
我正在尝试将 Cortana 实现到我的应用,因此当用户说"你好小娜,在测试应用中阅读第一步"时,应用将从列表框中读取第一个元素。我遇到的问题是,当我这样说时,应用程序只是打开一个带有我说的句子的必应网页。
<?xml version="1.0" encoding="utf-8" ?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.1">
<CommandSet xml:lang="en-US" Name="CommandSet_en-US">
<CommandPrefix> Test App</CommandPrefix>
<Example> read step one </Example>
<Command Name="step">
<Example> read step one </Example>
<ListenFor> read step {number} </ListenFor>
<Feedback> Reading Instruction </Feedback>
<Navigate Target="Page1"/>
</Command>
<PhraseList Label= "number">
<Item> one </Item>
<Item> two </Item>
</PhraseList>
</CommandSet>
</VoiceCommands>
在 app.xaml.cs:
protected async override void OnLaunched(LaunchActivatedEventArgs e)
//code
Window.Current.Activate();
}
try
{
StorageFile vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync( @"CortanaCommands.xml");
await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("There was an error Registering the Voice Command Definitions", ex);
}
}
protected override void OnActivated(IActivatedEventArgs e)
{
if (e.Kind != Windows.ApplicationModel.Activation.ActivationKind.VoiceCommand)
{
return;
}
var commandArgs = e as Windows.ApplicationModel.Activation.VoiceCommandActivatedEventArgs;
var speechRecognitionResult = commandArgs.Result;
string voiceCommandName = speechRecognitionResult.RulePath[0];
string textSpoken = speechRecognitionResult.Text;
string spokenStep = "";
try
{
spokenStep = speechRecognitionResult.SemanticInterpretation.Properties["number"][0];
}
catch
{
}
Frame rootFrame = Window.Current.Content as Frame;
MainPage page = rootFrame.Content as MainPage;
if (page == null)
{
return;
}
switch (spokenStep)
{
case "one":
page.Count1 = 0;
break;
default:
//no match
break;
}
switch (voiceCommandName)
{
case "step":
page.StepOne();
break;
default:
break;
}
}
我遇到了你的问题,你的StepOne
方法是这样的:
public void StepOne(int count1) { readText(SteplistBox.Items[count1].ToString()); }
此方法中有一个参数,但你像这样调用此方法:page.StepOne();
此方法中没有参数。请注意,StepOne()
方法和StepOne(int i)
是两种不同的方法。
这个问题可能是一个错字,但我假设你想做的是使用 Cortana 打开你的应用程序并根据语音命令从MainPage
读取ListBox
项目。加上我的评论中可能存在的问题,在这里我为您写了一个示例:
App.xaml.cs 代码:
private string count = null;
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.VoiceCommand)
{
VoiceCommandActivatedEventArgs vargs = (VoiceCommandActivatedEventArgs)args;
SpeechRecognitionResult res = vargs.Result;
string cmdName = res.RulePath[0];
if (cmdName == "step")
{
var interpretation = res.SemanticInterpretation;
string item = interpretation.Properties["number"].FirstOrDefault();
if (!string.IsNullOrEmpty(item))
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
switch (item)
{
case "one":
count = "one";
break;
case "two":
count = "two";
break;
default:
count = null;
break;
}
rootFrame.Navigate(typeof(MainPage), count);
}
}
}
count = null;
Window.Current.Activate();
}
主页.cs代码:
public void StepOne(int i)
{
readText(SteplistBox.Items[i].ToString());
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.Parameter != null)
{
if ((string)e.Parameter == "one")
{
StepOne(0);
}
else if ((string)e.Parameter == "two")
{
StepOne(1);
}
}
}
更新
如果不想使用主页OnNavigatedTo
方法和e.Patameter
,可以更改 App.xaml 中的代码.cs如下所示:
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.VoiceCommand)
{
VoiceCommandActivatedEventArgs vargs = (VoiceCommandActivatedEventArgs)args;
SpeechRecognitionResult res = vargs.Result;
string cmdName = res.RulePath[0];
if (cmdName == "step")
{
var interpretation = res.SemanticInterpretation;
string item = interpretation.Properties["number"].FirstOrDefault();
if (!string.IsNullOrEmpty(item))
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
rootFrame.Navigate(typeof(MainPage));
MainPage page = rootFrame.Content as MainPage;
switch (item)
{
case "one":
page.StepOne(0);
break;
case "two":
page.StepOne(1);
break;
default:
break;
}
}
}
}
Window.Current.Activate();
}
并将StepOne(int i)
方法保留在主页中.cs如下所示:
public void StepOne(int i)
{
readText(SteplistBox.Items[i].ToString());
}