O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Carteira de acesso rápido, carteira de acesso rápido, carteira de acesso rápido, carteira de acesso rápido

O recurso Carteira de Acesso Rápido, disponível a partir do Android 11, permite que o usuário acesse cartões de pagamento e passes relevantes diretamente no menu de energia. Os principais casos de uso incluem selecionar o método de pagamento apropriado antes de realizar uma transação em um terminal NFC e acessar rapidamente voos e outros passes para eventos futuros.

No Android 12 ou superior, o recurso Carteira de acesso rápido está disponível na sombra, conforme mostrado na Figura 1 e na Figura 2.

Recurso de carteira de acesso rápido na sombra
Figura 1. Recurso de acesso rápido à carteira (dispositivo bloqueado).
Recurso de carteira de acesso rápido na sombra
Figura 2. Recurso Carteira de acesso rápido (dispositivo desbloqueado).

No Android 11, o recurso está disponível no menu de energia, conforme mostrado na Figura 3.

Recurso de acesso rápido da carteira no menu de energia
Figura 3. Recurso de acesso rápido da carteira no menu de energia.

Requisitos

Seu dispositivo deve ter NFC para usar o recurso Carteira de acesso rápido. O recurso se vincula ao QuickAccessWalletService do aplicativo de pagamento NFC padrão, o que significa que o dispositivo também deve oferecer suporte à emulação de cartão baseada em host NFC (HCE) .

Visão geral do recurso

Há duas partes na Carteira de Acesso Rápido: a interface do usuário da Carteira de Acesso Rápido e o provedor de cartão da Carteira de Acesso Rápido.

No Android 12 ou superior, a interface do usuário da carteira é executada na interface do usuário do sistema e está localizada em frameworks/base/packages/SystemUI/src/com/android/systemui/wallet . No Android 11, a IU da carteira, localizada em platform/packages/apps/QuickAccessWallet , deve ser instalada e colocada na lista de permissões.

O provedor do cartão Quick Access Wallet é o aplicativo de pagamento NFC padrão. Os usuários podem ter vários aplicativos de pagamento NFC instalados simultaneamente, mas apenas o aplicativo de pagamento NFC padrão pode mostrar cartões no menu de energia. Você pode especificar qual aplicativo de pagamento NFC é definido como padrão inicialmente, mas os usuários podem selecionar um aplicativo diferente em Configurações. Se apenas um aplicativo de pagamento NFC estiver instalado, ele se tornará o padrão automaticamente (consulte CardEmulationManager ).

Implementação

Para fornecer cartões à interface do usuário da carteira de acesso rápido, os aplicativos de pagamento NFC devem implementar o QuickAccessWalletService . Os aplicativos de pagamento devem incluir uma entrada de manifesto anunciando o serviço.

Para garantir que apenas a IU do sistema possa se vincular a QuickAccessWalletService , o aplicativo de pagamento NFC deve exigir a permissão android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE . Exigir essa permissão garante que apenas a interface do usuário do sistema possa ser vinculada a QuickAccessWalletService .

<service
     android:name=".MyQuickAccessWalletService"
     android:label="@string/my_default_tile_label"
     android:icon="@drawable/my_default_icon_label"
     android:logo="@drawable/my_wallet_logo"
     android:permission="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE">
     <intent-filter>
         <action android:name="android.service.quickaccesswallet.QuickAccessWalletService" />
         <category android:name="android.intent.category.DEFAULT"/>
     </intent-filter>
     <meta-data android:name="android.quickaccesswallet"
          android:resource="@xml/quickaccesswallet_configuration" />
     <meta-data
          android:name="android.quickaccesswallet.tile"
          android:resource="@drawable/my_default_tile_icon"/>
</service>

Informações adicionais sobre a carteira estão incluídas no arquivo XML vinculado:

<quickaccesswallet-service
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:settingsActivity="com.example.android.SettingsActivity"
   android:shortcutLongLabel="@string/my_wallet_empty_state_text"
   android:shortcutShortLabel="@string/my_wallet_button_text"
   android:targetActivity="com.example.android.WalletActivity"/>

Em seguida, o aplicativo de pagamento deve implementar QuickAccessWalletService :

public class MyQuickAccessWalletService extends QuickAccessWalletService {

    @Override
    public void onWalletCardsRequested(
            GetWalletCardsRequest request,
            GetWalletCardsCallback callback) {
        GetWalletCardsResponse response = // generate response
        callback.onSuccess(response);
    }

    @Override
    public void onWalletCardSelected(SelectWalletCardRequest request) {
        // selecting a card should ensure that it is used when making an NFC payment
    }

    @Override
    public void onWalletDismissed() {
        // May un-select card if the wallet app has the concept of a 'default'
        // payment method
    }
}

Se HostApduService começar a manipular uma transação NFC e, consequentemente, iniciar uma atividade para exibir o andamento e o resultado do pagamento, ele também deve tentar obter uma referência ao QuickAccessWalletService vinculado e chamar QuickAccessWalletService#sendEvent com um tipo de evento TYPE_NFC_PAYMENT_STARTED . Isso faz com que a interface do usuário da carteira de acesso rápido seja descartada, permitindo ao usuário uma visão desobstruída da atividade de pagamento.

Para obter documentação adicional sobre a implementação de QuickAccessWalletService , consulte QuickAccessWalletService e o teste CTS TestQuickAccessWalletService .

Ativando a interface do usuário da carteira de acesso rápido no Android 11

Para configurar a Carteira de acesso rápido para estar disponível no menu de energia no Android 11, inclua o destino QuickAccessWallet na compilação e ative o plug-in globalactions.wallet adicionando a linha em negrito no exemplo de código abaixo ao overlay/frameworks/base/packages/SystemUI/res/values/config.xml .

<resources>
    ...
    <!-- SystemUI Plugins that can be loaded on user builds. -->
    <string-array name="config_pluginWhitelist" translatable="false">
        <item>com.android.systemui</item>
        <item>com.android.systemui.plugin.globalactions.wallet</item>
    </string-array>
</resources>

Especifique o aplicativo de pagamento NFC padrão no arquivo de configuração de configurações usando def_nfc_payment_component .

O aplicativo de pagamento NFC padrão deve expor QuickAccessWalletService para fornecer cartões à carteira de acesso rápido. Se o aplicativo de pagamento NFC padrão não exportar esse serviço, a interface do usuário da carteira ficará oculta.

Detalhes de implementação do QuickAccessWalletService

QuickAccessWalletService tem três métodos abstratos que devem ser implementados: onWalletCardsRequested , onWalletCardSelected e onWalletDismissed . O diagrama de sequência abaixo ilustra uma sequência de chamadas quando a Carteira de Acesso Rápido é visualizada imediatamente antes de um pagamento NFC.

Diagrama de sequência da carteira de acesso rápido

Exemplo de sequência de chamada quando a carteira de acesso rápido é visualizada
Figura 4. Exemplo de sequência de chamada quando a carteira de acesso rápido é visualizada.

Nem todas as visualizações da Carteira de Acesso Rápido são seguidas por um pagamento NFC, mas a Figura 4 acima ilustra todos os recursos do QuickAccessWalletService . Neste exemplo, o fornecedor do cartão da Carteira de Acesso Rápido implementa os elementos destacados em azul. Supõe-se que os cartões de pagamento sejam armazenados no dispositivo em um banco de dados e acessados ​​por meio de uma interface denominada PaymentCardManager . Supõe-se ainda que uma atividade chamada PaymentActivity exibe o resultado de um pagamento NFC. O fluxo ocorre da seguinte forma:

  1. O usuário executa um gesto para abrir a Carteira de Acesso Rápido.
  2. A interface do usuário da carteira de acesso rápido (parte da interface do usuário do sistema) verifica o gerenciador de pacotes para ver se o aplicativo de pagamento NFC padrão exporta QuickAccessWalletService .

    • Se o serviço não for exportado, a Carteira de Acesso Rápido não será exibida.
  3. A interface do usuário da carteira de acesso rápido se vincula ao QuickAccessWalletService e chama onWalletCardsRequested . Esse método recebe um objeto de solicitação contendo dados sobre o número e o tamanho dos cartões que podem ser fornecidos e um retorno de chamada. O retorno de chamada pode ser chamado de um thread em segundo plano.

  4. QuickAccessWalletService calcula os cartões que deseja mostrar e chama o método onSuccess no retorno de chamada fornecido. É recomendável que o serviço execute essas ações em um thread em segundo plano.

  5. Assim que os cartões são exibidos, a interface do usuário do sistema notifica QuickAccessWalletService que o primeiro cartão foi selecionado chamando onWalletCardSelected .

    • onWalletCardSelected é chamado toda vez que o usuário seleciona um novo cartão.
    • onWalletCardSelected pode ser chamado mesmo que o cartão selecionado no momento não tenha sido alterado.
  6. Quando o usuário dispensa a carteira de acesso rápido, a interface do usuário do sistema notifica QuickAccessWalletService chamando onWalletDismissed .

No exemplo acima, o usuário coloca o telefone ao alcance de um terminal de pagamento NFC enquanto a carteira está sendo exibida. Um componente chave para lidar com pagamentos NFC é HostApduService , que deve ser implementado para processar APDUs fornecidas pelo leitor NFC (para obter mais informações, consulte Emulação de cartão baseada em host ). Supõe-se que o aplicativo de pagamento inicie uma atividade para exibir o andamento e o resultado da interação com o terminal NFC. No entanto, a interface do usuário da carteira de acesso rápido é exibida na parte superior da janela do aplicativo, o que significa que a atividade de pagamento é obscurecida pela interface do usuário da carteira de acesso rápido. Para corrigir isso, o aplicativo deve notificar a interface do usuário do sistema de que a interface do usuário da carteira de acesso rápido deve ser dispensada. Ele pode fazer isso obtendo uma referência ao QuickAccessWalletService vinculado e chamando sendWalletServiceEvent com o tipo de evento TYPE_NFC_PAYMENT_STARTED .

Implementação de amostra QuickAccessWalletService

/** Sample implementation of {@link QuickAccessWalletService} */
@RequiresApi(VERSION_CODES.R)
public class MyQuickAccessWalletService extends QuickAccessWalletService {

  private static final String TAG = "QAWalletSvc";
  private ExecutorService executor;
  private PaymentCardManager paymentCardManager;

  @Override
  public void onCreate() {
    super.onCreate();
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      Log.w(TAG, "Should not run on pre-R devices");
      stopSelf();
      return;
    }
    executor = Executors.newSingleThreadExecutor();
    paymentCardManager = new PaymentCardManager();
  }

  @Override
  public void onDestroy() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.shutdownNow();
  }

  @Override
  public void onWalletCardsRequested(
      @NonNull GetWalletCardsRequest request, @NonNull GetWalletCardsCallback callback) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> {
          List<PaymentCard> paymentCards = paymentCardManager.getCards();
          int maxCards = Math.min(paymentCards.size(), request.getMaxCards());
          List<WalletCard> walletCards = new ArrayList<>(maxCards);
          int selectedIndex = 0;
          int cardWidthPx = request.getCardWidthPx();
          int cardHeightPx = request.getCardHeightPx();
          for (int index = 0; index < maxCards; index++) {
            PaymentCard paymentCard = paymentCards.get(index);
            WalletCard walletCard =
                new WalletCard.Builder(
                        paymentCard.getCardId(),
                        paymentCard.getCardImage(cardWidthPx, cardHeightPx),
                        paymentCard.getContentDescription(),
                        paymentCard.getPendingIntent())
                    .build();
            walletCards.add(walletCard);
            if (paymentCard.isSelected()) {
              selectedIndex = index;
            }
          }
          GetWalletCardsResponse response =
              new GetWalletCardsResponse(walletCards, selectedIndex);
          callback.onSuccess(response);
        });
  }

  @Override
  public void onWalletCardSelected(@NonNull SelectWalletCardRequest request) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> paymentCardManager.selectCardById(request.getCardId()));
  }

  @Override
  public void onWalletDismissed() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(() -> {
      paymentCardManager.removeCardOverrides();
    });
  }
}

Para obter mais detalhes sobre QuickAccessWalletService , consulte Referência da API QuickAccessWalletService .

Permissões

A entrada do manifesto para QuickAccessWalletService deve exigir a permissão android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE introduzida no Android 11. Essa é uma permissão de nível de assinatura mantida pela IU do sistema, o que significa que apenas o processo da IU do sistema pode se vincular a implementações de QuickAccessWalletService . Esteja ciente de que os aplicativos carregados lateralmente podem reivindicar essa permissão e obter acesso total aos dados do QuickAccessWalletService em dispositivos com Android 10 ou inferior. Para evitar isso, é recomendável que o serviço verifique a versão de compilação no onCreate e ative o serviço apenas em dispositivos que executam o Android 11 e superior. Nenhuma outra permissão de aplicativo é necessária além daquelas necessárias para fornecer serviços de pagamento de emulação de cartão de host.

Se o aplicativo de pagamento NFC padrão não implementar ou exportar QuickAccessWalletService , a interface do usuário da carteira de acesso rápido não será exibida.

Configurações no Android 12

Para ativar ou desativar a Carteira de acesso rápido na tela de bloqueio, os usuários podem usar a opção Mostrar carteira em Configurações > Tela > Tela de bloqueio . Para desativar a carteira na sombra, os usuários devem editá-la manualmente na sombra de configurações rápidas.

Alterne para ativar ou desativar a carteira na tela de bloqueio

Figura 5. Mostrar a alternância de carteira na página da tela de bloqueio em Configurações.

Configurações no Android 11

Os usuários podem desativar o recurso Carteira de acesso rápido no aplicativo Configurações. A página de configurações é encontrada em Configurações > Sistema > Gestos > Cartões e passes .

Página de configurações para ativar ou desativar o recurso Carteira de acesso rápido
Figura 6. Página de configurações para ativar ou desativar o recurso Carteira de acesso rápido.

Costumização

Adicionando a visualização da carteira de acesso rápido a outro local na interface do usuário do sistema

A interface do usuário da carteira de acesso rápido foi criada como um plug-in do sistema . Embora a implementação do AOSP faça uso dele em GlobalActionsDialog (mostrado ao pressionar longamente), você pode mover o recurso para trás de um gesto diferente, desde que mantenha o contrato especificado pela interface do plug-in.

public interface GlobalActionsPanelPlugin extends Plugin {

  /** Invoked when the view is shown */
  PanelViewController onPanelShown(Callbacks callbacks, boolean deviceLocked);

  /** Callbacks for interacting with the view container */
  interface Callbacks {
    /** Dismisses the view */
    void dismissGlobalActionsMenu();

    /** Starts a PendingIntent, dismissing the keyguard if necessary. */
    void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent);
  }

  /** Provides the Quick Access Wallet view */
  interface PanelViewController {

    /** Returns the QuickAccessWallet view, which may take any size */
    View getPanelContent();

    /** Invoked when the view is dismissed */
    void onDismissed();

    /** Invoked when the device is either locked or unlocked. */
    void onDeviceLockStateChanged(boolean locked);
  }
}

A interface do usuário da carteira de acesso rápido implementa GlobalActionsPanelPlugin e PanelViewController . GlobalActionsDialog obtém uma instância do plugin wallet usando com.android.systemui.Dependency :

GlobalActionsPanelPlugin mPanelPlugin =
    Dependency.get(ExtensionController.class)
        .newExtension(GlobalActionsPanelPlugin.class)
        .withPlugin(GlobalActionsPanelPlugin.class)
        .build()
        .get();

Depois de verificar se o plug-in não é nulo e se o PanelViewController retornado por onPanelShown não é nulo, a caixa de diálogo anexa a View fornecida por getPanelContent à sua própria View e fornece retornos de chamada apropriados para eventos do sistema.

// Construct a Wallet PanelViewController.
// `this` implements GlobalActionsPanelPlugin.Callbacks
GlobalActionsPanelPlugin.PanelViewController mPanelController =
    mPanelPlugin.onPanelShown(this, !mKeyguardStateController.isUnlocked());

// Attach the view
FrameLayout panelContainer = findViewById(R.id.my_panel_container);
FrameLayout.LayoutParams panelParams =
    new FrameLayout.LayoutParams(
        FrameLayout.LayoutParams.MATCH_PARENT,
        FrameLayout.LayoutParams.MATCH_PARENT);
panelContainer.addView(mPanelController.getPanelContent(), panelParams);

// Respond to unlock events (if the view can be accessed while the phone is locked)
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
  @Override
  public void onUnlockedChanged() {
    boolean unlocked = keyguardStateController.isUnlocked()
        || keyguardStateController.canDismissLockScreen();
    mPanelController.onDeviceLockStateChanged(unlocked);
  }
});

// Implement GlobalActionsPanelPlugin.Callbacks
@Override
public void dismissGlobalActionsMenu() {
  dismissDialog();
}
@Override
public void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
  mActivityStarter.startPendingIntentDismissingKeyguard(pendingIntent);
}

// Notify the wallet when the container view is dismissed
mPanelController.onDismissed();

Para remover o Quick Access Wallet do menu de energia, omita o destino QuickAccessWallet da compilação do sistema. Para remover a Carteira de acesso rápido do menu de energia, mas adicioná-la a uma exibição diferente fornecida pela IU do sistema, inclua o destino de compilação e remova as referências ao GlobalActionsPanelPlugin de GlobalActionsImpl .

Definir configurações padrão

Android 12

No Android 12 ou superior, a Carteira de acesso rápido está sempre visível na aba de configurações rápidas. A visibilidade da Carteira de Acesso Rápido na tela de bloqueio é limitada pela seguinte configuração segura: LOCKSCREEN_SHOW_WALLET . Essa configuração controla se o ícone da Carteira de acesso rápido é exibido no canto inferior direito da tela de bloqueio. Essa configuração é definida como true por padrão, mas pode ser desativada pelo usuário em Configurações > Tela > Tela de bloqueio > Mostrar carteira .

Android 11

No Android 11, a visibilidade da Carteira de acesso rápido é limitada por duas configurações seguras: GLOBAL_ACTIONS_PANEL_ENABLED e GLOBAL_ACTIONS_PANEL_AVAILABLE . A configuração AVAILABLE controla se o recurso pode ser ativado e desativado em Configurações. Essa configuração é definida como true por WalletPluginService . Se QuickAccessWallet não estiver incluído na compilação, a configuração permanecerá false . A configuração ENABLED é definida como true por padrão no mesmo local, mas pode ser desativada pelo usuário em Configurações. Para alterar o comportamento padrão, modifique WalletPluginService#enableFeatureInSettings .

Validação

Para validar sua implementação da Carteira de Acesso Rápido, execute CTS e testes manuais. As alterações no plugin também devem exercitar os testes robolétricos incluídos.

Testes CTS

Execute os testes CTS localizados em cts/tests/quickaccesswallet .

Testes manuais para Android 12

Testar os principais recursos da Carteira de Acesso Rápido requer um terminal de pagamento NFC (real ou falso) e um aplicativo de pagamento NFC que implemente QuickAccessWalletService (aplicativo de carteira). Os principais recursos que devem ser testados incluem: disponibilidade, estado zero, seleção de cartão e comportamento da tela de bloqueio.

Disponibilidade

  • Se o aplicativo de pagamento NFC padrão não for compatível com o recurso, a Carteira de acesso rápido não estará acessível nas configurações rápidas nem na tela de bloqueio.
  • Se o aplicativo de pagamento NFC padrão for compatível com o recurso, a Carteira de acesso rápido estará acessível na aba de configurações rápidas.
  • Se o aplicativo de pagamento NFC padrão for compatível com o recurso e se a configuração LOCKSCREEN_SHOW_WALLET for true , a Carteira de acesso rápido ficará acessível na tela de bloqueio.
  • Se o aplicativo de pagamento NFC padrão for compatível com o recurso e se a configuração LOCKSCREEN_SHOW_WALLET for false , a Carteira de acesso rápido não poderá ser acessada na tela de bloqueio.

Estado zero

  • Se QuickAccessWalletService estiver ativado e exportado, mas não fornecer nenhum cartão, o bloco na Sombra aparecerá conforme mostrado no exemplo da Figura 7. Clicar no bloco abre o aplicativo de pagamento NFC padrão.

    Exemplo de bloco na sombra mostrando o aplicativo de pagamento NFC padrão

    Figura 7. Exemplo de bloco na sombra mostrando o aplicativo de pagamento NFC padrão.

  • Clicar na exibição de estado vazio, conforme mostrado na Figura 8, abre o aplicativo de pagamento NFC padrão. Essa exibição de estado vazia é exibida apenas quando o usuário tem um cartão na carteira, remove o cartão da página de detalhes do cartão e volta para a exibição da carteira.

  • A tela de bloqueio mostra o ícone da carteira.

Visualização de estado vazio na carteira de acesso rápido

Figura 8. Visualização de estado vazio na interface do usuário da carteira de acesso rápido.

Estado diferente de zero

  • Se o aplicativo de carteira fornecer um ou mais cartões, o bloco na sombra aparecerá conforme mostrado na Figura 9.

    Exemplo de bloco na sombra quando o aplicativo de carteira tem um ou mais cartões

    Figura 9. Exemplo de bloco na sombra quando o aplicativo de carteira tem um ou mais cartões.

  • Clicar no ladrilho mostra um carrossel de cartas.

  • A tela de bloqueio mostra um botão que abre a Carteira de Acesso Rápido.

    Interface de usuário da carteira de acesso rápido com um cartão exibido

    Figura 10. Interface de usuário da carteira de acesso rápido com um cartão exibido.

  • Se o cartão exibido representar um método de pagamento NFC, manter o telefone em um terminal de pagamento NFC resultará no uso desse método de pagamento e a exibição da carteira será descartada.

  • Clicar em um cartão exibido abre a atividade detalhada desse cartão.

  • Se vários cartões forem fornecidos pelo QuickAccessWalletService , o usuário poderá deslizar entre os cartões.

  • O menu de estouro contém uma entrada: abra as configurações da tela de bloqueio para que o usuário possa alterar a opção Mostrar carteira .

Testes de estado de bloqueio

  • Se o telefone estiver bloqueado, a carteira ficará visível na aba de configurações rápidas, com uma descrição de Adicionar um cartão se não houver cartão no aplicativo de pagamento padrão ou desbloquear para uso se houver cartões no aplicativo de pagamento padrão.
  • Se o telefone estiver bloqueado, a visibilidade da carteira na tela de bloqueio é controlada pela configuração Secure.LOCKSCREEN_SHOW_WALLET , que é controlada em Configurações.
  • Se o telefone estiver bloqueado, LOCKSCREEN_SHOW_WALLET será false e não existir nenhum cartão no aplicativo de pagamento NFC padrão, a carteira não será exibida na tela de bloqueio.
  • Se o telefone estiver bloqueado, LOCKSCREEN_SHOW_WALLET for true e não existir nenhum cartão no aplicativo de pagamento NFC padrão, a carteira não será exibida na tela de bloqueio.
  • Se o telefone estiver bloqueado, LOCKSCREEN_SHOW_WALLET for true e houver cartões no aplicativo de pagamento NFC padrão, a carteira será exibida na tela de bloqueio.
  • Desbloquear o telefone enquanto a carteira está sendo exibida na tela de bloqueio resulta na repetição dos cartões, o que pode resultar em conteúdo diferente do cartão.

Testes de acessibilidade

  • Os usuários do Talkback podem navegar na visualização da carteira deslizando para a esquerda e para a direita e ouvindo as descrições de conteúdo dos cartões.
  • Deslizar para a esquerda e para a direita com o Talkback ativado seleciona cada cartão por vez. Os usuários do Talkback podem selecionar e usar um método de pagamento NFC em um terminal de pagamento NFC.

Testes manuais para Android 11

Testar os principais recursos da Carteira de Acesso Rápido requer um terminal de pagamento NFC (real ou falso) e um aplicativo de pagamento NFC que implemente QuickAccessWalletService (aplicativo de carteira). Os principais recursos que devem ser testados incluem disponibilidade, estado zero, seleção de cartão e comportamento da tela de bloqueio.

Disponibilidade

  • Se a configuração GLOBAL_ACTIONS_PANEL_ENABLED for true e o aplicativo de pagamento NFC padrão oferecer suporte ao recurso, a Carteira de acesso rápido estará acessível.
  • Se a configuração GLOBAL_ACTIONS_PANEL_ENABLED for false e o aplicativo de pagamento NFC padrão for compatível com o recurso, a Carteira de acesso rápido não estará acessível.
  • Se a configuração GLOBAL_ACTIONS_PANEL_ENABLED for true e o aplicativo de pagamento NFC padrão não for compatível com o recurso, a Carteira de acesso rápido não estará acessível.
  • Se a configuração GLOBAL_ACTIONS_PANEL_ENABLED for false e o aplicativo de pagamento NFC padrão não for compatível com o recurso, a Carteira de acesso rápido não estará acessível.

Estado zero

  • Se QuickAccessWalletService estiver ativado e exportado, mas não fornecer nenhum cartão, a interface do usuário da carteira de acesso rápido exibirá a exibição de estado vazia.
  • Clicar na visualização de estado vazio abre o aplicativo de carteira.

    Visualização de estado vazio na interface do usuário da carteira de acesso rápido
    Figura 11. Visualização de estado vazio na interface do usuário da carteira de acesso rápido.

Estado diferente de zero

  • Se o aplicativo de carteira fornecer um ou mais cartões, os cartões serão exibidos na interface do usuário da carteira de acesso rápido.

    Interface de usuário da carteira de acesso rápido com um cartão exibido
    Figura 12. Interface de usuário da carteira de acesso rápido com um cartão exibido.
  • Se o cartão exibido representar um método de pagamento NFC, manter o telefone em um terminal de pagamento NFC resultará no uso desse método de pagamento e a exibição da carteira será descartada.

  • Clicar em um cartão exibido dispensa a visualização da carteira e abre a atividade detalhada desse cartão.

  • Se vários cartões forem fornecidos pelo QuickAccessWalletService , o usuário poderá deslizar entre os cartões.

  • O menu flutuante contém duas entradas: uma que abre o aplicativo de carteira e outra que abre a tela Mostrar cartões e passes em Configurações.

Testes de estado de bloqueio

  • Se o telefone estiver bloqueado, a visibilidade da carteira é controlada pela configuração Settings.Secure.POWER_MENU_LOCK_SHOW_CONTENT , que pode ser controlada em Settings.
  • Se o telefone estiver bloqueado e POWER_MENU_LOCK_SHOW_CONTENT for false , a carteira não será exibida.
  • Se o telefone estiver bloqueado e POWER_MENU_LOCK_SHOW_CONTENT for true , a carteira será exibida.
  • Desbloquear o telefone enquanto a carteira está sendo exibida na tela de bloqueio faz com que os cartões sejam consultados novamente, o que pode resultar em conteúdo de cartão diferente.

Testes de acessibilidade

  • Os usuários do TalkBack podem navegar na visualização da carteira deslizando para a esquerda e para a direita e ouvindo as descrições de conteúdo dos cartões.
  • Deslizar para a esquerda e para a direita com o TalkBack ativado seleciona cada cartão por vez. Os usuários do TalkBack podem selecionar e usar um método de pagamento NFC em um terminal de pagamento NFC.
,

O recurso Carteira de Acesso Rápido, disponível a partir do Android 11, permite que o usuário acesse cartões de pagamento e passes relevantes diretamente no menu de energia. Os principais casos de uso incluem selecionar o método de pagamento apropriado antes de realizar uma transação em um terminal NFC e acessar rapidamente voos e outros passes para eventos futuros.

No Android 12 ou superior, o recurso Carteira de acesso rápido está disponível na sombra, conforme mostrado na Figura 1 e na Figura 2.

Recurso de carteira de acesso rápido na sombra
Figura 1. Recurso de acesso rápido à carteira (dispositivo bloqueado).
Recurso de carteira de acesso rápido na sombra
Figura 2. Recurso Carteira de acesso rápido (dispositivo desbloqueado).

No Android 11, o recurso está disponível no menu de energia, conforme mostrado na Figura 3.

Recurso de acesso rápido da carteira no menu de energia
Figura 3. Recurso de acesso rápido da carteira no menu de energia.

Requisitos

Seu dispositivo deve ter NFC para usar o recurso Carteira de acesso rápido. O recurso se vincula ao QuickAccessWalletService do aplicativo de pagamento NFC padrão, o que significa que o dispositivo também deve oferecer suporte à emulação de cartão baseada em host NFC (HCE) .

Visão geral do recurso

Há duas partes na Carteira de Acesso Rápido: a interface do usuário da Carteira de Acesso Rápido e o provedor de cartão da Carteira de Acesso Rápido.

No Android 12 ou superior, a interface do usuário da carteira é executada na interface do usuário do sistema e está localizada em frameworks/base/packages/SystemUI/src/com/android/systemui/wallet . No Android 11, a IU da carteira, localizada em platform/packages/apps/QuickAccessWallet , deve ser instalada e colocada na lista de permissões.

O provedor do cartão Quick Access Wallet é o aplicativo de pagamento NFC padrão. Os usuários podem ter vários aplicativos de pagamento NFC instalados simultaneamente, mas apenas o aplicativo de pagamento NFC padrão pode mostrar cartões no menu de energia. Você pode especificar qual aplicativo de pagamento NFC é definido como padrão inicialmente, mas os usuários podem selecionar um aplicativo diferente em Configurações. Se apenas um aplicativo de pagamento NFC estiver instalado, ele se tornará o padrão automaticamente (consulte CardEmulationManager ).

Implementação

Para fornecer cartões à interface do usuário da carteira de acesso rápido, os aplicativos de pagamento NFC devem implementar o QuickAccessWalletService . Os aplicativos de pagamento devem incluir uma entrada de manifesto anunciando o serviço.

Para garantir que apenas a IU do sistema possa se vincular a QuickAccessWalletService , o aplicativo de pagamento NFC deve exigir a permissão android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE . Exigir essa permissão garante que apenas a interface do usuário do sistema possa ser vinculada a QuickAccessWalletService .

<service
     android:name=".MyQuickAccessWalletService"
     android:label="@string/my_default_tile_label"
     android:icon="@drawable/my_default_icon_label"
     android:logo="@drawable/my_wallet_logo"
     android:permission="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE">
     <intent-filter>
         <action android:name="android.service.quickaccesswallet.QuickAccessWalletService" />
         <category android:name="android.intent.category.DEFAULT"/>
     </intent-filter>
     <meta-data android:name="android.quickaccesswallet"
          android:resource="@xml/quickaccesswallet_configuration" />
     <meta-data
          android:name="android.quickaccesswallet.tile"
          android:resource="@drawable/my_default_tile_icon"/>
</service>

Informações adicionais sobre a carteira estão incluídas no arquivo XML vinculado:

<quickaccesswallet-service
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:settingsActivity="com.example.android.SettingsActivity"
   android:shortcutLongLabel="@string/my_wallet_empty_state_text"
   android:shortcutShortLabel="@string/my_wallet_button_text"
   android:targetActivity="com.example.android.WalletActivity"/>

Em seguida, o aplicativo de pagamento deve implementar QuickAccessWalletService :

public class MyQuickAccessWalletService extends QuickAccessWalletService {

    @Override
    public void onWalletCardsRequested(
            GetWalletCardsRequest request,
            GetWalletCardsCallback callback) {
        GetWalletCardsResponse response = // generate response
        callback.onSuccess(response);
    }

    @Override
    public void onWalletCardSelected(SelectWalletCardRequest request) {
        // selecting a card should ensure that it is used when making an NFC payment
    }

    @Override
    public void onWalletDismissed() {
        // May un-select card if the wallet app has the concept of a 'default'
        // payment method
    }
}

Se HostApduService começar a manipular uma transação NFC e, consequentemente, iniciar uma atividade para exibir o andamento e o resultado do pagamento, ele também deve tentar obter uma referência ao QuickAccessWalletService vinculado e chamar QuickAccessWalletService#sendEvent com um tipo de evento TYPE_NFC_PAYMENT_STARTED . Isso faz com que a interface do usuário da carteira de acesso rápido seja descartada, permitindo ao usuário uma visão desobstruída da atividade de pagamento.

Para obter documentação adicional sobre a implementação de QuickAccessWalletService , consulte QuickAccessWalletService e o teste CTS TestQuickAccessWalletService .

Ativando a interface do usuário da carteira de acesso rápido no Android 11

Para configurar a Carteira de acesso rápido para estar disponível no menu de energia no Android 11, inclua o destino QuickAccessWallet na compilação e ative o plug-in globalactions.wallet adicionando a linha em negrito no exemplo de código abaixo ao overlay/frameworks/base/packages/SystemUI/res/values/config.xml .

<resources>
    ...
    <!-- SystemUI Plugins that can be loaded on user builds. -->
    <string-array name="config_pluginWhitelist" translatable="false">
        <item>com.android.systemui</item>
        <item>com.android.systemui.plugin.globalactions.wallet</item>
    </string-array>
</resources>

Especifique o aplicativo de pagamento NFC padrão no arquivo de configuração de configurações usando def_nfc_payment_component .

O aplicativo de pagamento NFC padrão deve expor QuickAccessWalletService para fornecer cartões à carteira de acesso rápido. Se o aplicativo de pagamento NFC padrão não exportar esse serviço, a interface do usuário da carteira ficará oculta.

Detalhes de implementação do QuickAccessWalletService

QuickAccessWalletService tem três métodos abstratos que devem ser implementados: onWalletCardsRequested , onWalletCardSelected e onWalletDismissed . O diagrama de sequência abaixo ilustra uma sequência de chamadas quando a Carteira de Acesso Rápido é visualizada imediatamente antes de um pagamento NFC.

Diagrama de sequência da carteira de acesso rápido

Exemplo de sequência de chamada quando a carteira de acesso rápido é visualizada
Figura 4. Exemplo de sequência de chamada quando a carteira de acesso rápido é visualizada.

Nem todas as visualizações da Carteira de Acesso Rápido são seguidas por um pagamento NFC, mas a Figura 4 acima ilustra todos os recursos do QuickAccessWalletService . Neste exemplo, o fornecedor do cartão da Carteira de Acesso Rápido implementa os elementos destacados em azul. Supõe-se que os cartões de pagamento sejam armazenados no dispositivo em um banco de dados e acessados ​​por meio de uma interface denominada PaymentCardManager . Supõe-se ainda que uma atividade chamada PaymentActivity exibe o resultado de um pagamento NFC. O fluxo ocorre da seguinte forma:

  1. O usuário executa um gesto para abrir a Carteira de Acesso Rápido.
  2. A interface do usuário da carteira de acesso rápido (parte da interface do usuário do sistema) verifica o gerenciador de pacotes para ver se o aplicativo de pagamento NFC padrão exporta QuickAccessWalletService .

    • Se o serviço não for exportado, a Carteira de Acesso Rápido não será exibida.
  3. A interface do usuário da carteira de acesso rápido se vincula ao QuickAccessWalletService e chama onWalletCardsRequested . Esse método recebe um objeto de solicitação contendo dados sobre o número e o tamanho dos cartões que podem ser fornecidos e um retorno de chamada. O retorno de chamada pode ser chamado de um thread em segundo plano.

  4. QuickAccessWalletService calcula os cartões que deseja mostrar e chama o método onSuccess no retorno de chamada fornecido. É recomendável que o serviço execute essas ações em um thread em segundo plano.

  5. Assim que os cartões são exibidos, a interface do usuário do sistema notifica QuickAccessWalletService que o primeiro cartão foi selecionado chamando onWalletCardSelected .

    • onWalletCardSelected é chamado toda vez que o usuário seleciona um novo cartão.
    • onWalletCardSelected pode ser chamado mesmo que o cartão selecionado no momento não tenha sido alterado.
  6. Quando o usuário dispensa a carteira de acesso rápido, a interface do usuário do sistema notifica QuickAccessWalletService chamando onWalletDismissed .

No exemplo acima, o usuário coloca o telefone ao alcance de um terminal de pagamento NFC enquanto a carteira está sendo exibida. Um componente chave para lidar com pagamentos NFC é HostApduService , que deve ser implementado para processar APDUs fornecidas pelo leitor NFC (para obter mais informações, consulte Emulação de cartão baseada em host ). Supõe-se que o aplicativo de pagamento inicie uma atividade para exibir o andamento e o resultado da interação com o terminal NFC. No entanto, a interface do usuário da carteira de acesso rápido é exibida na parte superior da janela do aplicativo, o que significa que a atividade de pagamento é obscurecida pela interface do usuário da carteira de acesso rápido. Para corrigir isso, o aplicativo deve notificar a interface do usuário do sistema de que a interface do usuário da carteira de acesso rápido deve ser dispensada. Ele pode fazer isso obtendo uma referência ao QuickAccessWalletService vinculado e chamando sendWalletServiceEvent com o tipo de evento TYPE_NFC_PAYMENT_STARTED .

Implementação de amostra QuickAccessWalletService

/** Sample implementation of {@link QuickAccessWalletService} */
@RequiresApi(VERSION_CODES.R)
public class MyQuickAccessWalletService extends QuickAccessWalletService {

  private static final String TAG = "QAWalletSvc";
  private ExecutorService executor;
  private PaymentCardManager paymentCardManager;

  @Override
  public void onCreate() {
    super.onCreate();
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      Log.w(TAG, "Should not run on pre-R devices");
      stopSelf();
      return;
    }
    executor = Executors.newSingleThreadExecutor();
    paymentCardManager = new PaymentCardManager();
  }

  @Override
  public void onDestroy() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.shutdownNow();
  }

  @Override
  public void onWalletCardsRequested(
      @NonNull GetWalletCardsRequest request, @NonNull GetWalletCardsCallback callback) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> {
          List<PaymentCard> paymentCards = paymentCardManager.getCards();
          int maxCards = Math.min(paymentCards.size(), request.getMaxCards());
          List<WalletCard> walletCards = new ArrayList<>(maxCards);
          int selectedIndex = 0;
          int cardWidthPx = request.getCardWidthPx();
          int cardHeightPx = request.getCardHeightPx();
          for (int index = 0; index < maxCards; index++) {
            PaymentCard paymentCard = paymentCards.get(index);
            WalletCard walletCard =
                new WalletCard.Builder(
                        paymentCard.getCardId(),
                        paymentCard.getCardImage(cardWidthPx, cardHeightPx),
                        paymentCard.getContentDescription(),
                        paymentCard.getPendingIntent())
                    .build();
            walletCards.add(walletCard);
            if (paymentCard.isSelected()) {
              selectedIndex = index;
            }
          }
          GetWalletCardsResponse response =
              new GetWalletCardsResponse(walletCards, selectedIndex);
          callback.onSuccess(response);
        });
  }

  @Override
  public void onWalletCardSelected(@NonNull SelectWalletCardRequest request) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> paymentCardManager.selectCardById(request.getCardId()));
  }

  @Override
  public void onWalletDismissed() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(() -> {
      paymentCardManager.removeCardOverrides();
    });
  }
}

Para obter mais detalhes sobre QuickAccessWalletService , consulte Referência da API QuickAccessWalletService .

Permissões

A entrada do manifesto para QuickAccessWalletService deve exigir a permissão android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE introduzida no Android 11. Essa é uma permissão de nível de assinatura mantida pela IU do sistema, o que significa que apenas o processo da IU do sistema pode se vincular a implementações de QuickAccessWalletService . Esteja ciente de que os aplicativos carregados lateralmente podem reivindicar essa permissão e obter acesso total aos dados do QuickAccessWalletService em dispositivos com Android 10 ou inferior. Para evitar isso, é recomendável que o serviço verifique a versão de compilação no onCreate e ative o serviço apenas em dispositivos que executam o Android 11 e superior. Nenhuma outra permissão de aplicativo é necessária além daquelas necessárias para fornecer serviços de pagamento de emulação de cartão de host.

Se o aplicativo de pagamento NFC padrão não implementar ou exportar QuickAccessWalletService , a interface do usuário da carteira de acesso rápido não será exibida.

Configurações no Android 12

Para ativar ou desativar a Carteira de acesso rápido na tela de bloqueio, os usuários podem usar a opção Mostrar carteira em Configurações > Tela > Tela de bloqueio . Para desativar a carteira na sombra, os usuários devem editá-la manualmente na sombra de configurações rápidas.

Alterne para ativar ou desativar a carteira na tela de bloqueio

Figura 5. Mostrar a alternância de carteira na página da tela de bloqueio em Configurações.

Configurações no Android 11

Os usuários podem desativar o recurso Carteira de acesso rápido no aplicativo Configurações. A página de configurações é encontrada em Configurações > Sistema > Gestos > Cartões e passes .

Página de configurações para ativar ou desativar o recurso Carteira de acesso rápido
Figura 6. Página de configurações para ativar ou desativar o recurso Carteira de acesso rápido.

Costumização

Adicionando a visualização da carteira de acesso rápido a outro local na interface do usuário do sistema

A interface do usuário da carteira de acesso rápido foi criada como um plug-in do sistema . Embora a implementação do AOSP faça uso dele em GlobalActionsDialog (mostrado ao pressionar longamente), você pode mover o recurso para trás de um gesto diferente, desde que mantenha o contrato especificado pela interface do plug-in.

public interface GlobalActionsPanelPlugin extends Plugin {

  /** Invoked when the view is shown */
  PanelViewController onPanelShown(Callbacks callbacks, boolean deviceLocked);

  /** Callbacks for interacting with the view container */
  interface Callbacks {
    /** Dismisses the view */
    void dismissGlobalActionsMenu();

    /** Starts a PendingIntent, dismissing the keyguard if necessary. */
    void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent);
  }

  /** Provides the Quick Access Wallet view */
  interface PanelViewController {

    /** Returns the QuickAccessWallet view, which may take any size */
    View getPanelContent();

    /** Invoked when the view is dismissed */
    void onDismissed();

    /** Invoked when the device is either locked or unlocked. */
    void onDeviceLockStateChanged(boolean locked);
  }
}

A interface do usuário da carteira de acesso rápido implementa GlobalActionsPanelPlugin e PanelViewController . GlobalActionsDialog obtém uma instância do plugin wallet usando com.android.systemui.Dependency :

GlobalActionsPanelPlugin mPanelPlugin =
    Dependency.get(ExtensionController.class)
        .newExtension(GlobalActionsPanelPlugin.class)
        .withPlugin(GlobalActionsPanelPlugin.class)
        .build()
        .get();

Depois de verificar se o plug-in não é nulo e se o PanelViewController retornado por onPanelShown não é nulo, a caixa de diálogo anexa a View fornecida por getPanelContent à sua própria View e fornece retornos de chamada apropriados para eventos do sistema.

// Construct a Wallet PanelViewController.
// `this` implements GlobalActionsPanelPlugin.Callbacks
GlobalActionsPanelPlugin.PanelViewController mPanelController =
    mPanelPlugin.onPanelShown(this, !mKeyguardStateController.isUnlocked());

// Attach the view
FrameLayout panelContainer = findViewById(R.id.my_panel_container);
FrameLayout.LayoutParams panelParams =
    new FrameLayout.LayoutParams(
        FrameLayout.LayoutParams.MATCH_PARENT,
        FrameLayout.LayoutParams.MATCH_PARENT);
panelContainer.addView(mPanelController.getPanelContent(), panelParams);

// Respond to unlock events (if the view can be accessed while the phone is locked)
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
  @Override
  public void onUnlockedChanged() {
    boolean unlocked = keyguardStateController.isUnlocked()
        || keyguardStateController.canDismissLockScreen();
    mPanelController.onDeviceLockStateChanged(unlocked);
  }
});

// Implement GlobalActionsPanelPlugin.Callbacks
@Override
public void dismissGlobalActionsMenu() {
  dismissDialog();
}
@Override
public void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
  mActivityStarter.startPendingIntentDismissingKeyguard(pendingIntent);
}

// Notify the wallet when the container view is dismissed
mPanelController.onDismissed();

Para remover o Quick Access Wallet do menu de energia, omita o destino QuickAccessWallet da compilação do sistema. Para remover a Carteira de acesso rápido do menu de energia, mas adicioná-la a uma exibição diferente fornecida pela IU do sistema, inclua o destino de compilação e remova as referências ao GlobalActionsPanelPlugin de GlobalActionsImpl .

Definir configurações padrão

Android 12

No Android 12 ou superior, a Carteira de acesso rápido está sempre visível na aba de configurações rápidas. A visibilidade da Carteira de Acesso Rápido na tela de bloqueio é limitada pela seguinte configuração segura: LOCKSCREEN_SHOW_WALLET . Essa configuração controla se o ícone da Carteira de acesso rápido é exibido no canto inferior direito da tela de bloqueio. Essa configuração é definida como true por padrão, mas pode ser desativada pelo usuário em Configurações > Tela > Tela de bloqueio > Mostrar carteira .

Android 11

No Android 11, a visibilidade da Carteira de acesso rápido é limitada por duas configurações seguras: GLOBAL_ACTIONS_PANEL_ENABLED e GLOBAL_ACTIONS_PANEL_AVAILABLE . A configuração AVAILABLE controla se o recurso pode ser ativado e desativado em Configurações. Essa configuração é definida como true por WalletPluginService . Se QuickAccessWallet não estiver incluído na compilação, a configuração permanecerá false . A configuração ENABLED é definida como true por padrão no mesmo local, mas pode ser desativada pelo usuário em Configurações. Para alterar o comportamento padrão, modifique WalletPluginService#enableFeatureInSettings .

Validação

Para validar sua implementação da Carteira de Acesso Rápido, execute CTS e testes manuais. As alterações no plugin também devem exercitar os testes robolétricos incluídos.

Testes CTS

Execute os testes CTS localizados em cts/tests/quickaccesswallet .

Testes manuais para Android 12

Testar os principais recursos da Carteira de Acesso Rápido requer um terminal de pagamento NFC (real ou falso) e um aplicativo de pagamento NFC que implemente QuickAccessWalletService (aplicativo de carteira). Os principais recursos que devem ser testados incluem: disponibilidade, estado zero, seleção de cartão e comportamento da tela de bloqueio.

Disponibilidade

  • Se o aplicativo de pagamento NFC padrão não for compatível com o recurso, a Carteira de acesso rápido não estará acessível nas configurações rápidas nem na tela de bloqueio.
  • Se o aplicativo de pagamento NFC padrão for compatível com o recurso, a Carteira de acesso rápido estará acessível na aba de configurações rápidas.
  • Se o aplicativo de pagamento NFC padrão for compatível com o recurso e se a configuração LOCKSCREEN_SHOW_WALLET for true , a Carteira de acesso rápido ficará acessível na tela de bloqueio.
  • Se o aplicativo de pagamento NFC padrão for compatível com o recurso e se a configuração LOCKSCREEN_SHOW_WALLET for false , a Carteira de acesso rápido não poderá ser acessada na tela de bloqueio.

Estado zero

  • Se QuickAccessWalletService estiver ativado e exportado, mas não fornecer nenhum cartão, o bloco na Sombra aparecerá conforme mostrado no exemplo da Figura 7. Clicar no bloco abre o aplicativo de pagamento NFC padrão.

    Exemplo de bloco na sombra mostrando o aplicativo de pagamento NFC padrão

    Figura 7. Exemplo de bloco na sombra mostrando o aplicativo de pagamento NFC padrão.

  • Clicar na exibição de estado vazio, conforme mostrado na Figura 8, abre o aplicativo de pagamento NFC padrão. Essa exibição de estado vazia é exibida apenas quando o usuário tem um cartão na carteira, remove o cartão da página de detalhes do cartão e volta para a exibição da carteira.

  • A tela de bloqueio mostra o ícone da carteira.

Visualização de estado vazio na carteira de acesso rápido

Figura 8. Visualização de estado vazio na interface do usuário da carteira de acesso rápido.

Estado diferente de zero

  • Se o aplicativo de carteira fornecer um ou mais cartões, o bloco na sombra aparecerá conforme mostrado na Figura 9.

    Exemplo de bloco na sombra quando o aplicativo de carteira tem um ou mais cartões

    Figura 9. Exemplo de bloco na sombra quando o aplicativo de carteira tem um ou mais cartões.

  • Clicar no ladrilho mostra um carrossel de cartas.

  • A tela de bloqueio mostra um botão que abre a Carteira de Acesso Rápido.

    Interface de usuário da carteira de acesso rápido com um cartão exibido

    Figura 10. Interface de usuário da carteira de acesso rápido com um cartão exibido.

  • Se o cartão exibido representar um método de pagamento NFC, manter o telefone em um terminal de pagamento NFC resultará no uso desse método de pagamento e a exibição da carteira será descartada.

  • Clicking on a displayed card opens the detailed activity for that card.

  • If multiple cards are provided by QuickAccessWalletService , the user is able to swipe between cards.

  • The overflow menu contains one entry: open the lock screen settings so that the user can change the Show wallet option.

Lock state tests

  • If the phone is locked, the wallet is visible on the quick settings shade, with a description of Add a card if no card exists in the default payment app, or unlock to use if cards exist in the default payment app.
  • If the phone is locked, wallet visibility on the lock screen is controlled by the Secure.LOCKSCREEN_SHOW_WALLET setting, which is controlled in Settings.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is false , and no card exists in the default NFC payment app, the wallet isn't displayed on the lock screen.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is true , and no card exists in the default NFC payment app, the wallet isn't displayed on the lock screen.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is true , and cards exist in the default NFC payment app, the wallet is displayed on the lock screen.
  • Unlocking the phone while the wallet is being displayed on the lock screen results in the cards being requeried, which might result in different card content.

Accessibility tests

  • Talkback users can navigate the wallet view by swiping left and right and by listening to the content descriptions of the cards.
  • Swiping left and right with Talkback enabled selects each card in turn. Talkback users can select and use an NFC payment method at an NFC payment terminal.

Manual tests for Android 11

Testing the core features of the Quick Access Wallet requires an NFC payment terminal (real or fake) and an NFC payment app that implements QuickAccessWalletService (wallet app). Core features that must be tested include availability, zero state, card selection, and lock screen behavior.

Availability

  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is true and the default NFC payment app supports the feature, the Quick Access Wallet is accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is false and the default NFC payment app supports the feature, the Quick Access Wallet isn't accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is true and the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is false and the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible.

Zero state

  • If QuickAccessWalletService is enabled and exported but doesn't provide any cards, the Quick Access Wallet UI displays the empty state view.
  • Clicking the empty state view opens the wallet app.

    Empty state view in the Quick Access Wallet UI
    Figure 11. Empty state view in the Quick Access Wallet UI.

Non-zero state

  • If the wallet app provides one or more cards, the cards are displayed in the Quick Access Wallet UI.

    Quick Access Wallet UI with a card displayed
    Figure 12. Quick Access Wallet UI with a card displayed.
  • If the displayed card represents an NFC payment method, holding the phone to an NFC payment terminal results in that payment method being used and the wallet view is dismissed.

  • Clicking a displayed card dismisses the wallet view and opens the detailed activity for that card.

  • If multiple cards are provided by QuickAccessWalletService , the user is able to swipe between cards.

  • The overflow menu contains two entries: one that opens the wallet app and one that opens the Show cards & passes screen in Settings.

Lock state tests

  • If the phone is locked, wallet visibility is controlled by the Settings.Secure.POWER_MENU_LOCK_SHOW_CONTENT setting, which can be controlled in Settings.
  • If the phone is locked and POWER_MENU_LOCK_SHOW_CONTENT is false , the wallet isn't displayed.
  • If the phone is locked and POWER_MENU_LOCK_SHOW_CONTENT is true , the wallet is displayed.
  • Unlocking the phone while the wallet is being displayed on the lock screen results in the cards being re-queried, which might result in different card content.

Accessibility tests

  • TalkBack users can navigate the wallet view by swiping left and right and by listening to the content descriptions of the cards.
  • Swiping left and right with TalkBack enabled selects each card in turn. TalkBack users can select and use an NFC payment method at an NFC payment terminal.
,

The Quick Access Wallet feature, available from Android 11, allows the user to access payment cards and relevant passes directly from the power menu. Major use cases include selecting the appropriate payment method before performing a transaction at an NFC terminal and quickly accessing flights and other passes for upcoming events.

In Android 12 or higher, the Quick Access Wallet feature is available from the shade as shown in Figure 1 and Figure 2.

Quick Access Wallet feature in shade
Figure 1. Quick Access Wallet feature (device locked).
Quick Access Wallet feature in shade
Figure 2. Quick Access Wallet feature (device unlocked).

In Android 11, the feature is available from the power menu as shown in Figure 3.

Quick Access Wallet feature in power menu
Figure 3. Quick Access Wallet feature in power menu.

Requisitos

Your device must have NFC to use the Quick Access Wallet feature. The feature binds to QuickAccessWalletService of the default NFC payment app, which means that the device must also support NFC host-based card emulation (HCE) .

Feature overview

There are two parts to the Quick Access Wallet: the Quick Access Wallet UI and the Quick Access Wallet card provider.

In Android 12 or higher, the Wallet UI runs in System UI and is located in frameworks/base/packages/SystemUI/src/com/android/systemui/wallet . In Android 11, the Wallet UI, which is located in platform/packages/apps/QuickAccessWallet , must be installed and whitelisted.

The Quick Access Wallet card provider is the default NFC payment app. Users can have multiple NFC payment apps installed simultaneously, but only the default NFC payment app can show cards on the power menu. You can specify which NFC payment app is set as the default initially, but users can select a different app in Settings. If only one NFC payment app is installed, it becomes the default automatically (see CardEmulationManager ).

Implementação

To provide cards to the Quick Access Wallet UI, NFC payment apps must implement QuickAccessWalletService . Payment apps must include a manifest entry advertising the service.

To ensure that only the System UI can bind to QuickAccessWalletService , the NFC payment app must require the android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE permission. Requiring this permission ensures that only the System UI can bind to QuickAccessWalletService .

<service
     android:name=".MyQuickAccessWalletService"
     android:label="@string/my_default_tile_label"
     android:icon="@drawable/my_default_icon_label"
     android:logo="@drawable/my_wallet_logo"
     android:permission="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE">
     <intent-filter>
         <action android:name="android.service.quickaccesswallet.QuickAccessWalletService" />
         <category android:name="android.intent.category.DEFAULT"/>
     </intent-filter>
     <meta-data android:name="android.quickaccesswallet"
          android:resource="@xml/quickaccesswallet_configuration" />
     <meta-data
          android:name="android.quickaccesswallet.tile"
          android:resource="@drawable/my_default_tile_icon"/>
</service>

Additional information about the wallet is included in the linked XML file:

<quickaccesswallet-service
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:settingsActivity="com.example.android.SettingsActivity"
   android:shortcutLongLabel="@string/my_wallet_empty_state_text"
   android:shortcutShortLabel="@string/my_wallet_button_text"
   android:targetActivity="com.example.android.WalletActivity"/>

Next, the payment app must implement QuickAccessWalletService :

public class MyQuickAccessWalletService extends QuickAccessWalletService {

    @Override
    public void onWalletCardsRequested(
            GetWalletCardsRequest request,
            GetWalletCardsCallback callback) {
        GetWalletCardsResponse response = // generate response
        callback.onSuccess(response);
    }

    @Override
    public void onWalletCardSelected(SelectWalletCardRequest request) {
        // selecting a card should ensure that it is used when making an NFC payment
    }

    @Override
    public void onWalletDismissed() {
        // May un-select card if the wallet app has the concept of a 'default'
        // payment method
    }
}

If HostApduService starts to handle an NFC transaction and, as a consequence, starts an activity to display the progress and outcome of the payment, it should also try to get a reference to the bound QuickAccessWalletService and call QuickAccessWalletService#sendEvent with an event type of TYPE_NFC_PAYMENT_STARTED . This causes the Quick Access Wallet UI to be dismissed, thus allowing the user an unobstructed view of the payment activity.

For additional documentation on implementing QuickAccessWalletService , see QuickAccessWalletService and the TestQuickAccessWalletService CTS test.

Enabling Quick Access Wallet UI in Android 11

To configure the Quick Access Wallet to be available from the power menu in Android 11, include the QuickAccessWallet target in the build and enable the globalactions.wallet plugin by adding the line in bold in the code sample below to the overlay/frameworks/base/packages/SystemUI/res/values/config.xml file.

<resources>
    ...
    <!-- SystemUI Plugins that can be loaded on user builds. -->
    <string-array name="config_pluginWhitelist" translatable="false">
        <item>com.android.systemui</item>
        <item>com.android.systemui.plugin.globalactions.wallet</item>
    </string-array>
</resources>

Specify the default NFC payment app in the settings configuration file using def_nfc_payment_component .

The default NFC payment app must expose QuickAccessWalletService to provide cards to the Quick Access Wallet. If the default NFC payment app doesn't export this service, the wallet UI is hidden.

QuickAccessWalletService implementation details

QuickAccessWalletService has three abstract methods that must be implemented: onWalletCardsRequested , onWalletCardSelected , and onWalletDismissed . The sequence diagram below illustrates a call sequence when the Quick Access Wallet is viewed immediately preceding an NFC payment.

Quick Access Wallet sequence diagram

Example call sequence when Quick Access Wallet is viewed
Figure 4. Example call sequence when Quick Access Wallet is viewed.

Not all views of the Quick Access Wallet are followed by an NFC payment, but Figure 4 above illustrates all of the capabilities of QuickAccessWalletService . In this example, the Quick Access Wallet card provider implements the elements outlined in blue. It's assumed that payment cards are stored on the device in a database and are accessed through an interface named PaymentCardManager . It's further assumed that an activity called PaymentActivity displays the result of an NFC payment. The flow proceeds as follows:

  1. The user performs a gesture to bring up the Quick Access Wallet.
  2. The Quick Access Wallet UI (part of System UI) checks the package manager to see if the default NFC payment app exports QuickAccessWalletService .

    • If the service isn't exported, the Quick Access Wallet isn't displayed.
  3. The Quick Access Wallet UI binds to the QuickAccessWalletService and calls onWalletCardsRequested . This method takes a request object containing data about the number and size of the cards that can be provided and a callback. The callback can be called from a background thread.

  4. QuickAccessWalletService computes the cards that it wants to show, then calls the onSuccess method on the provided callback. It's recommended that the service perform these actions on a background thread.

  5. As soon as the cards are displayed, the System UI notifies QuickAccessWalletService that the first card has been selected by calling onWalletCardSelected .

    • onWalletCardSelected is called every time the user selects a new card.
    • onWalletCardSelected might be called even if the currently selected card hasn't changed.
  6. When the user dismisses the Quick Access Wallet, the System UI notifies QuickAccessWalletService by calling onWalletDismissed .

In the above example, the user brings the phone into range of an NFC payment terminal while the wallet is being displayed. A key component of handling NFC payments is HostApduService , which must be implemented to process APDUs provided by the NFC reader (for more information, see Host-based card emulation ). It's assumed that the payment app starts an activity to display the progress and result of the interaction with the NFC terminal. However, the Quick Access Wallet UI is displayed on top of the app window, meaning that the payment activity is obscured by the Quick Access Wallet UI. To rectify this, the app must notify the System UI that the Quick Access Wallet UI should be dismissed. It can do so by getting a reference to the bound QuickAccessWalletService and calling sendWalletServiceEvent with the event type TYPE_NFC_PAYMENT_STARTED .

QuickAccessWalletService sample implementation

/** Sample implementation of {@link QuickAccessWalletService} */
@RequiresApi(VERSION_CODES.R)
public class MyQuickAccessWalletService extends QuickAccessWalletService {

  private static final String TAG = "QAWalletSvc";
  private ExecutorService executor;
  private PaymentCardManager paymentCardManager;

  @Override
  public void onCreate() {
    super.onCreate();
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      Log.w(TAG, "Should not run on pre-R devices");
      stopSelf();
      return;
    }
    executor = Executors.newSingleThreadExecutor();
    paymentCardManager = new PaymentCardManager();
  }

  @Override
  public void onDestroy() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.shutdownNow();
  }

  @Override
  public void onWalletCardsRequested(
      @NonNull GetWalletCardsRequest request, @NonNull GetWalletCardsCallback callback) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> {
          List<PaymentCard> paymentCards = paymentCardManager.getCards();
          int maxCards = Math.min(paymentCards.size(), request.getMaxCards());
          List<WalletCard> walletCards = new ArrayList<>(maxCards);
          int selectedIndex = 0;
          int cardWidthPx = request.getCardWidthPx();
          int cardHeightPx = request.getCardHeightPx();
          for (int index = 0; index < maxCards; index++) {
            PaymentCard paymentCard = paymentCards.get(index);
            WalletCard walletCard =
                new WalletCard.Builder(
                        paymentCard.getCardId(),
                        paymentCard.getCardImage(cardWidthPx, cardHeightPx),
                        paymentCard.getContentDescription(),
                        paymentCard.getPendingIntent())
                    .build();
            walletCards.add(walletCard);
            if (paymentCard.isSelected()) {
              selectedIndex = index;
            }
          }
          GetWalletCardsResponse response =
              new GetWalletCardsResponse(walletCards, selectedIndex);
          callback.onSuccess(response);
        });
  }

  @Override
  public void onWalletCardSelected(@NonNull SelectWalletCardRequest request) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> paymentCardManager.selectCardById(request.getCardId()));
  }

  @Override
  public void onWalletDismissed() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(() -> {
      paymentCardManager.removeCardOverrides();
    });
  }
}

For further details about QuickAccessWalletService , see QuickAccessWalletService API reference .

Permissões

The manifest entry for QuickAccessWalletService must require the android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE permission introduced in Android 11. This is a signature-level permission held by the System UI, which means that only the System UI process can bind to implementations of QuickAccessWalletService . Be aware that side-loaded apps can claim this permission and get full access to QuickAccessWalletService data on devices running Android 10 or lower. To prevent this, it's recommended that the service check the build version in onCreate and enable the service only on devices running Android 11 and higher. No other app permissions are required beyond those necessary to provide host card emulation payment services.

If the default NFC payment app doesn't implement or export QuickAccessWalletService , the Quick Access Wallet UI isn't displayed.

Settings in Android 12

To enable or disable the Quick Access Wallet from the lock screen, users can use the Show wallet toggle in Settings > Display > Lock screen . To disable the wallet in the shade, users must manually edit it in the quick settings shade.

Toggle to enable or disable wallet from lock screen

Figure 5. Show wallet toggle in the Lock screen page in Settings.

Settings in Android 11

Users can turn off the Quick Access Wallet feature from the Settings app. The settings page is found in Settings > System > Gestures > Cards & passes .

Settings page to enable or disable the Quick Access Wallet feature
Figure 6. Settings page to enable or disable the Quick Access Wallet feature.

Costumização

Adding Quick Access Wallet view to another location in System UI

The Quick Access Wallet UI is built as a system plugin . Although the AOSP implementation makes use of it in GlobalActionsDialog (shown on long power press), you can move the feature behind a different gesture as long as you maintain the contract specified by the plugin interface.

public interface GlobalActionsPanelPlugin extends Plugin {

  /** Invoked when the view is shown */
  PanelViewController onPanelShown(Callbacks callbacks, boolean deviceLocked);

  /** Callbacks for interacting with the view container */
  interface Callbacks {
    /** Dismisses the view */
    void dismissGlobalActionsMenu();

    /** Starts a PendingIntent, dismissing the keyguard if necessary. */
    void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent);
  }

  /** Provides the Quick Access Wallet view */
  interface PanelViewController {

    /** Returns the QuickAccessWallet view, which may take any size */
    View getPanelContent();

    /** Invoked when the view is dismissed */
    void onDismissed();

    /** Invoked when the device is either locked or unlocked. */
    void onDeviceLockStateChanged(boolean locked);
  }
}

The Quick Access Wallet UI implements GlobalActionsPanelPlugin and PanelViewController . GlobalActionsDialog gets an instance of the wallet plugin by using com.android.systemui.Dependency :

GlobalActionsPanelPlugin mPanelPlugin =
    Dependency.get(ExtensionController.class)
        .newExtension(GlobalActionsPanelPlugin.class)
        .withPlugin(GlobalActionsPanelPlugin.class)
        .build()
        .get();

After checking that the plugin is non-null and that the PanelViewController returned by onPanelShown is non-null, the dialog attaches the View provided by getPanelContent to its own View and provides appropriate callbacks for system events.

// Construct a Wallet PanelViewController.
// `this` implements GlobalActionsPanelPlugin.Callbacks
GlobalActionsPanelPlugin.PanelViewController mPanelController =
    mPanelPlugin.onPanelShown(this, !mKeyguardStateController.isUnlocked());

// Attach the view
FrameLayout panelContainer = findViewById(R.id.my_panel_container);
FrameLayout.LayoutParams panelParams =
    new FrameLayout.LayoutParams(
        FrameLayout.LayoutParams.MATCH_PARENT,
        FrameLayout.LayoutParams.MATCH_PARENT);
panelContainer.addView(mPanelController.getPanelContent(), panelParams);

// Respond to unlock events (if the view can be accessed while the phone is locked)
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
  @Override
  public void onUnlockedChanged() {
    boolean unlocked = keyguardStateController.isUnlocked()
        || keyguardStateController.canDismissLockScreen();
    mPanelController.onDeviceLockStateChanged(unlocked);
  }
});

// Implement GlobalActionsPanelPlugin.Callbacks
@Override
public void dismissGlobalActionsMenu() {
  dismissDialog();
}
@Override
public void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
  mActivityStarter.startPendingIntentDismissingKeyguard(pendingIntent);
}

// Notify the wallet when the container view is dismissed
mPanelController.onDismissed();

To remove the Quick Access Wallet from the power menu, omit the QuickAccessWallet target from the system build. To remove the Quick Access Wallet from the power menu but add it to a different System UI provided view, include the build target and remove references to the GlobalActionsPanelPlugin from GlobalActionsImpl .

Setting default configurations

Android 12

In Android 12 or higher, the Quick Access Wallet is always visible in the quick settings shade. Visibility of the Quick Access Wallet in the lock screen is gated by the following secure setting: LOCKSCREEN_SHOW_WALLET . This setting controls whether the Quick Access Wallet icon is shown on the bottom right of the lock screen. This setting is set to true by default, but can be turned off by the user in Settings > Display > Lock screen > Show wallet .

Android 11

In Android 11, Quick Access Wallet visibility is gated by two secure settings: GLOBAL_ACTIONS_PANEL_ENABLED and GLOBAL_ACTIONS_PANEL_AVAILABLE . The AVAILABLE setting controls whether the feature can be turned on and off in Settings. This setting is set to true by WalletPluginService . If QuickAccessWallet isn't included in the build, then the setting remains false . The ENABLED setting is set to true by default in the same place, but can be turned off by the user in Settings. To change the default behavior, modify WalletPluginService#enableFeatureInSettings .

Validação

To validate your implementation of the Quick Access Wallet, run CTS and manual tests. Changes to the plugin should also exercise the included robolectric tests .

CTS tests

Run the CTS tests located at cts/tests/quickaccesswallet .

Manual tests for Android 12

Testing the core features of the Quick Access Wallet requires an NFC payment terminal (real or fake) and an NFC payment app that implements QuickAccessWalletService (wallet app). Core features that must be tested include: availability, zero state, card selection, and lock screen behavior.

Availability

  • If the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible in neither the quick settings nor the lock screen.
  • If the default NFC payment app supports the feature, the Quick Access Wallet is accessible in the quick settings shade.
  • If the default NFC payment app supports the feature and if the LOCKSCREEN_SHOW_WALLET setting is true , the Quick Access Wallet is accessible on the lock screen.
  • If the default NFC payment app supports the feature and if the LOCKSCREEN_SHOW_WALLET setting is false , the Quick Access Wallet isn't accessible on the lock screen.

Zero state

  • If QuickAccessWalletService is enabled and exported but doesn't provide any cards, the tile in the Shade appears as shown in the example in Figure 7. Clicking on the tile opens the default NFC payment app.

    Example tile in the shade showing default NFC payment app

    Figure 7. Example tile in the shade showing default NFC payment app.

  • Clicking on the empty state view as shown in Figure 8 opens the default NFC payment app. This empty state view is displayed only when the user has one card left in the wallet, removes the card from the card detail page, and then goes back to the wallet view.

  • The lock screen shows the wallet icon.

Empty state view in the Quick Access Wallet

Figure 8. Empty state view in the Quick Access Wallet UI.

Non-zero state

  • If the wallet app provides one or more cards, the tile in the shade appears as shown in Figure 9.

    Example tile in the shade when wallet app has one or more cards

    Figure 9. Example tile in the shade when wallet app has one or more cards.

  • Clicking on the tile shows a card carousel.

  • The lock screen shows a button that opens the Quick Access Wallet.

    Quick Access Wallet UI with a card displayed

    Figure 10. Quick Access Wallet UI with a card displayed.

  • If the displayed card represents an NFC payment method, holding the phone to an NFC payment terminal results in that payment method being used and the wallet view is dismissed.

  • Clicking on a displayed card opens the detailed activity for that card.

  • If multiple cards are provided by QuickAccessWalletService , the user is able to swipe between cards.

  • The overflow menu contains one entry: open the lock screen settings so that the user can change the Show wallet option.

Lock state tests

  • If the phone is locked, the wallet is visible on the quick settings shade, with a description of Add a card if no card exists in the default payment app, or unlock to use if cards exist in the default payment app.
  • If the phone is locked, wallet visibility on the lock screen is controlled by the Secure.LOCKSCREEN_SHOW_WALLET setting, which is controlled in Settings.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is false , and no card exists in the default NFC payment app, the wallet isn't displayed on the lock screen.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is true , and no card exists in the default NFC payment app, the wallet isn't displayed on the lock screen.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is true , and cards exist in the default NFC payment app, the wallet is displayed on the lock screen.
  • Unlocking the phone while the wallet is being displayed on the lock screen results in the cards being requeried, which might result in different card content.

Accessibility tests

  • Talkback users can navigate the wallet view by swiping left and right and by listening to the content descriptions of the cards.
  • Swiping left and right with Talkback enabled selects each card in turn. Talkback users can select and use an NFC payment method at an NFC payment terminal.

Manual tests for Android 11

Testing the core features of the Quick Access Wallet requires an NFC payment terminal (real or fake) and an NFC payment app that implements QuickAccessWalletService (wallet app). Core features that must be tested include availability, zero state, card selection, and lock screen behavior.

Availability

  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is true and the default NFC payment app supports the feature, the Quick Access Wallet is accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is false and the default NFC payment app supports the feature, the Quick Access Wallet isn't accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is true and the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is false and the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible.

Zero state

  • If QuickAccessWalletService is enabled and exported but doesn't provide any cards, the Quick Access Wallet UI displays the empty state view.
  • Clicking the empty state view opens the wallet app.

    Empty state view in the Quick Access Wallet UI
    Figure 11. Empty state view in the Quick Access Wallet UI.

Non-zero state

  • If the wallet app provides one or more cards, the cards are displayed in the Quick Access Wallet UI.

    Quick Access Wallet UI with a card displayed
    Figure 12. Quick Access Wallet UI with a card displayed.
  • If the displayed card represents an NFC payment method, holding the phone to an NFC payment terminal results in that payment method being used and the wallet view is dismissed.

  • Clicking a displayed card dismisses the wallet view and opens the detailed activity for that card.

  • If multiple cards are provided by QuickAccessWalletService , the user is able to swipe between cards.

  • The overflow menu contains two entries: one that opens the wallet app and one that opens the Show cards & passes screen in Settings.

Lock state tests

  • If the phone is locked, wallet visibility is controlled by the Settings.Secure.POWER_MENU_LOCK_SHOW_CONTENT setting, which can be controlled in Settings.
  • If the phone is locked and POWER_MENU_LOCK_SHOW_CONTENT is false , the wallet isn't displayed.
  • If the phone is locked and POWER_MENU_LOCK_SHOW_CONTENT is true , the wallet is displayed.
  • Unlocking the phone while the wallet is being displayed on the lock screen results in the cards being re-queried, which might result in different card content.

Accessibility tests

  • TalkBack users can navigate the wallet view by swiping left and right and by listening to the content descriptions of the cards.
  • Swiping left and right with TalkBack enabled selects each card in turn. TalkBack users can select and use an NFC payment method at an NFC payment terminal.
,

The Quick Access Wallet feature, available from Android 11, allows the user to access payment cards and relevant passes directly from the power menu. Major use cases include selecting the appropriate payment method before performing a transaction at an NFC terminal and quickly accessing flights and other passes for upcoming events.

In Android 12 or higher, the Quick Access Wallet feature is available from the shade as shown in Figure 1 and Figure 2.

Quick Access Wallet feature in shade
Figure 1. Quick Access Wallet feature (device locked).
Quick Access Wallet feature in shade
Figure 2. Quick Access Wallet feature (device unlocked).

In Android 11, the feature is available from the power menu as shown in Figure 3.

Quick Access Wallet feature in power menu
Figure 3. Quick Access Wallet feature in power menu.

Requisitos

Your device must have NFC to use the Quick Access Wallet feature. The feature binds to QuickAccessWalletService of the default NFC payment app, which means that the device must also support NFC host-based card emulation (HCE) .

Feature overview

There are two parts to the Quick Access Wallet: the Quick Access Wallet UI and the Quick Access Wallet card provider.

In Android 12 or higher, the Wallet UI runs in System UI and is located in frameworks/base/packages/SystemUI/src/com/android/systemui/wallet . In Android 11, the Wallet UI, which is located in platform/packages/apps/QuickAccessWallet , must be installed and whitelisted.

The Quick Access Wallet card provider is the default NFC payment app. Users can have multiple NFC payment apps installed simultaneously, but only the default NFC payment app can show cards on the power menu. You can specify which NFC payment app is set as the default initially, but users can select a different app in Settings. If only one NFC payment app is installed, it becomes the default automatically (see CardEmulationManager ).

Implementação

To provide cards to the Quick Access Wallet UI, NFC payment apps must implement QuickAccessWalletService . Payment apps must include a manifest entry advertising the service.

To ensure that only the System UI can bind to QuickAccessWalletService , the NFC payment app must require the android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE permission. Requiring this permission ensures that only the System UI can bind to QuickAccessWalletService .

<service
     android:name=".MyQuickAccessWalletService"
     android:label="@string/my_default_tile_label"
     android:icon="@drawable/my_default_icon_label"
     android:logo="@drawable/my_wallet_logo"
     android:permission="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE">
     <intent-filter>
         <action android:name="android.service.quickaccesswallet.QuickAccessWalletService" />
         <category android:name="android.intent.category.DEFAULT"/>
     </intent-filter>
     <meta-data android:name="android.quickaccesswallet"
          android:resource="@xml/quickaccesswallet_configuration" />
     <meta-data
          android:name="android.quickaccesswallet.tile"
          android:resource="@drawable/my_default_tile_icon"/>
</service>

Additional information about the wallet is included in the linked XML file:

<quickaccesswallet-service
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:settingsActivity="com.example.android.SettingsActivity"
   android:shortcutLongLabel="@string/my_wallet_empty_state_text"
   android:shortcutShortLabel="@string/my_wallet_button_text"
   android:targetActivity="com.example.android.WalletActivity"/>

Next, the payment app must implement QuickAccessWalletService :

public class MyQuickAccessWalletService extends QuickAccessWalletService {

    @Override
    public void onWalletCardsRequested(
            GetWalletCardsRequest request,
            GetWalletCardsCallback callback) {
        GetWalletCardsResponse response = // generate response
        callback.onSuccess(response);
    }

    @Override
    public void onWalletCardSelected(SelectWalletCardRequest request) {
        // selecting a card should ensure that it is used when making an NFC payment
    }

    @Override
    public void onWalletDismissed() {
        // May un-select card if the wallet app has the concept of a 'default'
        // payment method
    }
}

If HostApduService starts to handle an NFC transaction and, as a consequence, starts an activity to display the progress and outcome of the payment, it should also try to get a reference to the bound QuickAccessWalletService and call QuickAccessWalletService#sendEvent with an event type of TYPE_NFC_PAYMENT_STARTED . This causes the Quick Access Wallet UI to be dismissed, thus allowing the user an unobstructed view of the payment activity.

For additional documentation on implementing QuickAccessWalletService , see QuickAccessWalletService and the TestQuickAccessWalletService CTS test.

Enabling Quick Access Wallet UI in Android 11

To configure the Quick Access Wallet to be available from the power menu in Android 11, include the QuickAccessWallet target in the build and enable the globalactions.wallet plugin by adding the line in bold in the code sample below to the overlay/frameworks/base/packages/SystemUI/res/values/config.xml file.

<resources>
    ...
    <!-- SystemUI Plugins that can be loaded on user builds. -->
    <string-array name="config_pluginWhitelist" translatable="false">
        <item>com.android.systemui</item>
        <item>com.android.systemui.plugin.globalactions.wallet</item>
    </string-array>
</resources>

Specify the default NFC payment app in the settings configuration file using def_nfc_payment_component .

The default NFC payment app must expose QuickAccessWalletService to provide cards to the Quick Access Wallet. If the default NFC payment app doesn't export this service, the wallet UI is hidden.

QuickAccessWalletService implementation details

QuickAccessWalletService has three abstract methods that must be implemented: onWalletCardsRequested , onWalletCardSelected , and onWalletDismissed . The sequence diagram below illustrates a call sequence when the Quick Access Wallet is viewed immediately preceding an NFC payment.

Quick Access Wallet sequence diagram

Example call sequence when Quick Access Wallet is viewed
Figure 4. Example call sequence when Quick Access Wallet is viewed.

Not all views of the Quick Access Wallet are followed by an NFC payment, but Figure 4 above illustrates all of the capabilities of QuickAccessWalletService . In this example, the Quick Access Wallet card provider implements the elements outlined in blue. It's assumed that payment cards are stored on the device in a database and are accessed through an interface named PaymentCardManager . It's further assumed that an activity called PaymentActivity displays the result of an NFC payment. The flow proceeds as follows:

  1. The user performs a gesture to bring up the Quick Access Wallet.
  2. The Quick Access Wallet UI (part of System UI) checks the package manager to see if the default NFC payment app exports QuickAccessWalletService .

    • If the service isn't exported, the Quick Access Wallet isn't displayed.
  3. The Quick Access Wallet UI binds to the QuickAccessWalletService and calls onWalletCardsRequested . This method takes a request object containing data about the number and size of the cards that can be provided and a callback. The callback can be called from a background thread.

  4. QuickAccessWalletService computes the cards that it wants to show, then calls the onSuccess method on the provided callback. It's recommended that the service perform these actions on a background thread.

  5. As soon as the cards are displayed, the System UI notifies QuickAccessWalletService that the first card has been selected by calling onWalletCardSelected .

    • onWalletCardSelected is called every time the user selects a new card.
    • onWalletCardSelected might be called even if the currently selected card hasn't changed.
  6. When the user dismisses the Quick Access Wallet, the System UI notifies QuickAccessWalletService by calling onWalletDismissed .

In the above example, the user brings the phone into range of an NFC payment terminal while the wallet is being displayed. A key component of handling NFC payments is HostApduService , which must be implemented to process APDUs provided by the NFC reader (for more information, see Host-based card emulation ). It's assumed that the payment app starts an activity to display the progress and result of the interaction with the NFC terminal. However, the Quick Access Wallet UI is displayed on top of the app window, meaning that the payment activity is obscured by the Quick Access Wallet UI. To rectify this, the app must notify the System UI that the Quick Access Wallet UI should be dismissed. It can do so by getting a reference to the bound QuickAccessWalletService and calling sendWalletServiceEvent with the event type TYPE_NFC_PAYMENT_STARTED .

QuickAccessWalletService sample implementation

/** Sample implementation of {@link QuickAccessWalletService} */
@RequiresApi(VERSION_CODES.R)
public class MyQuickAccessWalletService extends QuickAccessWalletService {

  private static final String TAG = "QAWalletSvc";
  private ExecutorService executor;
  private PaymentCardManager paymentCardManager;

  @Override
  public void onCreate() {
    super.onCreate();
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      Log.w(TAG, "Should not run on pre-R devices");
      stopSelf();
      return;
    }
    executor = Executors.newSingleThreadExecutor();
    paymentCardManager = new PaymentCardManager();
  }

  @Override
  public void onDestroy() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.shutdownNow();
  }

  @Override
  public void onWalletCardsRequested(
      @NonNull GetWalletCardsRequest request, @NonNull GetWalletCardsCallback callback) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> {
          List<PaymentCard> paymentCards = paymentCardManager.getCards();
          int maxCards = Math.min(paymentCards.size(), request.getMaxCards());
          List<WalletCard> walletCards = new ArrayList<>(maxCards);
          int selectedIndex = 0;
          int cardWidthPx = request.getCardWidthPx();
          int cardHeightPx = request.getCardHeightPx();
          for (int index = 0; index < maxCards; index++) {
            PaymentCard paymentCard = paymentCards.get(index);
            WalletCard walletCard =
                new WalletCard.Builder(
                        paymentCard.getCardId(),
                        paymentCard.getCardImage(cardWidthPx, cardHeightPx),
                        paymentCard.getContentDescription(),
                        paymentCard.getPendingIntent())
                    .build();
            walletCards.add(walletCard);
            if (paymentCard.isSelected()) {
              selectedIndex = index;
            }
          }
          GetWalletCardsResponse response =
              new GetWalletCardsResponse(walletCards, selectedIndex);
          callback.onSuccess(response);
        });
  }

  @Override
  public void onWalletCardSelected(@NonNull SelectWalletCardRequest request) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(
        () -> paymentCardManager.selectCardById(request.getCardId()));
  }

  @Override
  public void onWalletDismissed() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
      return;
    }
    executor.submit(() -> {
      paymentCardManager.removeCardOverrides();
    });
  }
}

For further details about QuickAccessWalletService , see QuickAccessWalletService API reference .

Permissões

The manifest entry for QuickAccessWalletService must require the android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE permission introduced in Android 11. This is a signature-level permission held by the System UI, which means that only the System UI process can bind to implementations of QuickAccessWalletService . Be aware that side-loaded apps can claim this permission and get full access to QuickAccessWalletService data on devices running Android 10 or lower. To prevent this, it's recommended that the service check the build version in onCreate and enable the service only on devices running Android 11 and higher. No other app permissions are required beyond those necessary to provide host card emulation payment services.

If the default NFC payment app doesn't implement or export QuickAccessWalletService , the Quick Access Wallet UI isn't displayed.

Settings in Android 12

To enable or disable the Quick Access Wallet from the lock screen, users can use the Show wallet toggle in Settings > Display > Lock screen . To disable the wallet in the shade, users must manually edit it in the quick settings shade.

Toggle to enable or disable wallet from lock screen

Figure 5. Show wallet toggle in the Lock screen page in Settings.

Settings in Android 11

Users can turn off the Quick Access Wallet feature from the Settings app. The settings page is found in Settings > System > Gestures > Cards & passes .

Settings page to enable or disable the Quick Access Wallet feature
Figure 6. Settings page to enable or disable the Quick Access Wallet feature.

Costumização

Adding Quick Access Wallet view to another location in System UI

The Quick Access Wallet UI is built as a system plugin . Although the AOSP implementation makes use of it in GlobalActionsDialog (shown on long power press), you can move the feature behind a different gesture as long as you maintain the contract specified by the plugin interface.

public interface GlobalActionsPanelPlugin extends Plugin {

  /** Invoked when the view is shown */
  PanelViewController onPanelShown(Callbacks callbacks, boolean deviceLocked);

  /** Callbacks for interacting with the view container */
  interface Callbacks {
    /** Dismisses the view */
    void dismissGlobalActionsMenu();

    /** Starts a PendingIntent, dismissing the keyguard if necessary. */
    void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent);
  }

  /** Provides the Quick Access Wallet view */
  interface PanelViewController {

    /** Returns the QuickAccessWallet view, which may take any size */
    View getPanelContent();

    /** Invoked when the view is dismissed */
    void onDismissed();

    /** Invoked when the device is either locked or unlocked. */
    void onDeviceLockStateChanged(boolean locked);
  }
}

The Quick Access Wallet UI implements GlobalActionsPanelPlugin and PanelViewController . GlobalActionsDialog gets an instance of the wallet plugin by using com.android.systemui.Dependency :

GlobalActionsPanelPlugin mPanelPlugin =
    Dependency.get(ExtensionController.class)
        .newExtension(GlobalActionsPanelPlugin.class)
        .withPlugin(GlobalActionsPanelPlugin.class)
        .build()
        .get();

After checking that the plugin is non-null and that the PanelViewController returned by onPanelShown is non-null, the dialog attaches the View provided by getPanelContent to its own View and provides appropriate callbacks for system events.

// Construct a Wallet PanelViewController.
// `this` implements GlobalActionsPanelPlugin.Callbacks
GlobalActionsPanelPlugin.PanelViewController mPanelController =
    mPanelPlugin.onPanelShown(this, !mKeyguardStateController.isUnlocked());

// Attach the view
FrameLayout panelContainer = findViewById(R.id.my_panel_container);
FrameLayout.LayoutParams panelParams =
    new FrameLayout.LayoutParams(
        FrameLayout.LayoutParams.MATCH_PARENT,
        FrameLayout.LayoutParams.MATCH_PARENT);
panelContainer.addView(mPanelController.getPanelContent(), panelParams);

// Respond to unlock events (if the view can be accessed while the phone is locked)
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
  @Override
  public void onUnlockedChanged() {
    boolean unlocked = keyguardStateController.isUnlocked()
        || keyguardStateController.canDismissLockScreen();
    mPanelController.onDeviceLockStateChanged(unlocked);
  }
});

// Implement GlobalActionsPanelPlugin.Callbacks
@Override
public void dismissGlobalActionsMenu() {
  dismissDialog();
}
@Override
public void startPendingIntentDismissingKeyguard(PendingIntent pendingIntent) {
  mActivityStarter.startPendingIntentDismissingKeyguard(pendingIntent);
}

// Notify the wallet when the container view is dismissed
mPanelController.onDismissed();

To remove the Quick Access Wallet from the power menu, omit the QuickAccessWallet target from the system build. To remove the Quick Access Wallet from the power menu but add it to a different System UI provided view, include the build target and remove references to the GlobalActionsPanelPlugin from GlobalActionsImpl .

Setting default configurations

Android 12

In Android 12 or higher, the Quick Access Wallet is always visible in the quick settings shade. Visibility of the Quick Access Wallet in the lock screen is gated by the following secure setting: LOCKSCREEN_SHOW_WALLET . This setting controls whether the Quick Access Wallet icon is shown on the bottom right of the lock screen. This setting is set to true by default, but can be turned off by the user in Settings > Display > Lock screen > Show wallet .

Android 11

In Android 11, Quick Access Wallet visibility is gated by two secure settings: GLOBAL_ACTIONS_PANEL_ENABLED and GLOBAL_ACTIONS_PANEL_AVAILABLE . The AVAILABLE setting controls whether the feature can be turned on and off in Settings. This setting is set to true by WalletPluginService . If QuickAccessWallet isn't included in the build, then the setting remains false . The ENABLED setting is set to true by default in the same place, but can be turned off by the user in Settings. To change the default behavior, modify WalletPluginService#enableFeatureInSettings .

Validação

To validate your implementation of the Quick Access Wallet, run CTS and manual tests. Changes to the plugin should also exercise the included robolectric tests .

CTS tests

Run the CTS tests located at cts/tests/quickaccesswallet .

Manual tests for Android 12

Testing the core features of the Quick Access Wallet requires an NFC payment terminal (real or fake) and an NFC payment app that implements QuickAccessWalletService (wallet app). Core features that must be tested include: availability, zero state, card selection, and lock screen behavior.

Availability

  • If the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible in neither the quick settings nor the lock screen.
  • If the default NFC payment app supports the feature, the Quick Access Wallet is accessible in the quick settings shade.
  • If the default NFC payment app supports the feature and if the LOCKSCREEN_SHOW_WALLET setting is true , the Quick Access Wallet is accessible on the lock screen.
  • If the default NFC payment app supports the feature and if the LOCKSCREEN_SHOW_WALLET setting is false , the Quick Access Wallet isn't accessible on the lock screen.

Zero state

  • If QuickAccessWalletService is enabled and exported but doesn't provide any cards, the tile in the Shade appears as shown in the example in Figure 7. Clicking on the tile opens the default NFC payment app.

    Example tile in the shade showing default NFC payment app

    Figure 7. Example tile in the shade showing default NFC payment app.

  • Clicking on the empty state view as shown in Figure 8 opens the default NFC payment app. This empty state view is displayed only when the user has one card left in the wallet, removes the card from the card detail page, and then goes back to the wallet view.

  • The lock screen shows the wallet icon.

Empty state view in the Quick Access Wallet

Figure 8. Empty state view in the Quick Access Wallet UI.

Non-zero state

  • If the wallet app provides one or more cards, the tile in the shade appears as shown in Figure 9.

    Example tile in the shade when wallet app has one or more cards

    Figure 9. Example tile in the shade when wallet app has one or more cards.

  • Clicking on the tile shows a card carousel.

  • The lock screen shows a button that opens the Quick Access Wallet.

    Quick Access Wallet UI with a card displayed

    Figure 10. Quick Access Wallet UI with a card displayed.

  • If the displayed card represents an NFC payment method, holding the phone to an NFC payment terminal results in that payment method being used and the wallet view is dismissed.

  • Clicking on a displayed card opens the detailed activity for that card.

  • If multiple cards are provided by QuickAccessWalletService , the user is able to swipe between cards.

  • The overflow menu contains one entry: open the lock screen settings so that the user can change the Show wallet option.

Lock state tests

  • If the phone is locked, the wallet is visible on the quick settings shade, with a description of Add a card if no card exists in the default payment app, or unlock to use if cards exist in the default payment app.
  • If the phone is locked, wallet visibility on the lock screen is controlled by the Secure.LOCKSCREEN_SHOW_WALLET setting, which is controlled in Settings.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is false , and no card exists in the default NFC payment app, the wallet isn't displayed on the lock screen.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is true , and no card exists in the default NFC payment app, the wallet isn't displayed on the lock screen.
  • If the phone is locked, LOCKSCREEN_SHOW_WALLET is true , and cards exist in the default NFC payment app, the wallet is displayed on the lock screen.
  • Unlocking the phone while the wallet is being displayed on the lock screen results in the cards being requeried, which might result in different card content.

Accessibility tests

  • Talkback users can navigate the wallet view by swiping left and right and by listening to the content descriptions of the cards.
  • Swiping left and right with Talkback enabled selects each card in turn. Talkback users can select and use an NFC payment method at an NFC payment terminal.

Manual tests for Android 11

Testing the core features of the Quick Access Wallet requires an NFC payment terminal (real or fake) and an NFC payment app that implements QuickAccessWalletService (wallet app). Core features that must be tested include availability, zero state, card selection, and lock screen behavior.

Availability

  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is true and the default NFC payment app supports the feature, the Quick Access Wallet is accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is false and the default NFC payment app supports the feature, the Quick Access Wallet isn't accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is true and the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible.
  • If the GLOBAL_ACTIONS_PANEL_ENABLED setting is false and the default NFC payment app doesn't support the feature, the Quick Access Wallet isn't accessible.

Zero state

  • If QuickAccessWalletService is enabled and exported but doesn't provide any cards, the Quick Access Wallet UI displays the empty state view.
  • Clicking the empty state view opens the wallet app.

    Empty state view in the Quick Access Wallet UI
    Figure 11. Empty state view in the Quick Access Wallet UI.

Non-zero state

  • If the wallet app provides one or more cards, the cards are displayed in the Quick Access Wallet UI.

    Quick Access Wallet UI with a card displayed
    Figure 12. Quick Access Wallet UI with a card displayed.
  • If the displayed card represents an NFC payment method, holding the phone to an NFC payment terminal results in that payment method being used and the wallet view is dismissed.

  • Clicking a displayed card dismisses the wallet view and opens the detailed activity for that card.

  • If multiple cards are provided by QuickAccessWalletService , the user is able to swipe between cards.

  • The overflow menu contains two entries: one that opens the wallet app and one that opens the Show cards & passes screen in Settings.

Lock state tests

  • If the phone is locked, wallet visibility is controlled by the Settings.Secure.POWER_MENU_LOCK_SHOW_CONTENT setting, which can be controlled in Settings.
  • If the phone is locked and POWER_MENU_LOCK_SHOW_CONTENT is false , the wallet isn't displayed.
  • If the phone is locked and POWER_MENU_LOCK_SHOW_CONTENT is true , the wallet is displayed.
  • Unlocking the phone while the wallet is being displayed on the lock screen results in the cards being re-queried, which might result in different card content.

Accessibility tests

  • TalkBack users can navigate the wallet view by swiping left and right and by listening to the content descriptions of the cards.
  • Swiping left and right with TalkBack enabled selects each card in turn. TalkBack users can select and use an NFC payment method at an NFC payment terminal.