快速訪問錢包

Android 11 提供的快速訪問錢包功能允許用戶直接從電源菜單訪問支付卡和相關通行證。主要用例包括在 NFC 終端執行交易之前選擇適當的支付方式,以及為即將發生的事件快速訪問航班和其他通行證。

在 Android 12 或更高版本中,快速訪問錢包功能可從陰影中使用,如圖 1 和圖 2 所示。

陰影中的快速訪問錢包功能
圖1.快速訪問電子錢包功能(設備鎖定)。
陰影中的快速訪問錢包功能
圖2.快速訪問電子錢包功能(設備或解鎖)。

在 Android 11 中,該功能可從電源菜單中使用,如圖 3 所示。

電源菜單中的快速訪問錢包功能
在電源菜單圖3.快速訪問錢包功能。

要求

您的設備必須具有 NFC 才能使用快速訪問錢包功能。該功能結合到QuickAccessWalletService默認的NFC支付應用程序,這意味著該設備也必須支持NFC的基於主機卡模擬(HCE) 。

功能概述

Quick Access Wallet 有兩個部分:Quick Access Wallet UI 和 Quick Access Wallet card provider。

在Android中12或更高時,在系統UI和UI電子錢包運行位於frameworks/base/packages/SystemUI/src/com/android/systemui/wallet 。在Android的11,錢包用戶界面,它位於platform/packages/apps/QuickAccessWallet ,必須安裝和白名單。

Quick Access Wallet 卡提供商是默認的 NFC 支付應用程序。用戶可在多個NFC支付應用程序同時安裝,但只有默認的NFC支付應用程序可以在電源菜單上的顯示卡。您可以指定哪些NFC支付應用程序最初設置為默認,但用戶可以選擇設置不同的應用程序。如果只安裝了一個NFC支付應用程序,它會自動成為默認的(見CardEmulationManager )。

執行

為了提供卡到快速訪問錢包用戶界面,NFC支付應用程序必須實現QuickAccessWalletService 。支付應用程序必須包含宣傳服務的清單條目。

為了確保只有系統UI可以綁定到QuickAccessWalletService ,NFC支付應用程序必須要求android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE許可。要求此權限,確保只有系統UI可以綁定到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>

有關錢包的其他信息包含在鏈接的 XML 文件中:

<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"/>

接下來,支付應用程序必須實現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
    }
}

如果HostApduService開始處理的NFC交易,作為結果,開始一個活動,顯示支付的進度和結果,它也應該盡量去綁定參考QuickAccessWalletService並呼籲QuickAccessWalletService#sendEvent與事件類型TYPE_NFC_PAYMENT_STARTED .這會導致快速訪問錢包 UI 被關閉,從而使用戶可以暢通無阻地查看支付活動。

有關實現的其他文檔QuickAccessWalletService ,看到QuickAccessWalletServiceTestQuickAccessWalletService CTS測試。

在 Android 11 中啟用快速訪問錢包 UI

要配置在快速訪問電子錢包可以從Android中11的電力菜單,包括QuickAccessWallet中構建目標並啟用globalactions.wallet通過下面的代碼示例中添加線以粗體插件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>

指定默認NFC支付應用程序的設置配置文件使用def_nfc_payment_component

默認的NFC支付應用程序必須公開QuickAccessWalletService提供卡到快速訪問錢包。如果默認 NFC 支付應用程序沒有導出此服務,則錢包 UI 將隱藏。

QuickAccessWalletService 實現細節

QuickAccessWalletService有必須實現三個抽象方法: onWalletCardsRequestedonWalletCardSelectedonWalletDismissed 。下面的序列圖說明了在 NFC 支付之前查看 Quick Access Wallet 時的呼叫序列。

快速訪問錢包時序圖

查看快速訪問錢包時的示例調用序列
快速訪問電子錢包被觀察時圖4中實施例的呼叫序列。

沒有快速訪問錢包的所有意見之後是一個NFC支付,但上面的圖4舉例說明了所有的功能QuickAccessWalletService 。在此示例中,快速訪問錢包卡提供程序實​​現了以藍色標出的元素。它假定支付卡存儲在設備上的數據庫,並通過一個名為接口被訪問PaymentCardManager 。它進一步假設一個活動叫做PaymentActivity顯示器的NFC支付的結果。流程如下:

  1. 用戶執行手勢以調出快速訪問錢包。
  2. 快速訪問錢包UI(用戶界面系統的一部分)檢查軟件包管理器查看是否默認的NFC支付應用出口QuickAccessWalletService

    • 如果服務未導出,則不會顯示快速訪問錢包。
  3. 快速訪問錢包UI綁定到QuickAccessWalletService和電話onWalletCardsRequested 。此方法採用一個請求對象,其中包含有關可提供的卡片數量和大小的數據以及回調。可以從後台線程調用回調。

  4. QuickAccessWalletService計算,它要展示的卡片,然後調用onSuccess所提供的回調方法。建議服務在後台線程上執行這些操作。

  5. 只要顯示卡,通知系統UI QuickAccessWalletService第一卡已通過調用選擇onWalletCardSelected

    • onWalletCardSelected被稱為每次用戶選擇新卡的時間。
    • onWalletCardSelected即使當前選擇的卡並沒有改變可能會被調用。
  6. 當用戶退出快速訪問錢包,系統UI通知QuickAccessWalletService通過調用onWalletDismissed

在上面的示例中,用戶在展示錢包時將手機帶入 NFC 支付終端的範圍內。處理NFC支付的一個關鍵組成部分是HostApduService ,必須實現由NFC讀取器(有關詳細信息,請參閱該程序的APDU基於主機的卡模擬)。假設支付應用程序啟動一個活動來顯示與 NFC 終端交互的進度和結果。但是,快速訪問錢包 UI 顯示在應用程序窗口的頂部,這意味著支付活動被快速訪問錢包 UI 遮住了。要糾正此問題,應用程序必須通知系統 UI 應關閉快速訪問錢包 UI。它可以通過獲取到綁定的引用這樣做QuickAccessWalletService並調用sendWalletServiceEvent與事件類型TYPE_NFC_PAYMENT_STARTED

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();
    });
  }
}

有關進一步的細節QuickAccessWalletService ,看到QuickAccessWalletService API參考

權限

對於清單項QuickAccessWalletService必須要求android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE在Android的11本介紹權限是由系統UI,這意味著只有在系統UI進程都可以綁定的實現方式舉行簽名級別的權限QuickAccessWalletService 。要知道,側載應用程序可以要求此權限,並可以完全訪問QuickAccessWalletService數據上運行Android 10或更低的設備。為了防止這種情況,我們建議的服務為您在構建版本onCreate ,只有在運行Android 11和更高版本的設備啟用該服務。除了提供主機卡模擬支付服務所需的權限外,不需要其他應用程序權限。

如果默認的NFC支付應用不執行或出口QuickAccessWalletService ,不顯示快速訪問錢包UI。

Android 12 中的設置

要啟用或從鎖定屏幕禁用快速訪問錢包,用戶可以使用在設置>顯示>鎖定屏幕顯示切換的錢包。要在陰影中禁用錢包,用戶必須在快速設置陰影中手動編輯它。

從鎖定屏幕切換以啟用或禁用錢包

圖5顯示的錢包切換在設置鎖定屏幕頁。

Android 11 中的設置

用戶可以從“設置”應用程序關閉快速訪問錢包功能。設置頁面在設置>系統>手勢>卡和傳球找到。

用於啟用或禁用快速訪問錢包功能的設置頁面
圖6.設置頁面啟用或禁用快速訪問錢包功能。

定制

將快速訪問錢包視圖添加到系統 UI 中的另一個位置

快速訪問錢包UI被構建為系統插件。雖然AOSP實施,使得在使用它的GlobalActionsDialog (顯示在長電按),即可背後不同的手勢移動的特徵,只要您保持插件接口規定的合同。

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);
  }
}

快速訪問錢包UI工具GlobalActionsPanelPluginPanelViewControllerGlobalActionsDialog獲得通過使用錢包插件的實例com.android.systemui.Dependency

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

檢查該插件非空,而且以後PanelViewController返回由onPanelShown是非空的,對話的重視View提供由getPanelContent自身的View ,並提供適當的回調系統事件。

// 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();

從電源菜單中刪除快速訪問錢包,省略QuickAccessWallet從系統構建目標。要從電源菜單快速訪問錢包,但將其添加到不同的系統UI提供的視圖,包括構建目標,並刪除引用到GlobalActionsPanelPluginGlobalActionsImpl

設置默認配置

安卓 12

在 Android 12 或更高版本中,快速訪問錢包始終在快速設置陰影中可見。在鎖屏快速訪問錢包的能見度由以下安全設置門: LOCKSCREEN_SHOW_WALLET 。此設置控制是否在鎖定屏幕的右下角顯示快速訪問錢包圖標。此設置為true默認,但可以通過在設置>顯示>鎖定屏幕>顯示錢包的用戶關閉。

安卓 11

:在Android中11,快速訪問錢包的知名度是由兩個安全設置門GLOBAL_ACTIONS_PANEL_ENABLEDGLOBAL_ACTIONS_PANEL_AVAILABLE 。所述AVAILABLE設置控制是否將功能可以打開和關閉在設置轉動。此設置為trueWalletPluginService 。如果QuickAccessWallet在構建不包括,那麼設置保持false 。在ENABLED設置為true默認情況下在同一個地方,但可以通過設置用戶關閉。要更改默認的行為,修改WalletPluginService#enableFeatureInSettings

驗證

要驗證 Quick Access Wallet 的實施,請運行 CTS 和手動測試。更改插件也應該行使包括robolectric測試

CTS 測試

運行位於CTS測試cts/tests/quickaccesswallet

Android 12 的手動測試

測試快速訪問錢包的核心功能需要一個NFC支付終端(真的或假的)和NFC支付應用實現QuickAccessWalletService (電子錢包應用)。必須測試的核心功能包括:可用性、零狀態、卡片選擇和鎖屏行為。

可用性

  • 如果默認 NFC 支付應用程序不支持該功能,則在快速設置和鎖定屏幕中都無法訪問快速訪問錢包。
  • 如果默認 NFC 支付應用程序支持該功能,則可在快速設置陰影中訪問快速訪問錢包。
  • 如果默認的NFC支付應用程序支持該功能,如果LOCKSCREEN_SHOW_WALLET設置為true ,快速訪問錢包是鎖屏上訪問。
  • 如果默認的NFC支付應用程序支持該功能,如果LOCKSCREEN_SHOW_WALLET設置是false ,快速訪問錢包是不是鎖屏上訪問。

零狀態

  • 如果QuickAccessWalletService啟用和出口,但不提供任何卡,如在圖7.單擊圖塊上的示例所示的陰影出現瓷磚打開默認的NFC支付應用。

    顯示默認 NFC 支付應用程序的陰影中的示例圖塊

    圖7.實施例瓦中示出默認NFC支付應用陰涼處。

  • 單擊圖 8 所示的空狀態視圖將打開默認的 NFC 支付應用程序。僅當用戶在錢包中還剩一張卡片,從卡片詳細信息頁面移除卡片,然後返回錢包視圖時,才會顯示此空狀態視圖。

  • 鎖定屏幕顯示錢包圖標。

快速訪問錢包中的空狀態視圖

中快速訪問電子錢包UI 8.空狀態圖。

非零狀態

  • 如果錢包應用程序提供一張或多張卡片,則陰影中的磁貼如圖 9 所示。

    當錢包應用程序有一張或多張卡片時,陰影中的示例圖塊

    圖9.實施例瓦在陰涼處時電子錢包應用具有一個或多個卡片。

  • 單擊磁貼會顯示卡片輪播。

  • 鎖定屏幕顯示一個按鈕,用於打開快速訪問錢包。

    顯示卡片的快速訪問錢包 UI

    用卡圖10.快速訪問錢包UI顯示。

  • 如果顯示的卡代表一種 NFC 支付方式,將手機靠近 NFC 支付終端會導致使用該支付方式並關閉錢包視圖。

  • 單擊顯示的卡片可打開該卡片的詳細活動。

  • 如果通過設置多個卡QuickAccessWalletService ,用戶能夠卡之間刷卡。

  • 溢出菜單包含一個條目:開啟鎖屏設置,使用戶可以改變顯示錢包的選擇。

鎖定狀態測試

  • 如果手機被鎖定,錢包是在快速設置遮陽可見,如果用在默認的支付應用中不存在卡,或者如果在默認的支付應用程序存在卡解鎖使用添加卡的說明。
  • 如果手機被鎖定,在鎖定屏幕上的錢包可見性由控制Secure.LOCKSCREEN_SHOW_WALLET設置,在設置控制。
  • 如果手機被鎖定, LOCKSCREEN_SHOW_WALLETfalse ,並且存在於默認的NFC支付應用程序不卡,不顯示在鎖屏上的錢包。
  • 如果手機被鎖定, LOCKSCREEN_SHOW_WALLETtrue ,並且存在於默認的NFC支付應用程序不卡,不顯示在鎖屏上的錢包。
  • 如果手機被鎖定, LOCKSCREEN_SHOW_WALLETtrue ,並且在默認的NFC支付應用程序存在卡,錢包被顯示在鎖定屏幕上。
  • 在錢包顯示在鎖定屏幕上時解鎖手機會導致重新查詢卡片,這可能會導致卡片內容不同。

可訪問性測試

  • Talkback 用戶可以通過左右滑動和收聽卡片的內容描述來導航錢包視圖。
  • 在啟用 Talkback 的情況下左右滑動依次選擇每張卡片。 Talkback用戶可以在NFC支付終端上選擇和使用NFC支付方式。

Android 11 的手動測試

測試快速訪問錢包的核心功能需要一個NFC支付終端(真的或假的)和NFC支付應用實現QuickAccessWalletService (電子錢包應用)。必須測試的核心功能包括可用性、零狀態、卡片選擇和鎖屏行為。

可用性

  • 如果GLOBAL_ACTIONS_PANEL_ENABLED設置為true ,默認的NFC支付應用程序支持此功能,快速訪問錢包訪問。
  • 如果GLOBAL_ACTIONS_PANEL_ENABLED設置是false ,默認的NFC支付應用程序支持此功能,快速訪問電子錢包無法訪問。
  • 如果GLOBAL_ACTIONS_PANEL_ENABLED設置為true ,默認的NFC支付應用程序支持此功能,快速訪問電子錢包無法訪問。
  • 如果GLOBAL_ACTIONS_PANEL_ENABLED設置是false ,默認的NFC支付應用程序支持此功能,快速訪問電子錢包無法訪問。

零狀態

  • 如果QuickAccessWalletService啟用和出口,但不提供任何卡,快速訪問錢包UI顯示空狀態視圖。
  • 單擊空狀態視圖將打開錢包應用程序。

    快速訪問錢包 UI 中的空狀態視圖
    中快速訪問電子錢包UI 11.空狀態圖。

非零狀態

  • 如果錢包應用程序提供一張或多張卡片,這些卡片將顯示在快速訪問錢包 UI 中。

    顯示卡片的快速訪問錢包 UI
    用卡圖12.快速訪問錢包UI顯示。
  • 如果顯示的卡代表一種 NFC 支付方式,將手機靠近 NFC 支付終端會導致使用該支付方式並關閉錢包視圖。

  • 單擊顯示的卡片會關閉錢包視圖並打開該卡片的詳細活動。

  • 如果通過設置多個卡QuickAccessWalletService ,用戶能夠卡之間刷卡。

  • 溢出菜單包含兩個條目:一個打開的電子錢包應用和一個打開的顯示卡和設置在屏幕傳遞

鎖定狀態測試

  • 如果手機被鎖定,錢包可見性由控制Settings.Secure.POWER_MENU_LOCK_SHOW_CONTENT設置,可以在設置中進行控制。
  • 如果手機被鎖定, POWER_MENU_LOCK_SHOW_CONTENTfalse ,不顯示錢包。
  • 如果手機被鎖定, POWER_MENU_LOCK_SHOW_CONTENTtrue ,則顯示的錢包。
  • 在錢包顯示在鎖屏界面時解鎖手機會導致重新查詢卡片,這可能會導致卡片內容不同。

可訪問性測試

  • TalkBack 用戶可以通過左右滑動和收聽卡片的內容描述來導航錢包視圖。
  • 在啟用 TalkBack 的情況下左右滑動會依次選擇每張卡片。 TalkBack 用戶可以在 NFC 支付終端上選擇和使用 NFC 支付方式。