2016-03-01 15 views
0

我想實現柯塔娜到我的應用程序,所以當用戶說「嘿柯塔娜,在測試應用程式閱讀一步一個」應用程序將讀取一個列表框的第一個元素。我遇到的問題是,當我說這個時,應用程序只是用我說的句子打開一個bing網頁。UWP柯塔娜不登記應用命令

<?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; 
     } 
    } 
+0

在代碼中,你捕捉異常,如果有註冊的語音命令定義一個錯誤,你確定你已經成功註冊了你的vcd文件?你的代碼在我身邊工作的很好,cortana會在短時間內啓動應用程序,然後關閉它,因爲你錯過了'OnActivated(IActivatedEventArgs e)'方法末尾的'Window.Current.Activate();',或者你打算這麼做嗎? –

+0

您好我設法讓Cortana實際上識別應用程序,但是當它到達線頁面.stepOne()應用程序崩潰爲「對象引用未設置爲對象的實例」。頁面值爲null,但類型爲App2.Page1。 – myf33tsmell

+0

在我身邊,頁面值是'MainPage',而它是'Page1'在你身邊,但忘記了這一點,在你的代碼中,如果'page'爲null,它將返回,這個錯誤不應該發生。問題實際上是在你的App2.Page1的StepOne()方法中,而且我沒有測試這個方法,這個錯誤依然不會發生在我身邊,請發佈這個代碼方法。 –

回答

0

我收到了你的問題,你的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(); 
} 

MainPage.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 L代碼IKE在此:

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)方法在這樣的MainPage.cs:

public void StepOne(int i) 
{ 
    readText(SteplistBox.Items[i].ToString()); 
} 
+0

感謝您的幫助,雖然我已經在使用的OnNavigatedTo方法來檢索從SQLite數據庫列表框中的數據,所以,當我嘗試實現這一點,應用程序將在嘗試使用e.Parameter崩潰,這將正常工作對於另一個例子,我使用它。希望我的問題是明確的,有辦法做到這一點。 – myf33tsmell

+0

@ myf33tsmell,很容易將我的代碼更改爲不使用e.Parameter ...請參閱我的更新代碼。 –

+0

謝謝我在另一個應用程序中嘗試了這一點,它的工作原理,但這幫助我解決了我的應用程序的問題。在我的應用程序中導航到我使用的主頁:var user = e.ClickedItem as SQLTable;這個.Frame.Navigate(typeof(MainPage),user.ID.ToString());所以當我嘗試使用cortana時,它導航到一個空的主頁,而不是一個傳遞了sql信息來填充列表框。林不知道這可以排序,但它仍然有很多幫助。 – myf33tsmell