Usando Cortana em background

Recentemente falamos como integrar a Cortana em seu aplicativo e mostramos como usar comandos de voz no primeiro plano (foreground). Nele abordamos que ao identificar algum comando de voz, a Cortana abre seu app para responder pela requisição solicitada.
E se pudéssemos atender ao usuário sem que nossa aplicação fosse aberta?

É isso que mostraremos aqui através de chamadas em segundo plano. Vamos usar comandos de voz que serão tratados pelo nosso aplicativo mas a resposta será apresentada na própria janela da Cortana sem que nosso aplicativo seja aberto.

Assim como no post anterior, usaremos como exemplo o aplicativo HomeControl, responsável por controlar itens de uma casa inteligente como luzes, portas e temperaturas através de comandos de voz interpretados pela Cortana.

Vamos então evoluir o código fonte apresentado anteriormente que está disponível no repositório GIT para trazer essa nova funcionalidade.

Alterando a definição de comandos de voz (VCD)

Neste ponto, devemos ter o Voice Command Definitions (VCD) criado com o nome de HomeControlCommands.xml preparado para as chamadas em primeiro plano. Vamos agora incluir um novo comando que deverá ser tratado em background.

<Command Name="CheckTemperature">
  <Example>Check temperature</Example>
  <ListenFor>check [current] temperature</ListenFor>
  <Feedback>Checking temperature</Feedback>
  <VoiceCommandService Target="VoiceCommandService" />
</Command>

Importante: Diferentemente dos comandos em primeiro plano que podem utilizar o elemento Navigate, aqui devemos usar o VoiceCommandService, especificando o valor do atributo Target com um nome qualquer para nosso serviço. Estamos utilizando aqui o nome VoiceCommandService. Guarde bem esse nome pois ele será usado em breve.

Registrando o VCD no App Startup

Garanta que o VCD criado está sendo registrado na abertura da aplicação através do método App.OnLaunched dentro do arquivo App.xaml.cs.

protected async override void OnLaunched(LaunchActivatedEventArgs e)
{
	...
	// Install the VCD
	try
	{
		StorageFile vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync(@"HomeControlCommands.xml");
		await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);
	}
	catch (Exception ex)
	{
		System.Diagnostics.Debug.WriteLine("There was an error registering the Voice Command Definitions", ex);
	}
}

Criando background task

Até aqui fizemos a Cortana tratar um novo comando através da alteração do VCD e garantimos que este esteja registrado. Precisamos agora preparar nossa app para tratar esse comando em background. Para isso precisamos adicionar um novo projeto do tipo Windows Runtime Component que será responsável por agir em background. Chamaremos esse projeto de CortanaComponent.

usando_cortana_em_background_add_project

Após criado o projeto, vamos adicionar uma nova classe com o nome HomeControlVoiceCommandService.cs. Essa classe deve implementar a interface IBackgroundTask. Além disso ela deve ser public sealed. Essa classe será a responsável por tratar os comandos e fornecer as informações que serão retornadas para a Cortana exibir para o usuário. É exatamente isso que mostraremos no código abaixo:

using System;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.VoiceCommands;

namespace CortanaComponent
{
    public sealed class HomeControlVoiceCommandService : IBackgroundTask
    {
        private VoiceCommandServiceConnection voiceServiceConnection;
        private BackgroundTaskDeferral serviceDeferral;

        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            // Create the deferral by requesting it from the task instance
            serviceDeferral = taskInstance.GetDeferral();

            AppServiceTriggerDetails triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;

            if (triggerDetails != null && triggerDetails.Name.Equals("VoiceCommandService"))
            {
                voiceServiceConnection = VoiceCommandServiceConnection.FromAppServiceTriggerDetails(triggerDetails);

                VoiceCommand voiceCommand = await voiceServiceConnection.GetVoiceCommandAsync();

                // Perform the appropriate command depending on the operation defined in VCD
                switch (voiceCommand.CommandName)
                {
                    case "CheckTemperature":
                        VoiceCommandUserMessage userMessage = new VoiceCommandUserMessage();
                        userMessage.DisplayMessage = "The current temperature is 23 degrees";
                        userMessage.SpokenMessage = "The current temperature is 23 degrees";

                        VoiceCommandResponse response = VoiceCommandResponse.CreateResponse(userMessage, null);
                        await voiceServiceConnection.ReportSuccessAsync(response);
                        break;

                    default:
                        break;
                }
            }

            // Once the asynchronous method(s) are done, close the deferral
            serviceDeferral.Complete();
        }
    }
}

Neste exemplo estamos tratando o comando CheckTemperature que deve retornar uma mensagem bem simples para o usuário indicando a temperatura atual. Além da mensagem mostrada na tela, também estamos indicando para a Cortana “ler” essa mensagem.

Fica faltando agora linkar os projetos. Para isso devemos adicionar o projeto CortanaComponent como referência no projeto HomeControl.

usando_cortana_em_background_add_reference

E para finalizar, precisamos registrar o serviço no Package.appxmanifest.

usando_cortana_em_background_register_service

Na aba Declarations, crie uma nova declaração do tipo App Service. No campo Name, utilize o mesmo nome usado ao criar o novo comando no arquivo HomeControlCommands.xml (valor usado no atributo Target do elemento VoiceCommandService). No campo Entry point utilize o nome completo da classe que implementa IBackgroundTask (nome_do_package.nome_da_classe).

Pronto! Para testar, basta usar a Cortana e usar o comando de voz recém-criado.

Exemplo: HomeControl, check current temperature

usando_cortana_em_background_response

O código fonte do exemplo acima está disponível no repositório GIT oficial do blog talkitbr.

No próximo post, mostraremos outras formas de usar a Cortana em segundo plano através do uso de List views, desambiguation e confirmation. Continue nos seguindo no talkitbr. Até a próxima!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s