Interagir com um app em segundo plano na CortanaInteract with a background app in Cortana

Aviso

Este recurso não tem mais suporte a partir do Windows 10 pode ser 2020 atualização (versão 2004, codinome "20H1").This feature is no longer supported as of the Windows 10 May 2020 Update (version 2004, codename "20H1").

Consulte Cortana no Microsoft 365 para saber como a Cortana está transformando experiências de produtividade moderna.See Cortana in Microsoft 365 for how Cortana is transforming modern productivity experiences.

Habilite a interação do usuário com um aplicativo em segundo plano, por meio de entrada de texto e de fala na tela da Cortana , ao executar um comando de voz.Enable user interaction with a background app, through speech and text input in the Cortana canvas, while executing a voice command.

A Cortana dá suporte a um fluxo de trabalho de ativação por ativação completo com seu aplicativo.Cortana supports a complete turn-by-turn workflow with your app. Esse fluxo de trabalho é definido pelo seu aplicativo e pode oferecer suporte a funcionalidades como:This workflow is defined by your app, and can support functionality such as:

  • Conclusão bem-sucedidaSuccessful completion
  • EntregaHand-off
  • ProgressoProgress
  • ConfirmaçãoConfirmation
  • DesambiguidadeDisambiguation
  • ErroError

Compondo cadeias de comentáriosComposing feedback strings

Dica

Pré-requisitosPrerequisites

Se você for iniciante no desenvolvimento de aplicativos da Plataforma Universal do Windows (UWP), consulte estes tópicos para familiarizar-se com as tecnologias discutidas aqui.If you're new to developing Universal Windows Platform (UWP) apps, have a look through these topics to get familiar with the technologies discussed here.

Diretrizes de experiência do usuárioUser experience guidelines

Consulte diretrizes de design da Cortana para obter informações sobre como integrar seu aplicativo com a Cortana e interações de fala para obter dicas úteis sobre a criação de um aplicativo habilitado para fala útil e envolvente.See Cortana design guidelines for info about how to integrate your app with Cortana and Speech interactions for helpful tips on designing a useful and engaging speech-enabled app.

Compor as cadeias de caracteres de comentários que são exibidas e faladas pela Cortana.Compose the feedback strings that are both displayed and spoken by Cortana.

As diretrizes de design da Cortana fornecem recomendações sobre como compor cadeias de caracteres para Cortana.The Cortana design guidelines provides recommendations on composing strings for Cortana.

Os cartões de conteúdo podem fornecer contexto adicional para o usuário e ajudá-lo a manter as cadeias de comentários concisas.Content cards can provide additional context for the user and help you keep feedback strings concise.

A Cortana dá suporte aos seguintes modelos de cartão de conteúdo (apenas um modelo pode ser usado na tela de conclusão):Cortana supports the following content card templates (only one template can be used on the completion screen):

  • Somente títuloTitle only
  • Título com até três linhas de textoTitle with up to three lines of text
  • Título com imagemTitle with image
  • Título com imagem e até três linhas de textoTitle with image and up to three lines of text

A imagem pode ser:The image can be:

  • 68W x 68h68w x 68h
  • 68W x 92h68w x 92h
  • 280W x 140h280w x 140h

Você também pode permitir que os usuários iniciem seu aplicativo em primeiro plano clicando em um cartão ou no link de texto para seu aplicativo.You can also let users launch your app in the foreground by clicking either a card or the text link to your app.

Tela de conclusãoCompletion screen

Uma tela de conclusão fornece ao usuário informações sobre a tarefa de comando de voz concluída.A completion screen provides the user with information about the completed voice command task.

As tarefas que levam menos de 500 milissegundos para que seu aplicativo responda e não exigem informações adicionais do usuário, são concluídas sem interação adicional com o Cortana.Tasks that take less than 500 milliseconds for your app to respond, and require no additional information from the user, are completed without further interaction with Cortana. A Cortana simplesmente exibe a tela de conclusão.Cortana simply displays the completion screen.

Aqui, usamos o aplicativo Adventure Works para mostrar a tela de conclusão de uma solicitação de comando de voz para exibir viagens futuras a Londres.Here, we use the Adventure Works app to show the completion screen for a voice command request to display upcoming trips to London.

Captura de tela da conclusão do aplicativo em segundo plano da Cortana para uma próxima viagem

O comando de voz é definido em AdventureWorksCommands.xml:The voice command is defined in AdventureWorksCommands.xml:

<Command Name="whenIsTripToDestination">
  <Example> When is my trip to Las Vegas?</Example>
  <ListenFor RequireAppName="BeforeOrAfterPhrase"> when is [my] trip to {destination}</ListenFor>
  <ListenFor RequireAppName="ExplicitlySpecified"> when is [my] {builtin:AppName} trip to {destination} </ListenFor>
  <Feedback> Looking for trip to {destination}</Feedback>
  <VoiceCommandService Target="AdventureWorksVoiceCommandService"/>
</Command>

AdventureWorksVoiceCommandService.cs contém o método de mensagem de conclusão:AdventureWorksVoiceCommandService.cs contains the completion message method:

/// <summary>
/// Show details for a single trip, if the trip can be found. 
/// This demonstrates a simple response flow in Cortana.
/// </summary>
/// <param name="destination">The destination, expected to be in the phrase list.</param>
private async Task SendCompletionMessageForDestination(string destination)
{
    // If this operation is expected to take longer than 0.5 seconds, the task must
    // supply a progress response to Cortana before starting the operation, and
    // updates must be provided at least every 5 seconds.
    string loadingTripToDestination = string.Format(
               cortanaResourceMap.GetValue("LoadingTripToDestination", cortanaContext).ValueAsString,
               destination);
    await ShowProgressScreen(loadingTripToDestination);
    Model.TripStore store = new Model.TripStore();
    await store.LoadTrips();

    // Query for the specified trip. 
    // The destination should be in the phrase list. However, there might be  
    // multiple trips to the destination. We pick the first.
    IEnumerable<Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);

    var userMessage = new VoiceCommandUserMessage();
    var destinationsContentTiles = new List<VoiceCommandContentTile>();
    if (trips.Count() == 0)
    {
        string foundNoTripToDestination = string.Format(
               cortanaResourceMap.GetValue("FoundNoTripToDestination", cortanaContext).ValueAsString,
               destination);
        userMessage.DisplayMessage = foundNoTripToDestination;
        userMessage.SpokenMessage = foundNoTripToDestination;
    }
    else
    {
        // Set plural or singular title.
        string message = "";
        if (trips.Count() > 1)
        {
            message = cortanaResourceMap.GetValue("PluralUpcomingTrips", cortanaContext).ValueAsString;
        }
        else
        {
            message = cortanaResourceMap.GetValue("SingularUpcomingTrip", cortanaContext).ValueAsString;
        }
        userMessage.DisplayMessage = message;
        userMessage.SpokenMessage = message;

        // Define a tile for each destination.
        foreach (Model.Trip trip in trips)
        {
            int i = 1;
            
            var destinationTile = new VoiceCommandContentTile();

            destinationTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
            destinationTile.Image = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///AdventureWorks.VoiceCommands/Images/GreyTile.png"));

            destinationTile.AppLaunchArgument = trip.Destination;
            destinationTile.Title = trip.Destination;
            if (trip.StartDate != null)
            {
                destinationTile.TextLine1 = trip.StartDate.Value.ToString(dateFormatInfo.LongDatePattern);
            }
            else
            {
                destinationTile.TextLine1 = trip.Destination + " " + i;
            }

            destinationsContentTiles.Add(destinationTile);
            i++;
        }
    }

    var response = VoiceCommandResponse.CreateResponse(userMessage, destinationsContentTiles);

    if (trips.Count() > 0)
    {
        response.AppLaunchArgument = destination;
    }

    await voiceServiceConnection.ReportSuccessAsync(response);
}

Tela de entregaHand-off screen

Depois que um comando de voz é reconhecido, a Cortana deve chamar ReportSuccessAsync e apresentar comentários em aproximadamente 500If o serviço de aplicativo não pode concluir a ação especificada pelo comando de voz dentro de 500 MS, a Cortana apresenta uma tela de entrega que é mostrada até que seu aplicativo chame ReportSuccessAsync ou por até 5 segundos.Once a voice command is recognized, Cortana must call ReportSuccessAsync and present feedback within approximately 500If the app service cannot complete the action specified by the voice command within 500ms, Cortana presents a hand-off screen that is shown until your app calls ReportSuccessAsync, or for up to 5 seconds.

Se o serviço de aplicativo não chamar ReportSuccessAsync ou qualquer outro método VoiceCommandServiceConnection, o usuário receberá uma mensagem de erro e a chamada do serviço de aplicativo será cancelada.If the app service doesn’t call ReportSuccessAsync, or any other VoiceCommandServiceConnection method, the user receives an error message and the app service call is cancelled.

Aqui está um exemplo de uma tela de entrega para o aplicativo Adventure Works .Here's an example of a hand-off screen for the Adventure Works app. Neste exemplo, um usuário consultou a Cortana para futuras viagens.In this example, a user has queried Cortana for upcoming trips. A tela de entrega inclui uma mensagem personalizada com o nome do serviço de aplicativo, um ícone e uma cadeia de caracteres de comentários .The hand-off screen includes a message customized with the app service name, an icon, and a Feedback string.

[!NOTE] Você pode declarar uma cadeia de caracteres de comentários no arquivo VCD.You can declare a Feedback string in the VCD file. Essa cadeia de caracteres não afeta o texto da interface do usuário exibido na tela da Cortana, afeta apenas o texto falado pelo Cortana.This string does not affect the UI text displayed on the Cortana canvas, it only affects the text spoken by Cortana.

Captura de tela do aplicativo em segundo plano da Cortana

Tela de progressoProgress screen

Se o serviço de aplicativo levar mais de 500 ms para chamar ReportSuccessAsync, a Cortana fornecerá ao usuário uma tela de progresso.If the app service takes more than 500ms to call ReportSuccessAsync, Cortana provides the user with a progress screen. O ícone do aplicativo é exibido e você deve fornecer as cadeias de caracteres de andamento de GUI e TTS para indicar que a tarefa está sendo manipulada ativamente.The app icon is displayed, and you must provide both GUI and TTS progress strings to indicate that the task is being actively handled.

A Cortana mostra uma tela de progresso por um máximo de 5 segundos.Cortana shows a progress screen for a maximum of 5 seconds. Após 5 segundos, a Cortana apresenta uma mensagem de erro ao usuário e o serviço de aplicativo é fechado.After 5 seconds, Cortana presents the user with an error message and the app service is closed. Se o serviço de aplicativo precisar de mais de 5 segundos para concluir a ação, ele poderá continuar atualizando a Cortana com telas de progresso.If the app service needs more than 5 seconds to complete the action, it can continue to update Cortana with progress screens.

Aqui está um exemplo de uma tela de progresso para o aplicativo Adventure Works .Here's an example of a progress screen for the Adventure Works app. Neste exemplo, um usuário cancelou uma viagem para Las Vegas.In this example, a user has canceled a trip to Las Vegas. A tela de progresso inclui uma mensagem personalizada para a ação, um ícone e um bloco de conteúdo com informações sobre a viagem sendo cancelada.The progress screen includes a message customized for the action, an icon, and a content tile with information about the trip being canceled.

Captura de tela de exibição da Cortana com aplicativo em segundo plano

AdventureWorksVoiceCommandService.cs contém o seguinte método de mensagem de progresso, que chama ReportProgressAsync para mostrar a tela de progresso no Cortana.AdventureWorksVoiceCommandService.cs contains the following progress message method, which calls ReportProgressAsync to show the progress screen in Cortana.

/// <summary>
/// Show a progress screen. These should be posted at least every 5 seconds for a 
/// long-running operation.
/// </summary>
/// <param name="message">The message to display, relating to the task being performed.</param>
/// <returns></returns>
private async Task ShowProgressScreen(string message)
{
    var userProgressMessage = new VoiceCommandUserMessage();
    userProgressMessage.DisplayMessage = userProgressMessage.SpokenMessage = message;

    VoiceCommandResponse response = VoiceCommandResponse.CreateResponse(userProgressMessage);
    await voiceServiceConnection.ReportProgressAsync(response);
}

Tela de confirmaçãoConfirmation screen

Quando uma ação especificada por um comando de voz é irreversível, tem um impacto significativo ou a confiança de reconhecimento não é alta, um serviço de aplicativo pode solicitar confirmação.When an action specified by a voice command is irreversible, has a significant impact, or the recognition confidence is not high, an app service can request confirmation.

Aqui está um exemplo de uma tela de confirmação para o aplicativo Adventure Works .Here's an example of a confirmation screen for the Adventure Works app. Neste exemplo, um usuário instruiu o serviço de aplicativo para cancelar uma viagem para Las Vegas por meio da Cortana.In this example, a user has instructed the app service to cancel a trip to Las Vegas through Cortana. O serviço de aplicativo forneceu a Cortana com uma tela de confirmação que solicita ao usuário uma resposta Sim ou não antes de cancelar a viagem.The app service has provided Cortana with a confirmation screen that prompts the user for a yes or no answer before canceling the trip.

Se o usuário disser algo diferente de "Sim" ou "não", a Cortana não pode determinar a resposta para a pergunta.If the user says something other than "Yes" or "No", Cortana cannot determine the answer to the question. Nesse caso, a Cortana solicita ao usuário uma pergunta semelhante fornecida pelo serviço de aplicativo.In this case, Cortana prompts the user with a similar question provided by the app service.

No segundo prompt, se o usuário ainda não disser "Sim" ou "não", a Cortana solicitará ao usuário uma terceira vez com a mesma pergunta prefixada com um desculpa.On the second prompt, if the user still doesn’t say "Yes" or "No", Cortana prompts the user a third time with the same question prefixed with an apology. Se o usuário ainda não disser "Sim" ou "não", a Cortana interromperá a escuta de entrada de voz e solicitará que o usuário toque em um dos botões.If the user still doesn’t say "Yes" or "No", Cortana stops listening for voice input and asks the user to tap one of the buttons instead.

A tela de confirmação inclui uma mensagem personalizada para a ação, um ícone e um bloco de conteúdo com informações sobre a viagem sendo cancelada.The confirmation screen includes a message customized for the action, an icon, and a content tile with information about the trip being canceled.

Captura de tela da exibição de confirmação da Cortana com aplicativo em segundo plano

AdventureWorksVoiceCommandService.cs contém o seguinte método de cancelamento de viagem, que chama RequestConfirmationAsync para mostrar uma tela de confirmação no Cortana.AdventureWorksVoiceCommandService.cs contains the following trip cancellation method, which calls RequestConfirmationAsync to show a confirmation screen in Cortana.

/// <summary>
/// Handle the Trip Cancellation task. This task demonstrates how to prompt a user
/// for confirmation of an operation, show users a progress screen while performing
/// a long-running task, and show a completion screen.
/// </summary>
/// <param name="destination">The name of a destination.</param>
/// <returns></returns>
private async Task SendCompletionMessageForCancellation(string destination)
{
    // Begin loading data to search for the target store. 
    // Consider inserting a progress screen here, in order to prevent Cortana from timing out. 
    string progressScreenString = string.Format(
        cortanaResourceMap.GetValue("ProgressLookingForTripToDest", cortanaContext).ValueAsString,
        destination);
    await ShowProgressScreen(progressScreenString);

    Model.TripStore store = new Model.TripStore();
    await store.LoadTrips();

    IEnumerable<Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);
    Model.Trip trip = null;
    if (trips.Count() > 1)
    {
        // If there is more than one trip, provide a disambiguation screen.
        // However, if a significant number of items are returned, you might want to 
        // just display a link to your app and provide a deeper search experience.
        string disambiguationDestinationString = string.Format(
            cortanaResourceMap.GetValue("DisambiguationWhichTripToDest", cortanaContext).ValueAsString,
            destination);
        string disambiguationRepeatString = cortanaResourceMap.GetValue("DisambiguationRepeat", cortanaContext).ValueAsString;
        trip = await DisambiguateTrips(trips, disambiguationDestinationString, disambiguationRepeatString);
    }
    else
    {
        trip = trips.FirstOrDefault();
    }

    var userPrompt = new VoiceCommandUserMessage();
    
    VoiceCommandResponse response;
    if (trip == null)
    {
        var userMessage = new VoiceCommandUserMessage();
        string noSuchTripToDestination = string.Format(
            cortanaResourceMap.GetValue("NoSuchTripToDestination", cortanaContext).ValueAsString,
            destination);
        userMessage.DisplayMessage = userMessage.SpokenMessage = noSuchTripToDestination;

        response = VoiceCommandResponse.CreateResponse(userMessage);
        await voiceServiceConnection.ReportSuccessAsync(response);
    }
    else
    {
        // Prompt the user for confirmation that this is the correct trip to cancel.
        string cancelTripToDestination = string.Format(
            cortanaResourceMap.GetValue("CancelTripToDestination", cortanaContext).ValueAsString,
            destination);
        userPrompt.DisplayMessage = userPrompt.SpokenMessage = cancelTripToDestination;
        var userReprompt = new VoiceCommandUserMessage();
        string confirmCancelTripToDestination = string.Format(
            cortanaResourceMap.GetValue("ConfirmCancelTripToDestination", cortanaContext).ValueAsString,
            destination);
        userReprompt.DisplayMessage = userReprompt.SpokenMessage = confirmCancelTripToDestination;
        
        response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt);

        var voiceCommandConfirmation = await voiceServiceConnection.RequestConfirmationAsync(response);

        // If RequestConfirmationAsync returns null, Cortana has likely been dismissed.
        if (voiceCommandConfirmation != null)
        {
            if (voiceCommandConfirmation.Confirmed == true)
            {
                string cancellingTripToDestination = string.Format(
               cortanaResourceMap.GetValue("CancellingTripToDestination", cortanaContext).ValueAsString,
               destination);
                await ShowProgressScreen(cancellingTripToDestination);

                // Perform the operation to remove the trip from app data. 
                // As the background task runs within the app package of the installed app,
                // we can access local files belonging to the app without issue.
                await store.DeleteTrip(trip);

                // Provide a completion message to the user.
                var userMessage = new VoiceCommandUserMessage();
                string cancelledTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("CancelledTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userMessage.DisplayMessage = userMessage.SpokenMessage = cancelledTripToDestination;
                response = VoiceCommandResponse.CreateResponse(userMessage);
                await voiceServiceConnection.ReportSuccessAsync(response);
            }
            else
            {
                // Confirm no action for the user.
                var userMessage = new VoiceCommandUserMessage();
                string keepingTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("KeepingTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userMessage.DisplayMessage = userMessage.SpokenMessage = keepingTripToDestination;

                response = VoiceCommandResponse.CreateResponse(userMessage);
                await voiceServiceConnection.ReportSuccessAsync(response);
            }
        }
    }
}

Tela de desambiguidadeDisambiguation screen

Quando uma ação especificada por um comando de voz tem mais de um resultado possível, um serviço de aplicativo pode solicitar mais informações do usuário.When an action specified by a voice command has more than one possible outcome, an app service can request more info from the user.

Aqui está um exemplo de uma tela de desambiguidade para o aplicativo Adventure Works .Here's an example of a disambiguation screen for the Adventure Works app. Neste exemplo, um usuário instruiu o serviço de aplicativo para cancelar uma viagem para Las Vegas por meio da Cortana.In this example, a user has instructed the app service to cancel a trip to Las Vegas through Cortana. No entanto, o usuário tem duas viagens para Las Vegas em datas diferentes e o serviço de aplicativo não pode concluir a ação sem que o usuário selecione a viagem desejada.However, the user has two trips to Las Vegas on different dates and the app service cannot complete the action without the user selecting the intended trip.

O serviço de aplicativo fornece à Cortana uma tela de desambiguação que solicita que o usuário faça uma seleção de uma lista de viagens de correspondência, antes de cancelar qualquer uma.The app service provides Cortana with a disambiguation screen that prompts the user to make a selection from a list of matching trips, before it cancels any.

Nesse caso, a Cortana solicita ao usuário uma pergunta semelhante fornecida pelo serviço de aplicativo.In this case, Cortana prompts the user with a similar question provided by the app service.

No segundo prompt, se o usuário ainda não disser algo que possa ser usado para identificar a seleção, o Cortana solicitará ao usuário uma terceira vez com a mesma pergunta prefixada com um desculpa.On the second prompt, if the user still doesn’t say something that can be used to identify the selection, Cortana prompts the user a third time with the same question prefixed with an apology. Se o usuário ainda não disser algo que possa ser usado para identificar a seleção, a Cortana interromperá a escuta de entrada de voz e solicitará que o usuário toque em um dos botões.If the user still doesn’t say something that can be used to identify the selection, Cortana stops listening for voice input and asks the user to tap one of the buttons instead.

A tela de Desambigüidade inclui uma mensagem personalizada para a ação, um ícone e um bloco de conteúdo com informações sobre a viagem sendo cancelada.The disambiguation screen includes a message customized for the action, an icon, and a content tile with information about the trip being canceled.

Captura de tela da exibição de desambiguação do aplicativo em segundo plano

AdventureWorksVoiceCommandService.cs contém o seguinte método de cancelamento de viagem, que chama RequestDisambiguationAsync para mostrar a tela de desambiguidade no Cortana.AdventureWorksVoiceCommandService.cs contains the following trip cancellation method, which calls RequestDisambiguationAsync to show the disambiguation screen in Cortana.

/// <summary>
/// Provide the user with a way to identify which trip to cancel. 
/// </summary>
/// <param name="trips">The set of trips</param>
/// <param name="disambiguationMessage">The initial disambiguation message</param>
/// <param name="secondDisambiguationMessage">Repeat prompt retry message</param>
private async Task<Model.Trip> DisambiguateTrips(IEnumerable<Model.Trip> trips, string disambiguationMessage, string secondDisambiguationMessage)
{
    // Create the first prompt message.
    var userPrompt = new VoiceCommandUserMessage();
    userPrompt.DisplayMessage =
        userPrompt.SpokenMessage = disambiguationMessage;

    // Create a re-prompt message if the user responds with an out-of-grammar response.
    var userReprompt = new VoiceCommandUserMessage();
    userReprompt.DisplayMessage =
        userReprompt.SpokenMessage = secondDisambiguationMessage;

    // Create card for each item. 
    var destinationContentTiles = new List<VoiceCommandContentTile>();
    int i = 1;
    foreach (Model.Trip trip in trips)
    {
        var destinationTile = new VoiceCommandContentTile();

        destinationTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
        destinationTile.Image = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///AdventureWorks.VoiceCommands/Images/GreyTile.png"));
        
        // The AppContext can be any arbitrary object.
        destinationTile.AppContext = trip;
        string dateFormat = "";
        if (trip.StartDate != null)
        {
            dateFormat = trip.StartDate.Value.ToString(dateFormatInfo.LongDatePattern);
        }
        else
        {
            // The app allows a trip to have no date.
            // However, the choices must be unique so they can be distinguished.
            // Here, we add a number to identify them.
            dateFormat = string.Format("{0}", i);
        } 

        destinationTile.Title = trip.Destination + " " + dateFormat;
        destinationTile.TextLine1 = trip.Description;

        destinationContentTiles.Add(destinationTile);
        i++;
    }

    // Cortana handles re-prompting if no valid response.
    var response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt, destinationContentTiles);

    // If cortana is dismissed in this operation, null is returned.
    var voiceCommandDisambiguationResult = await
        voiceServiceConnection.RequestDisambiguationAsync(response);
    if (voiceCommandDisambiguationResult != null)
    {
        return (Model.Trip)voiceCommandDisambiguationResult.SelectedItem.AppContext;
    }

    return null;
}

Tela de erroError screen

Quando uma ação especificada por um comando de voz não pode ser concluída, um serviço de aplicativo pode fornecer uma tela de erro.When an action specified by a voice command cannot be completed, an app service can provide an error screen.

Aqui está um exemplo de uma tela de erro para o aplicativo Adventure Works .Here's an example of an error screen for the Adventure Works app. Neste exemplo, um usuário instruiu o serviço de aplicativo para cancelar uma viagem para Las Vegas por meio da Cortana.In this example, a user has instructed the app service to cancel a trip to Las Vegas through Cortana. No entanto, o usuário não tem nenhuma viagem agendada para Las Vegas.However, the user does not have any trips scheduled to Las Vegas.

O serviço de aplicativo fornece à Cortana uma tela de erro que inclui uma mensagem personalizada para a ação, um ícone e a mensagem de erro específica.The app service provides Cortana with an error screen that includes a message customized for the action, an icon, and the specific error message.

Chame ReportFailureAsync para mostrar a tela de erro no Cortana.Call ReportFailureAsync to show the error screen in Cortana.

var userMessage = new VoiceCommandUserMessage();
    userMessage.DisplayMessage = userMessage.SpokenMessage = 
      "Sorry, you don't have any trips to Las Vegas";
                
    var response = VoiceCommandResponse.CreateResponse(userMessage);

    response.AppLaunchArgument = "showUpcomingTrips";
    await voiceServiceConnection.ReportFailureAsync(response);