Cortanaからアプリをバックグラウンド起動する – VoiceCommandServiceConnection

Cortanaからアプリの操作

UWPではCortanaに事前に音声コマンド定義ファイル(VoiceCommandDefinition)を登録しておくことによってCortanaに特定の言葉を発話させたときにアプリを起動させることができます。

CortanaからUWP起動はフォアグラウンド起動とバックグラウンド起動の2つのパターンがありますが今回はバックグラウンド起動のパターンです。

バックグラウンド起動の場合、アプリはAppServiceという仕組みを通してバックグラウンド起動し、特定の言葉をCortanaにしゃべらせることができます。

VoiceCommandDefinitionファイルを作る

VoiceCommandDefinitionファイルはここ

https://msdn.microsoft.com/ja-jp/library/windows/apps/xaml/dn706593.aspx

の定義に従って作ります。

  • CommandSet – 言語(ja-JP)単位で作ります。多言語対応する場合は複数作成
  • CommandPrefix – 認識したい言葉の前に必ずつけます
  • Example – 発話例
  • Command – 認識したいコマンドを定義。複数定義可
  • Example – 発話例
  • ListenFor – 認識したいコマンドを書きます。[]であってもなくてもよい、{}はPhraseListの中から選択することになります
  • Feedback – 認識完了したときCortanaに言わせる言葉
  • VoiceCommandService– 起動したいアプリのAppServiceを指定します。
<?xml version="1.0" encoding="utf-8" ?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.2">
  <CommandSet xml:lang="ja-JP">
    <CommandPrefix>サンプル</CommandPrefix>
    <Example>サンプル バックグラウンド起動</Example>
    <Command Name="Command1">
      <Example>サンプル バックグラウンド起動</Example>
      <ListenFor>バックグラウンド[起動]{number}</ListenFor>
      <Feedback>認識しました</Feedback>
      <VoiceCommandService Target="VoiceAppService" />
    </Command>
    <PhraseList Label="number">
      <Item> 1 </Item>
      <Item> 2 </Item>
    </PhraseList>
  </CommandSet>
</VoiceCommands>

フォアグラウンド起動の時と違う点は、NavigateがVoiceCommandServiceタグになっていることです。これでTargetに指定したAppServiceを起動することができます。

作ったVCDファイルはXMLとしてプロジェクトに保存しておきます。

VoiceCommandDefinitionファイルの登録

先ほど作ったVCDファイルをCortanaに登録します。

var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///VcdFiles/BackgroundVcd.xml"));
await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(file);

 

AppServiceを作る

新しいプロジェクトからWindowsランタイムコンポーネントを指定します。

1

今回は「CortanaSampleService」というWindowsRuntimeコンポーネントを作成しました。

次に元のUWP側の参照マネージャからさきほど作ったWindowsRuntimeコンポーネントを参照します。

2

マニフェストファイルを編集します。

宣言タブからAppServiceを追加し、名前を「VoiceAppService」、エントリポイントを「CortanaSampleService.SampleVoiceService」としました。

AppServiceを作成する

先ほど作ったWindowsRuntimeComponentに「SampleVoiceService」というクラスを作ります。

namespace CortanaSampleService
{
    public sealed class SampleVoiceService : IBackgroundTask
    {
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            var serviceDeferral = taskInstance.GetDeferral();
            var triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
            if (triggerDetails != null && triggerDetails.Name == "VoiceAppService")
            {
                var voiceServiceConnection = VoiceCommandServiceConnection.FromAppServiceTriggerDetails(triggerDetails);
                var voiceCommand = await voiceServiceConnection.GetVoiceCommandAsync();

                var commandName = voiceCommand.CommandName; //コマンド名
                var number = voiceCommand.SpeechRecognitionResult.SemanticInterpretation.Properties["number"][0];   //{}内のパラメータ
                var status = voiceCommand.SpeechRecognitionResult.Status;   //認識ステータス
                var text = voiceCommand.SpeechRecognitionResult.Text;   //認識した言葉

                //ここにレスポンス処理を書く
               
            }

            serviceDeferral.Complete();
        }
    }
}

これでCortanaにしゃべりかけるとアプリがバックグラウンド起動します。

正常応答を返す

先ほどのSampleVoiceServiceクラスの「ここにレスポンス処理を書く」の部分に以下の処理を書くとCortanaが正常応答を返します。

string responseMessage = "コマンドは正常に処理されました";
var message = new VoiceCommandUserMessage();
message.SpokenMessage = responseMessage;
message.DisplayMessage = responseMessage;

var response = VoiceCommandResponse.CreateResponse(message);
await voiceServiceConnection.ReportSuccessAsync(response);

異常応答を返す

先ほどの「ここにレスポンス処理を書く」の部分にこのような処理を書くと異常応答を返すことができます。

string responseMessage = "コマンドに異常が起きました";
var message = new VoiceCommandUserMessage();
message.SpokenMessage = responseMessage;
message.DisplayMessage = responseMessage;

var response = VoiceCommandResponse.CreateResponse(message);
await voiceServiceConnection.ReportFailureAsync(response);

※図ではわかりにくいですが正常応答の時と音が違います

確認応答

YesかNoの確認応答をする場合は以下のようにします。

//ここにレスポンス処理を書く
string questionMessage = "~処理を実行してもいいですか?";
var messageQuestion = new VoiceCommandUserMessage();
messageQuestion.SpokenMessage = questionMessage;
messageQuestion.DisplayMessage = questionMessage;

string responseMessage = "了解しました";
var messageResponse = new VoiceCommandUserMessage();
messageResponse.SpokenMessage = responseMessage;
messageResponse.DisplayMessage = responseMessage;

var response = VoiceCommandResponse.CreateResponseForPrompt(messageQuestion, messageResponse);
var result = await voiceServiceConnection.RequestConfirmationAsync(response);

if (result.Confirmed)
{
    //Yes
}
else
{
    //No
}

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください