Compartilhar via


Adicionar recursos de demonstração de varejo (RDX) ao seu aplicativo

Inclua um modo de demonstração de varejo em seu aplicativo do Windows para que os clientes que experimentarem computadores e dispositivos no piso de vendas possam entrar diretamente.

Quando os clientes estão em uma loja de varejo, eles esperam poder experimentar demonstrações de computadores e dispositivos. Eles geralmente passam uma parte considerável de seu tempo brincando com aplicativos através da experiência de demonstração de varejo (RDX).

Você pode configurar seu aplicativo para fornecer experiências diferentes enquanto estiver em modos normais ou de varejo . Por exemplo, se seu aplicativo começar com um processo de configuração, você poderá pular essa etapa no modo lojista e pré-preencher o aplicativo com dados de exemplo e configurações padrão para que possam começar a usar imediatamente.

Do ponto de vista de nossos clientes, há apenas um aplicativo. Para ajudar os clientes a distinguir entre os dois modos, recomendamos que, enquanto seu aplicativo estiver no modo de varejo, ele mostre a palavra "Varejo" em destaque na barra de título ou em um local adequado.

Além dos requisitos da Microsoft Store para aplicativos, os aplicativos RDX-compatíveis também devem ser compatíveis com os processos de configuração, limpeza e atualização do RDX para garantir que os clientes tenham uma experiência consistentemente positiva na loja.

Princípios de design

  • Mostre seu melhor. Use a experiência de demonstração de varejo para mostrar por que seu aplicativo é incrível. Esta é provavelmente a primeira vez que seu cliente verá seu aplicativo, portanto, mostre-lhes a melhor peça!

  • Mostrerápido. Os clientes podem ser impacientes – quanto mais rápido um usuário puder experimentar o valor real do seu aplicativo, melhor.

  • Mantenha a históriasimples. A experiência de demonstração de varejo é uma apresentação curta para destacar o valor do seu aplicativo.

  • Foco na experiência. Dê ao usuário tempo para digerir seu conteúdo. Embora levá-los rapidamente à melhor parte seja importante, criar pausas adequadas pode ajudá-los a aproveitar totalmente a experiência.

Requisitos técnicos

Como os aplicativos com reconhecimento RDX destinam-se a mostrar o melhor do seu aplicativo para clientes de varejo, eles devem atender aos requisitos técnicos e seguir as regulamentações de privacidade que a Microsoft Store tem para todos os aplicativos de experiência de demonstração de varejo.

Isso pode ser usado como uma lista de verificação para ajudá-lo a se preparar para o processo de validação e fornecer clareza no processo de teste. Observe que esses requisitos precisam ser mantidos, não apenas para o processo de validação, mas para todo o tempo de vida do aplicativo de experiência de demonstração de varejo; desde que seu aplicativo permaneça em execução nos dispositivos de demonstração de varejo.

Requisitos críticos

Os aplicativos com reconhecimento RDX que não atendem a esses requisitos críticos serão removidos de todos os dispositivos de demonstração de varejo o mais rápido possível.

  • Não solicite informações de identificação pessoal (PII). Isso inclui informações de logon, informações da conta da Microsoft ou detalhes do contato.

  • experiência sem erros. Seu aplicativo deve ser executado sem erros. Além disso, erros, pop-ups ou notificações não devem ser mostrados aos clientes que estão usando os dispositivos de demonstração de varejo. Os erros refletem negativamente sobre o aplicativo em si, sua marca, a marca do dispositivo, a marca do fabricante do dispositivo e a marca da Microsoft.

  • Aplicativos pagos devem ter um modo de avaliação. Seu aplicativo precisa ser gratuito ou incluir um modo de avaliação . Os clientes não estão procurando pagar por uma experiência em uma loja de varejo.

Requisitos de alta prioridade

Aplicativos com reconhecimento RDX que não atendem a esses requisitos de alta prioridade precisam ser investigados para uma correção imediatamente. Se nenhuma correção imediata for encontrada, esse aplicativo poderá ser removido de todos os dispositivos de demonstração de varejo.

  • experiência offline memorável. Seu aplicativo precisa demonstrar uma ótima experiência offline, pois cerca de 50% dos dispositivos estão offline em locais de varejo. Isso é para garantir que os clientes que interagem com seu aplicativo offline ainda possam ter uma experiência significativa e positiva.

  • experiência de conteúdo atualizada. Seu aplicativo nunca deve ser solicitado a receber atualizações quando estiver online. Se forem necessárias atualizações, elas deverão ser executadas silenciosamente.

  • Sem comunicação anônima Como um cliente que usa um dispositivo de demonstração de varejo é um usuário anônimo, ele não deve ser capaz de enviar mensagens ou compartilhar conteúdo do dispositivo.

  • Entregar experiências consistentes usando o processo de limpeza. Cada cliente deve ter a mesma experiência quando chegar a um dispositivo de demonstração de varejo. Seu aplicativo deve usar processo de limpeza para retornar ao mesmo estado padrão após cada uso. Não queremos que o próximo cliente veja o que o último cliente deixou para trás. Isso inclui placares, conquistas e desbloqueios.

  • Conteúdo apropriado para a idade. Todo o conteúdo do aplicativo precisa ser atribuído a uma categoria de classificação Adolescente ou inferior. Para saber mais, consulte Consiga a avaliação do seu aplicativo pela IARC e classificação ESRB.

Requisitos de prioridade média

A equipe da Windows Retail Store pode entrar em contato com os desenvolvedores diretamente para configurar uma discussão sobre como corrigir esses problemas.

  • capacidade de funcionar com sucesso em uma variedade de dispositivos. Os aplicativos devem ser executados bem em todos os dispositivos, incluindo dispositivos com especificações low-end. Se o aplicativo estiver instalado em dispositivos que não atenderam às especificações mínimas, o aplicativo precisará informar claramente o usuário sobre isso. Os requisitos mínimos do dispositivo devem ser conhecidos para que o aplicativo sempre possa ser executado com alto desempenho.

  • Atender aos requisitos de tamanho de aplicativo da loja de varejo. O aplicativo deve ter menos de 800 MB. Entre em contato com a equipe da Windows Retail Store diretamente para mais discussões se seu aplicativo com reconhecimento RDX não atender aos requisitos de tamanho.

API RetailInfo: Preparando seu código para o modo de demonstração

EstáModoDemoAtivado

A propriedade IsDemoModeEnabled na classe de utilitário RetailInfo, que faz parte do namespace Windows.System.Profile no SDK do Windows 10 e Windows 11, é usada como um indicador booleano para especificar em qual caminho de código seu aplicativo é executado – o modo normal ou o modo de varejo.

using Windows.Storage;

StorageFolder folder = ApplicationData.Current.LocalFolder;

if (Windows.System.Profile.RetailInfo.IsDemoModeEnabled) 
{
    // Use the demo specific directory
    folder = await folder.GetFolderAsync("demo");
}

StorageFile file = await folder.GetFileAsync("hello.txt");
// Now read from file
using namespace Windows::Storage;

StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;

if (Windows::System::Profile::RetailInfo::IsDemoModeEnabled) 
{
    // Use the demo specific directory
    create_task(localFolder->GetFolderAsync("demo").then([this](StorageFolder^ demoFolder)
    {
        return demoFolder->GetFileAsync("hello.txt");
    }).then([this](task<StorageFile^> fileTask)
    {
        StorageFile^ file = fileTask.get();
    });
    // Do something with file
}
else
{
    create_task(localFolder->GetFileAsync("hello.txt").then([this](StorageFile^ file)
    {
        // Do something with file
    });
}
if (Windows.System.Profile.retailInfo.isDemoModeEnabled) {
    console.log("Retail mode is enabled.");
} else {
    Console.log("Retail mode is not enabled.");
}

RetailInfo.Properties

Quando IsDemoModeEnabled retorna true, você pode consultar um conjunto de propriedades sobre o dispositivo usando RetailInfo.Properties para criar uma experiência de demonstração de varejo mais personalizada. Essas propriedades incluem Nome do Fabricante, Tamanho da Tela, Memória e assim por diante.

using Windows.UI.Xaml.Controls;
using Windows.System.Profile

TextBlock priceText = new TextBlock();
priceText.Text = RetailInfo.Properties[KnownRetailInfo.Price];
// Assume infoPanel is a StackPanel declared in XAML
this.infoPanel.Children.Add(priceText);
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::System::Profile;

TextBlock ^manufacturerText = ref new TextBlock();
manufacturerText.set_Text(RetailInfo::Properties[KnownRetailInfoProperties::Price]);
// Assume infoPanel is a StackPanel declared in XAML
this->infoPanel->Children->Add(manufacturerText);
var pro = Windows.System.Profile;
console.log(pro.retailInfo.properties[pro.KnownRetailInfoProperties.price);

IDL

//  Copyright (c) Microsoft Corporation. All rights reserved.
//
//  WindowsRuntimeAPISet

import "oaidl.idl";
import "inspectable.idl";
import "Windows.Foundation.idl";
#include <sdkddkver.h>

namespace Windows.System.Profile
{
    runtimeclass RetailInfo;
    runtimeclass KnownRetailInfoProperties;

    [version(NTDDI_WINTHRESHOLD), uuid(0712C6B8-8B92-4F2A-8499-031F1798D6EF), exclusiveto(RetailInfo)]
    [version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
    interface IRetailInfoStatics : IInspectable
    {
        [propget] HRESULT IsDemoModeEnabled([out, retval] boolean *value);
        [propget] HRESULT Properties([out, retval, hasvariant] Windows.Foundation.Collections.IMapView<HSTRING, IInspectable *> **value);
    }

    [version(NTDDI_WINTHRESHOLD), uuid(50BA207B-33C4-4A5C-AD8A-CD39F0A9C2E9), exclusiveto(KnownRetailInfoProperties)]
    [version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
    interface IKnownRetailInfoPropertiesStatics : IInspectable
    {
        [propget] HRESULT RetailAccessCode([out, retval] HSTRING *value);
        [propget] HRESULT ManufacturerName([out, retval] HSTRING *value);
        [propget] HRESULT ModelName([out, retval] HSTRING *value);
        [propget] HRESULT DisplayModelName([out, retval] HSTRING *value);
        [propget] HRESULT Price([out, retval] HSTRING *value);
        [propget] HRESULT IsFeatured([out, retval] HSTRING *value);
        [propget] HRESULT FormFactor([out, retval] HSTRING *value);
        [propget] HRESULT ScreenSize([out, retval] HSTRING *value);
        [propget] HRESULT Weight([out, retval] HSTRING *value);
        [propget] HRESULT DisplayDescription([out, retval] HSTRING *value);
        [propget] HRESULT BatteryLifeDescription([out, retval] HSTRING *value);
        [propget] HRESULT ProcessorDescription([out, retval] HSTRING *value);
        [propget] HRESULT Memory([out, retval] HSTRING *value);
        [propget] HRESULT StorageDescription([out, retval] HSTRING *value);
        [propget] HRESULT GraphicsDescription([out, retval] HSTRING *value);
        [propget] HRESULT FrontCameraDescription([out, retval] HSTRING *value);
        [propget] HRESULT RearCameraDescription([out, retval] HSTRING *value);
        [propget] HRESULT HasNfc([out, retval] HSTRING *value);
        [propget] HRESULT HasSdSlot([out, retval] HSTRING *value);
        [propget] HRESULT HasOpticalDrive([out, retval] HSTRING *value);
        [propget] HRESULT IsOfficeInstalled([out, retval] HSTRING *value);
        [propget] HRESULT WindowsVersion([out, retval] HSTRING *value);
    }

    [version(NTDDI_WINTHRESHOLD), static(IRetailInfoStatics, NTDDI_WINTHRESHOLD)]
    [version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone), static(IRetailInfoStatics, NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
    [threading(both)]
    [marshaling_behavior(agile)]
    runtimeclass RetailInfo
    {
    }

    [version(NTDDI_WINTHRESHOLD), static(IKnownRetailInfoPropertiesStatics, NTDDI_WINTHRESHOLD)]
    [version(NTDDI_WINTHRESHOLD, Platform.WindowsPhone), static(IKnownRetailInfoPropertiesStatics, NTDDI_WINTHRESHOLD, Platform.WindowsPhone)]
    [threading(both)]
    [marshaling_behavior(agile)]
    runtimeclass KnownRetailInfoProperties
    {
    }
}

Processo de limpeza

A limpeza começa dois minutos depois que um comprador para de interagir com o dispositivo. A demonstração de varejo é executada, e o Windows começa a resetar os dados amostrais nos contatos, fotos e outros aplicativos. Dependendo do dispositivo, isso pode levar entre 1 e 5 minutos para redefinir totalmente tudo de volta ao normal. Isso garante que todos os clientes da loja de varejo possam acessar um dispositivo e ter a mesma experiência ao interagir com o dispositivo.

Etapa 1: Limpeza

  • Todos os aplicativos Win32 e Store estão fechados
  • Todos os arquivos em pastas conhecidas como Pictures, Videos, Music, Documents, SavedPictures, CameraRoll, Desktop e Downloads pastas são excluídos
  • Os estados de roaming não estruturados e estruturados são excluídos
  • Estados locais estruturados são excluídos

Etapa 2: Configuração

  • Para dispositivos offline: as pastas permanecem vazias
  • Para dispositivos online: os conteúdos de demonstração de varejo podem ser transferidos para o dispositivo desde a Microsoft Store.

Armazenar dados em sessões de usuário

Para armazenar dados em sessões de usuário, você pode armazenar informações em ApplicationData.Current.TemporaryFolder pois o processo de limpeza padrão não exclui automaticamente os dados nesta pasta. Observe que as informações armazenadas usando LocalState são excluídas durante o processo de limpeza.

Personalizar o processo de limpeza

Para personalizar o processo de limpeza, implemente o serviço de aplicativo Microsoft-RetailDemo-Cleanup em seu aplicativo.

Cenários em que uma lógica de limpeza personalizada é necessária incluem a execução de uma configuração extensa, o download e o cache de dados ou o desejo de que os dados de LocalState não sejam excluídos.

Etapa 1: declare o serviço Microsoft-RetailDemo-Cleanup no manifesto do aplicativo.

  <Applications>
      <Extensions>
        <uap:Extension Category="windows.appService" EntryPoint="MyCompany.MyApp.RDXCustomCleanupTask">
          <uap:AppService Name="Microsoft-RetailDemo-Cleanup" />
        </uap:Extension>
      </Extensions>
   </Application>
  </Applications>

Etapa 2: Implementar sua lógica de limpeza personalizada na função de caso AppdataCleanup usando o modelo de exemplo abaixo.

using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Threading;
using System.Threading.Tasks;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.Foundation.Collections;
using Windows.Storage;

namespace MyCompany.MyApp
{
    public sealed class RDXCustomCleanupTask : IBackgroundTask
    {
        BackgroundTaskCancellationReason _cancelReason = BackgroundTaskCancellationReason.Abort;
        BackgroundTaskDeferral _deferral = null;
        IBackgroundTaskInstance _taskInstance = null;
        AppServiceConnection _appServiceConnection = null;

        const string MessageCommand = "Command";

        public void Run(IBackgroundTaskInstance taskInstance)
        {
            // Get the deferral object from the task instance, and take a reference to the taskInstance;
            _deferral = taskInstance.GetDeferral();
            _taskInstance = taskInstance;
            _taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);

            AppServiceTriggerDetails appService = _taskInstance.TriggerDetails as AppServiceTriggerDetails;
            if ((appService != null) && (appService.Name == "Microsoft-RetailDemo-Cleanup"))
            {
                _appServiceConnection = appService.AppServiceConnection;
                _appServiceConnection.RequestReceived += _appServiceConnection_RequestReceived;
                _appServiceConnection.ServiceClosed += _appServiceConnection_ServiceClosed;
            }
            else
            {
                _deferral.Complete();
            }
        }

        void _appServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
        {
        }

        async void _appServiceConnection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            //Get a deferral because we will be calling async code
            AppServiceDeferral requestDeferral = args.GetDeferral();
            string command = null;
            var returnData = new ValueSet();

            try
            {
                ValueSet message = args.Request.Message;
                if (message.ContainsKey(MessageCommand))
                {
                    command = message[MessageCommand] as string;
                }

                if (command != null)
                {
                    switch (command)
                    {
                        case "AppdataCleanup":
                            {
                                // Do custom clean up logic here
                                break;
                            }
                    }
                }
            }
            catch (Exception e)
            {
            }
            finally
            {
                requestDeferral.Complete();
                // Also release the task deferral since we only process one request per instance.
                _deferral.Complete();
            }
        }

        private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            _cancelReason = reason;
        }
    }
}