Adicionar recursos de demonstração (RDX) do varejo ao seu aplicativo
Inclua um modo de demonstração de varejo em seu aplicativo do Windows para que os clientes que experimentarem PCs e dispositivos na área de vendas possam começar imediatamente.
Quando os clientes estão em uma loja de varejo, eles esperam poder experimentar demonstrações de PCs e dispositivos. Eles geralmente gastam uma parte considerável de seu tempo brincando com aplicativos por meio da experiência de demonstração de varejo (RDX).
Você pode configurar seu aplicativo para fornecer experiências diferentes nos modos normal ou de varejo . Por exemplo, se o aplicativo começar com um processo de configuração, você poderá ignorá-lo no modo de varejo e preencher previamente o aplicativo com dados de exemplo e configurações padrão para que eles possam entrar imediatamente.
Do ponto de vista de nossos clientes, existe 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" com destaque na barra de título ou em um local adequado.
Além dos requisitos da Microsoft Store para aplicativos, os aplicativos com reconhecimento de RDX 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 de varejo.
Princípios de design
Mostre o 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, então mostre a ele a melhor peça!
Mostre rápido. Os clientes podem ficar impacientes - Quanto mais rápido um usuário puder experimentar o valor real do seu aplicativo, melhor.
Mantenha a história simples. A experiência de demonstração de varejo é um argumento de venda para o valor do seu aplicativo.
Concentre-se na experiência. Dê ao usuário tempo para digerir seu conteúdo. Embora seja importante levá-los rapidamente à melhor parte, projetar pausas adequadas pode ajudá-los a aproveitar ao máximo a experiência.
Requisitos técnicos
Como os aplicativos com reconhecimento de RDX destinam-se a mostrar o melhor do seu aplicativo para clientes de varejo, eles devem atender aos requisitos técnicos e aderir aos regulamentos 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 devem ser mantidos, não apenas para o processo de validação, mas por 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 de 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 de contato.
Experiência sem erros. Seu aplicativo deve ser executado sem erros. Além disso, nenhum pop-up ou notificação de erro deve ser mostrado aos clientes que usam os dispositivos de demonstração de varejo. Os erros refletem negativamente no próprio aplicativo, na sua marca, na marca do dispositivo, na marca do fabricante do dispositivo e na marca da Microsoft.
Os 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 querem pagar por uma experiência em uma loja de varejo.
Requisitos de alta prioridade
Os aplicativos com reconhecimento de 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, este 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 solicitar atualizações quando estiver online. Se forem necessárias atualizações, elas devem ser executadas silenciosamente.
Nenhuma 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.
Forneça experiências consistentes usando o processo de limpeza. Todo cliente deve ter a mesma experiência quando se aproxima de um dispositivo de demonstração de varejo. Seu aplicativo deve usar o 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 Classificar seu aplicativo pelas classificações da IARC e da ESRB.
Requisitos de prioridade média
A equipe da Windows Retail Store pode entrar em contato diretamente com os desenvolvedores para marcar uma discussão sobre como corrigir esses problemas.
Capacidade de executar com sucesso em uma variedade de dispositivos. Os aplicativos devem funcionar bem em todos os dispositivos, incluindo dispositivos com especificações de baixo custo. 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 divulgados para que o aplicativo sempre possa ser executado com alto desempenho.
Atenda aos requisitos de tamanho do aplicativo da loja de varejo. O aplicativo deve ser menor que 800 MB. Entre em contato diretamente com a equipe da Windows Retail Store para obter mais discussões se o aplicativo com reconhecimento de RDX não atender aos requisitos de tamanho.
API RetailInfo: preparando seu código para o modo de demonstração
IsDemoModeEnabled
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 booliano 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 ManufacturerName, Screensize, Memory 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 é reproduzida e o Windows começa a redefinir todos os dados de amostra nos contatos, fotos e outros aplicativos. Dependendo do dispositivo, isso pode levar de 1 a 5 minutos para redefinir totalmente tudo de volta ao normal. Isso garante que todos os clientes na loja de varejo possam ir até um dispositivo e ter a mesma experiência ao interagir com o dispositivo.
Etapa 1: Limpeza
- Todos os aplicativos Win32 e da loja estão fechados
- Todos os arquivos em pastas conhecidas, como Imagens, Vídeos, Música, Documentos, SavedPictures, CameraRoll, Desktop e Downloads são excluídos
- Os estados de roaming não estruturados e estruturados são excluídos
- Os estados locais estruturados são excluídos
Etapa 2: configuração
- Para dispositivos offline: as pastas permanecem vazias
- Para dispositivos online: os ativos de demonstração de varejo podem ser enviados para o dispositivo da Microsoft Store
Armazene dados entre as sessões do usuário
Para armazenar dados entre 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 nessa 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 Microsoft-RetailDemo-Cleanup
aplicativo em seu aplicativo.
Os 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 armazenamento em cache de dados ou não querer que os dados LocalState 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: Implemente 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;
}
}
}