محفظة الوصول السريع ، محفظة الوصول السريع ، محفظة الوصول السريع ، محفظة الوصول السريع

تتيح ميزة Quick Access Wallet ، المتوفرة من Android 11 ، للمستخدم الوصول إلى بطاقات الدفع والتصاريح ذات الصلة مباشرة من قائمة الطاقة. تشمل حالات الاستخدام الرئيسية اختيار طريقة الدفع المناسبة قبل إجراء معاملة في محطة NFC والوصول بسرعة إلى الرحلات الجوية وغيرها من التصاريح للأحداث القادمة.

في Android 12 أو أعلى ، تتوفر ميزة Quick Access Wallet من الظل كما هو موضح في الشكل 1 والشكل 2.

ميزة Quick Access Wallet في الظل
الشكل 1. ميزة محفظة الوصول السريع (الجهاز مغلق).
ميزة Quick Access Wallet في الظل
الشكل 2. ميزة محفظة الوصول السريع (الجهاز غير مؤمن).

في Android 11 ، تتوفر الميزة من قائمة الطاقة كما هو موضح في الشكل 3.

ميزة Quick Access Wallet في قائمة الطاقة
الشكل 3. ميزة محفظة الوصول السريع في قائمة الطاقة.

متطلبات

يجب أن يحتوي جهازك على NFC لاستخدام ميزة Quick Access Wallet. ترتبط الميزة بـ QuickAccessWalletService لتطبيق الدفع الافتراضي NFC ، مما يعني أن الجهاز يجب أن يدعم أيضًا محاكاة البطاقة المستندة إلى مضيف NFC (HCE) .

نظرة عامة على الميزات

هناك جزأان لـ Quick Access Wallet: واجهة مستخدم Quick Access Wallet ومزود بطاقة Quick Access Wallet.

في Android 12 أو أعلى ، تعمل واجهة مستخدم Wallet في واجهة مستخدم النظام وتقع في frameworks/base/packages/SystemUI/src/com/android/systemui/wallet . في Android 11 ، يجب تثبيت واجهة مستخدم Wallet الموجودة في platform/packages/apps/QuickAccessWallet في القائمة البيضاء.

موفر بطاقة Quick Access Wallet هو تطبيق الدفع الافتراضي عبر NFC. يمكن للمستخدمين تثبيت العديد من تطبيقات الدفع عبر NFC في وقت واحد ، ولكن تطبيق الدفع الافتراضي عن طريق NFC فقط هو الذي يمكنه عرض البطاقات في قائمة الطاقة. يمكنك تحديد تطبيق الدفع NFC الذي تم تعيينه على أنه التطبيق الافتراضي في البداية ، ولكن يمكن للمستخدمين تحديد تطبيق مختلف في الإعدادات. إذا تم تثبيت تطبيق دفع NFC واحد فقط ، فسيصبح التطبيق الافتراضي تلقائيًا (انظر CardEmulationManager ).

التنفيذ

لتوفير بطاقات إلى Quick Access Wallet UI ، يجب على تطبيقات الدفع NFC تنفيذ QuickAccessWalletService . يجب أن تتضمن تطبيقات الدفع بيانًا يوضح إدخال الخدمة.

للتأكد من أن واجهة مستخدم النظام فقط هي التي يمكنها الارتباط بـ QuickAccessWalletService ، يجب أن يتطلب تطبيق الدفع NFC إذن android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE . يضمن طلب هذا الإذن أن تكون واجهة مستخدم النظام فقط هي التي يمكنها الارتباط بـ 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 . يؤدي هذا إلى رفض واجهة مستخدم محفظة الوصول السريع ، مما يسمح للمستخدم بمشاهدة نشاط الدفع دون عائق.

للحصول على وثائق إضافية حول تنفيذ QuickAccessWalletService ، راجع QuickAccessWalletService واختبار TestQuickAccessWalletService CTS.

تمكين Quick Access Wallet UI في Android 11

لتكوين Quick Access Wallet لتكون متاحة من قائمة الطاقة في 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 لتوفير بطاقات إلى Quick Access Wallet. إذا لم يقم تطبيق الدفع الافتراضي عبر NFC بتصدير هذه الخدمة ، فسيتم إخفاء واجهة مستخدم المحفظة.

تفاصيل تنفيذ QuickAccessWalletService

تحتوي QuickAccessWalletService على ثلاث طرق مجردة يجب تنفيذها: onWalletCardsRequested و onWalletCardSelected و onWalletDismissed . يوضح الرسم التخطيطي للتسلسل أدناه تسلسل المكالمة عند عرض محفظة الوصول السريع مباشرة قبل دفع NFC.

مخطط تسلسل محفظة الوصول السريع

مثال على تسلسل المكالمات عند عرض محفظة الوصول السريع
الشكل 4. مثال على تسلسل المكالمات عند عرض محفظة الوصول السريع.

لا يتم اتباع جميع عروض محفظة الوصول السريع بدفع NFC ، لكن الشكل 4 أعلاه يوضح جميع إمكانات QuickAccessWalletService . في هذا المثال ، يقوم موفر بطاقة Quick Access Wallet بتنفيذ العناصر الموضحة باللون الأزرق. من المفترض أن يتم تخزين بطاقات الدفع على الجهاز في قاعدة بيانات ويتم الوصول إليها من خلال واجهة تسمى PaymentCardManager . يُفترض أيضًا أن نشاطًا يسمى PaymentActivity يعرض نتيجة دفع NFC. يستمر التدفق على النحو التالي:

  1. يقوم المستخدم بإيماءة لإظهار محفظة الوصول السريع.
  2. تتحقق واجهة مستخدم محفظة الوصول السريع (جزء من واجهة مستخدم النظام) من مدير الحزم لمعرفة ما إذا كان تطبيق الدفع الافتراضي عبر NFC يصدر QuickAccessWalletService .

    • إذا لم يتم تصدير الخدمة ، فلن يتم عرض Quick Access Wallet.
  3. ترتبط واجهة مستخدم محفظة الوصول السريع بـ QuickAccessWalletService وتستدعي onWalletCardsRequested . تأخذ هذه الطريقة كائن طلب يحتوي على بيانات حول عدد وحجم البطاقات التي يمكن تقديمها واستدعاء. يمكن استدعاء رد الاتصال من مؤشر ترابط في الخلفية.

  4. تحسب QuickAccessWalletService البطاقات التي تريد إظهارها ، ثم تستدعي طريقة onSuccess على رد الاتصال المقدم. يوصى بأن تقوم الخدمة بتنفيذ هذه الإجراءات على سلسلة رسائل في الخلفية.

  5. بمجرد عرض البطاقات ، تقوم واجهة مستخدم النظام بإعلام QuickAccessWalletService بأنه تم تحديد البطاقة الأولى عن طريق الاتصال بـ onWalletCardSelected .

    • يتم استدعاء onWalletCardSelected في كل مرة يختار فيها المستخدم بطاقة جديدة.
    • قد يتم استدعاء onWalletCardSelected حتى إذا لم تتغير البطاقة المحددة حاليًا.
  6. عندما يرفض المستخدم محفظة الوصول السريع ، تقوم واجهة مستخدم النظام بإعلام QuickAccessWalletService عن طريق الاتصال onWalletDismissed .

في المثال أعلاه ، يقوم المستخدم بإحضار الهاتف إلى نطاق محطة دفع NFC أثناء عرض المحفظة. يعد HostApduService أحد المكونات الرئيسية للتعامل مع مدفوعات NFC ، والتي يجب تنفيذها لمعالجة وحدات APDU التي يوفرها قارئ NFC (لمزيد من المعلومات ، راجع محاكاة البطاقة المستندة إلى المضيف ). من المفترض أن يبدأ تطبيق الدفع نشاطًا لعرض التقدم ونتيجة التفاعل مع محطة NFC. ومع ذلك ، يتم عرض Quick Access Wallet UI أعلى نافذة التطبيق ، مما يعني أن نشاط الدفع محجوب بواسطة Quick Access Wallet 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 .

أذونات

يجب أن يتطلب إدخال البيان لـ QuickAccessWalletService إذن android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE المقدم في Android 11. هذا إذن على مستوى التوقيع تحتفظ به واجهة مستخدم النظام ، مما يعني أن عملية واجهة مستخدم النظام فقط هي التي يمكنها الارتباط QuickAccessWalletService . اعلم أن التطبيقات المحملة على الجانب يمكنها المطالبة بهذا الإذن والحصول على وصول كامل إلى بيانات QuickAccessWalletService على الأجهزة التي تعمل بنظام Android 10 أو أقل. لمنع ذلك ، يوصى بأن تتحقق الخدمة من إصدار الإنشاء في onCreate وتمكين الخدمة فقط على الأجهزة التي تعمل بنظام Android 11 والإصدارات الأحدث. لا توجد أذونات تطبيقات أخرى مطلوبة بخلاف تلك اللازمة لتقديم خدمات الدفع لمضاهاة بطاقة المضيف.

إذا لم يقم تطبيق الدفع الافتراضي عبر NFC بتنفيذ QuickAccessWalletService أو تصديره ، فلن يتم عرض Quick Access Wallet UI.

الإعدادات في Android 12

لتمكين أو تعطيل محفظة الوصول السريع من شاشة القفل ، يمكن للمستخدمين استخدام تبديل إظهار المحفظة في الإعدادات > العرض > قفل الشاشة . لتعطيل المحفظة في الظل ، يجب على المستخدمين تحريرها يدويًا في ظل الإعدادات السريعة.

قم بالتبديل لتمكين أو تعطيل المحفظة من شاشة القفل

الشكل 5. إظهار تبديل المحفظة في صفحة شاشة القفل في الإعدادات.

الإعدادات في Android 11

يمكن للمستخدمين إيقاف تشغيل ميزة Quick Access Wallet من تطبيق الإعدادات. تم العثور على صفحة الإعدادات في الإعدادات > النظام > الإيماءات > البطاقات والممرات .

صفحة الإعدادات لتمكين أو تعطيل ميزة محفظة الوصول السريع
الشكل 6. صفحة الإعدادات لتمكين أو تعطيل ميزة محفظة الوصول السريع.

التخصيص

إضافة عرض محفظة الوصول السريع إلى موقع آخر في واجهة مستخدم النظام

تم تصميم Quick Access Wallet 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);
  }
}

تنفذ Quick Access Wallet UI تطبيق GlobalActionsPanelPlugin و PanelViewController . يحصل GlobalActionsDialog على مثيل للمكوِّن الإضافي للمحفظة باستخدام 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();

لإزالة Quick Access Wallet من قائمة الطاقة ، احذف هدف QuickAccessWallet من بنية النظام. لإزالة Quick Access Wallet من قائمة الطاقة مع إضافتها إلى طريقة عرض مختلفة مقدمة من System UI ، قم بتضمين هدف البناء وإزالة المراجع إلى GlobalActionsPanelPlugin من GlobalActionsImpl .

ضبط التكوينات الافتراضية

أندرويد 12

في Android 12 أو أعلى ، تظهر محفظة Quick Access Wallet دائمًا في ظل الإعدادات السريعة. يتم تحديد رؤية محفظة الوصول السريع في شاشة القفل من خلال الإعداد الآمن التالي: LOCKSCREEN_SHOW_WALLET . يتحكم هذا الإعداد في ظهور رمز محفظة الوصول السريع في الجزء السفلي الأيمن من شاشة القفل. يتم تعيين هذا الإعداد على " true " افتراضيًا ، ولكن يمكن للمستخدم إيقاف تشغيله في الإعدادات > العرض > شاشة القفل > إظهار المحفظة .

أندرويد 11

في Android 11 ، يتم تحديد رؤية محفظة الوصول السريع بواسطة إعدادين آمنين: GLOBAL_ACTIONS_PANEL_ENABLED و GLOBAL_ACTIONS_PANEL_AVAILABLE . يتحكم الإعداد AVAILABLE في إمكانية تشغيل الميزة وإيقاف تشغيلها في الإعدادات. تم تعيين هذا الإعداد على true بواسطة WalletPluginService . إذا لم يتم تضمين QuickAccessWallet في الإصدار ، فسيظل الإعداد false . يتم تعيين الإعداد ENABLED على true افتراضيًا في نفس المكان ، ولكن يمكن للمستخدم إيقاف تشغيله في الإعدادات. لتغيير السلوك الافتراضي ، قم بتعديل WalletPluginService#enableFeatureInSettings .

تصديق

للتحقق من صحة تنفيذك لـ Quick Access Wallet ، قم بتشغيل CTS والاختبارات اليدوية. يجب أن تمارس التغييرات التي يتم إجراؤها على المكون الإضافي أيضًا اختبارات robolectric المضمنة.

اختبارات CTS

قم بتشغيل اختبارات CTS الموجودة في cts/tests/quickaccesswallet .

الاختبارات اليدوية لنظام Android 12

يتطلب اختبار الميزات الأساسية لـ Quick Access Wallet محطة دفع NFC (حقيقية أو مزيفة) وتطبيق دفع NFC الذي ينفذ QuickAccessWalletService (تطبيق المحفظة). تشمل الميزات الأساسية التي يجب اختبارها: التوفر ، والحالة الصفرية ، واختيار البطاقة ، وسلوك قفل الشاشة.

التوفر

  • إذا كان تطبيق الدفع الافتراضي عبر NFC لا يدعم هذه الميزة ، فلا يمكن الوصول إلى محفظة الوصول السريع في الإعدادات السريعة ولا في شاشة القفل.
  • إذا كان تطبيق الدفع الافتراضي عبر NFC يدعم الميزة ، فيمكن الوصول إلى محفظة الوصول السريع في ظل الإعدادات السريعة.
  • إذا كان تطبيق الدفع الافتراضي عبر NFC يدعم الميزة وإذا كان إعداد LOCKSCREEN_SHOW_WALLET true ، فيمكن الوصول إلى محفظة الوصول السريع على شاشة القفل.
  • إذا كان تطبيق الدفع الافتراضي عبر NFC يدعم الميزة وإذا كان إعداد LOCKSCREEN_SHOW_WALLET false ، فلا يمكن الوصول إلى محفظة الوصول السريع على شاشة القفل.

حالة الصفر

  • إذا تم تمكين QuickAccessWalletService وتصديره ولكنه لا يوفر أي بطاقات ، فإن اللوحة الموجودة في Shade تظهر كما هو موضح في المثال في الشكل 7. يؤدي النقر فوق المربع إلى فتح تطبيق الدفع NFC الافتراضي.

    مثال على مربع في الظل يعرض تطبيق الدفع الافتراضي بتقنية NFC

    الشكل 7. مثال على مربع في الظل يعرض تطبيق الدفع الافتراضي بتقنية NFC.

  • يؤدي النقر فوق عرض الحالة الفارغة كما هو موضح في الشكل 8 إلى فتح تطبيق الدفع الافتراضي بتقنية NFC. يتم عرض عرض الحالة الفارغة هذا فقط عندما يكون لدى المستخدم بطاقة واحدة متبقية في المحفظة ، ويزيل البطاقة من صفحة تفاصيل البطاقة ، ثم يعود إلى عرض المحفظة.

  • تعرض شاشة القفل رمز المحفظة.

عرض الحالة الفارغ في محفظة الوصول السريع

الشكل 8. عرض الحالة الفارغة في Quick Access Wallet UI.

دولة غير صفرية

  • إذا كان تطبيق المحفظة يوفر بطاقة واحدة أو أكثر ، فسيظهر المربع الموجود في الظل كما هو موضح في الشكل 9.

    مثال على البلاط في الظل عندما يحتوي تطبيق المحفظة على بطاقة واحدة أو أكثر

    الشكل 9. مثال على مربع في الظل عندما يحتوي تطبيق المحفظة على بطاقة واحدة أو أكثر.

  • يؤدي النقر فوق المربع إلى إظهار دائرة البطاقة.

  • تعرض شاشة القفل زرًا يفتح محفظة الوصول السريع.

    Quick Access Wallet UI مع عرض بطاقة

    الشكل 10. Quick Access Wallet UI مع عرض بطاقة.

  • إذا كانت البطاقة المعروضة تمثل طريقة دفع NFC ، فإن تثبيت الهاتف أمام محطة دفع NFC يؤدي إلى استخدام طريقة الدفع هذه ورفض عرض المحفظة.

  • يؤدي النقر فوق البطاقة المعروضة إلى فتح النشاط التفصيلي لتلك البطاقة.

  • إذا تم توفير عدة بطاقات بواسطة QuickAccessWalletService ، يمكن للمستخدم التمرير بين البطاقات.

  • تحتوي القائمة الكاملة على إدخال واحد: افتح إعدادات شاشة القفل بحيث يمكن للمستخدم تغيير خيار إظهار المحفظة .

اختبارات حالة القفل

  • إذا كان الهاتف مقفلاً ، فستظهر المحفظة في ظل الإعدادات السريعة ، مع وصف إضافة بطاقة في حالة عدم وجود بطاقة في تطبيق الدفع الافتراضي ، أو إلغاء القفل للاستخدام في حالة وجود البطاقات في تطبيق الدفع الافتراضي.
  • إذا كان الهاتف مقفلاً ، يتم التحكم في رؤية المحفظة على شاشة القفل عن طريق إعداد Secure.LOCKSCREEN_SHOW_WALLET ، والذي يتم التحكم فيه في الإعدادات.
  • إذا تم قفل الهاتف ، فإن LOCKSCREEN_SHOW_WALLET false ، ولا توجد بطاقة في تطبيق الدفع الافتراضي NFC ، فلن يتم عرض المحفظة على شاشة القفل.
  • إذا تم قفل الهاتف ، فإن LOCKSCREEN_SHOW_WALLET true ، ولا توجد بطاقة في تطبيق الدفع الافتراضي NFC ، فلن يتم عرض المحفظة على شاشة القفل.
  • إذا كان الهاتف مقفلاً ، LOCKSCREEN_SHOW_WALLET true ، والبطاقات موجودة في تطبيق الدفع الافتراضي NFC ، يتم عرض المحفظة على شاشة القفل.
  • يؤدي فتح قفل الهاتف أثناء عرض المحفظة على شاشة القفل إلى إعادة طلب البطاقات ، مما قد يؤدي إلى اختلاف محتوى البطاقة.

اختبارات الوصول

  • يمكن لمستخدمي Talkback التنقل في عرض المحفظة عن طريق التمرير إلى اليسار واليمين والاستماع إلى أوصاف محتوى البطاقات.
  • يؤدي التمرير إلى اليسار واليمين مع تمكين Talkback إلى تحديد كل بطاقة على حدة. يمكن لمستخدمي Talkback تحديد واستخدام طريقة دفع NFC في محطة دفع NFC.

الاختبارات اليدوية لنظام Android 11

يتطلب اختبار الميزات الأساسية لـ Quick Access Wallet محطة دفع 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 وتصديره ولكنه لا يوفر أي بطاقات ، فإن Quick Access Wallet UI تعرض طريقة عرض الحالة الفارغة.
  • يؤدي النقر فوق عرض الحالة الفارغة إلى فتح تطبيق المحفظة.

    عرض الحالة الفارغ في Quick Access Wallet UI
    الشكل 11. عرض الحالة الفارغة في Quick Access Wallet UI.

دولة غير صفرية

  • إذا كان تطبيق المحفظة يوفر بطاقة واحدة أو أكثر ، فسيتم عرض البطاقات في Quick Access Wallet UI.

    Quick Access Wallet UI مع عرض بطاقة
    الشكل 12. واجهة مستخدم محفظة الوصول السريع مع عرض بطاقة.
  • إذا كانت البطاقة المعروضة تمثل طريقة دفع NFC ، فإن تثبيت الهاتف أمام محطة دفع NFC يؤدي إلى استخدام طريقة الدفع هذه ورفض عرض المحفظة.

  • يؤدي النقر فوق البطاقة المعروضة إلى رفض عرض المحفظة وفتح النشاط التفصيلي لتلك البطاقة.

  • إذا تم توفير عدة بطاقات بواسطة QuickAccessWalletService ، يمكن للمستخدم التمرير بين البطاقات.

  • تحتوي القائمة الكاملة على إدخالين: أحدهما يفتح تطبيق المحفظة والآخر يفتح شاشة إظهار البطاقات والمرور في الإعدادات.

اختبارات حالة القفل

  • إذا تم قفل الهاتف ، يتم التحكم في رؤية المحفظة بواسطة Settings.Secure.POWER_MENU_LOCK_SHOW_CONTENT الإعداد ، والذي يمكن التحكم فيه من خلال الإعدادات.
  • إذا تم قفل الهاتف وكان POWER_MENU_LOCK_SHOW_CONTENT false ، فلن يتم عرض المحفظة.
  • إذا تم قفل الهاتف وكان POWER_MENU_LOCK_SHOW_CONTENT true ، فسيتم عرض المحفظة.
  • يؤدي فتح قفل الهاتف أثناء عرض المحفظة على شاشة القفل إلى إعادة الاستعلام عن البطاقات ، مما قد يؤدي إلى اختلاف محتوى البطاقة.

اختبارات الوصول

  • يمكن لمستخدمي TalkBack التنقل في عرض المحفظة عن طريق التمرير إلى اليسار واليمين والاستماع إلى أوصاف محتوى البطاقات.
  • يؤدي التمرير سريعًا جهة اليسار واليمين مع تمكين TalkBack إلى تحديد كل بطاقة على حدة. يمكن لمستخدمي TalkBack تحديد واستخدام طريقة دفع NFC في محطة دفع NFC.
و

تتيح ميزة Quick Access Wallet ، المتوفرة من Android 11 ، للمستخدم الوصول إلى بطاقات الدفع والتصاريح ذات الصلة مباشرة من قائمة الطاقة. تشمل حالات الاستخدام الرئيسية اختيار طريقة الدفع المناسبة قبل إجراء معاملة في محطة NFC والوصول بسرعة إلى الرحلات الجوية وغيرها من التصاريح للأحداث القادمة.

في Android 12 أو أعلى ، تتوفر ميزة Quick Access Wallet من الظل كما هو موضح في الشكل 1 والشكل 2.

ميزة Quick Access Wallet في الظل
الشكل 1. ميزة محفظة الوصول السريع (الجهاز مغلق).
ميزة Quick Access Wallet في الظل
الشكل 2. ميزة محفظة الوصول السريع (الجهاز غير مؤمن).

في Android 11 ، تتوفر الميزة من قائمة الطاقة كما هو موضح في الشكل 3.

ميزة Quick Access Wallet في قائمة الطاقة
الشكل 3. ميزة محفظة الوصول السريع في قائمة الطاقة.

متطلبات

يجب أن يحتوي جهازك على NFC لاستخدام ميزة Quick Access Wallet. ترتبط الميزة بـ QuickAccessWalletService لتطبيق الدفع الافتراضي NFC ، مما يعني أن الجهاز يجب أن يدعم أيضًا محاكاة البطاقة المستندة إلى مضيف NFC (HCE) .

نظرة عامة على الميزات

هناك جزأان لـ Quick Access Wallet: واجهة مستخدم Quick Access Wallet ومزود بطاقة Quick Access Wallet.

في Android 12 أو أعلى ، تعمل واجهة مستخدم Wallet في واجهة مستخدم النظام وتقع في frameworks/base/packages/SystemUI/src/com/android/systemui/wallet . في Android 11 ، يجب تثبيت واجهة مستخدم Wallet الموجودة في platform/packages/apps/QuickAccessWallet في القائمة البيضاء.

موفر بطاقة Quick Access Wallet هو تطبيق الدفع الافتراضي عبر NFC. يمكن للمستخدمين تثبيت العديد من تطبيقات الدفع عبر NFC في وقت واحد ، ولكن تطبيق الدفع الافتراضي عن طريق NFC فقط هو الذي يمكنه عرض البطاقات في قائمة الطاقة. يمكنك تحديد تطبيق الدفع NFC الذي تم تعيينه على أنه التطبيق الافتراضي في البداية ، ولكن يمكن للمستخدمين تحديد تطبيق مختلف في الإعدادات. إذا تم تثبيت تطبيق دفع NFC واحد فقط ، فسيصبح التطبيق الافتراضي تلقائيًا (انظر CardEmulationManager ).

التنفيذ

لتوفير بطاقات إلى Quick Access Wallet UI ، يجب على تطبيقات الدفع NFC تنفيذ QuickAccessWalletService . يجب أن تتضمن تطبيقات الدفع بيانًا يوضح إدخال الخدمة.

للتأكد من أن واجهة مستخدم النظام فقط هي التي يمكنها الارتباط بـ QuickAccessWalletService ، يجب أن يتطلب تطبيق الدفع NFC إذن android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE . يضمن طلب هذا الإذن أن تكون واجهة مستخدم النظام فقط هي التي يمكنها الارتباط بـ 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 . يؤدي هذا إلى رفض واجهة مستخدم محفظة الوصول السريع ، مما يسمح للمستخدم بمشاهدة نشاط الدفع دون عائق.

للحصول على وثائق إضافية حول تنفيذ QuickAccessWalletService ، راجع QuickAccessWalletService واختبار TestQuickAccessWalletService CTS.

تمكين Quick Access Wallet UI في Android 11

لتكوين Quick Access Wallet لتكون متاحة من قائمة الطاقة في 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 لتوفير بطاقات إلى Quick Access Wallet. إذا لم يقم تطبيق الدفع الافتراضي عبر NFC بتصدير هذه الخدمة ، فسيتم إخفاء واجهة مستخدم المحفظة.

تفاصيل تنفيذ QuickAccessWalletService

تحتوي QuickAccessWalletService على ثلاث طرق مجردة يجب تنفيذها: onWalletCardsRequested و onWalletCardSelected و onWalletDismissed . يوضح الرسم التخطيطي للتسلسل أدناه تسلسل المكالمة عند عرض محفظة الوصول السريع مباشرة قبل دفع NFC.

مخطط تسلسل محفظة الوصول السريع

مثال على تسلسل المكالمات عند عرض محفظة الوصول السريع
الشكل 4. مثال على تسلسل المكالمات عند عرض محفظة الوصول السريع.

لا يتم اتباع جميع عروض محفظة الوصول السريع بدفع NFC ، لكن الشكل 4 أعلاه يوضح جميع إمكانات QuickAccessWalletService . في هذا المثال ، يقوم موفر بطاقة Quick Access Wallet بتنفيذ العناصر الموضحة باللون الأزرق. من المفترض أن يتم تخزين بطاقات الدفع على الجهاز في قاعدة بيانات ويتم الوصول إليها من خلال واجهة تسمى PaymentCardManager . يُفترض أيضًا أن نشاطًا يسمى PaymentActivity يعرض نتيجة دفع NFC. يستمر التدفق على النحو التالي:

  1. يقوم المستخدم بإيماءة لإظهار محفظة الوصول السريع.
  2. تتحقق واجهة مستخدم محفظة الوصول السريع (جزء من واجهة مستخدم النظام) من مدير الحزم لمعرفة ما إذا كان تطبيق الدفع الافتراضي عبر NFC يصدر QuickAccessWalletService .

    • إذا لم يتم تصدير الخدمة ، فلن يتم عرض Quick Access Wallet.
  3. ترتبط واجهة مستخدم محفظة الوصول السريع بـ QuickAccessWalletService وتستدعي onWalletCardsRequested . تأخذ هذه الطريقة كائن طلب يحتوي على بيانات حول عدد وحجم البطاقات التي يمكن تقديمها واستدعاء. يمكن استدعاء رد الاتصال من مؤشر ترابط في الخلفية.

  4. تحسب QuickAccessWalletService البطاقات التي تريد إظهارها ، ثم تستدعي طريقة onSuccess على رد الاتصال المقدم. يوصى بأن تقوم الخدمة بتنفيذ هذه الإجراءات على سلسلة رسائل في الخلفية.

  5. بمجرد عرض البطاقات ، تقوم واجهة مستخدم النظام بإعلام QuickAccessWalletService بأنه تم تحديد البطاقة الأولى عن طريق الاتصال بـ onWalletCardSelected .

    • يتم استدعاء onWalletCardSelected في كل مرة يختار فيها المستخدم بطاقة جديدة.
    • قد يتم استدعاء onWalletCardSelected حتى إذا لم تتغير البطاقة المحددة حاليًا.
  6. عندما يرفض المستخدم محفظة الوصول السريع ، تقوم واجهة مستخدم النظام بإعلام QuickAccessWalletService عن طريق الاتصال onWalletDismissed .

في المثال أعلاه ، يقوم المستخدم بإحضار الهاتف إلى نطاق محطة دفع NFC أثناء عرض المحفظة. يعد HostApduService أحد المكونات الرئيسية للتعامل مع مدفوعات NFC ، والتي يجب تنفيذها لمعالجة وحدات APDU التي يوفرها قارئ NFC (لمزيد من المعلومات ، راجع محاكاة البطاقة المستندة إلى المضيف ). من المفترض أن يبدأ تطبيق الدفع نشاطًا لعرض التقدم ونتيجة التفاعل مع محطة NFC. ومع ذلك ، يتم عرض Quick Access Wallet UI أعلى نافذة التطبيق ، مما يعني أن نشاط الدفع محجوب بواسطة Quick Access Wallet 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 .

أذونات

يجب أن يتطلب إدخال البيان لـ QuickAccessWalletService إذن android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE المقدم في Android 11. هذا إذن على مستوى التوقيع تحتفظ به واجهة مستخدم النظام ، مما يعني أن عملية واجهة مستخدم النظام فقط هي التي يمكنها الارتباط QuickAccessWalletService . اعلم أن التطبيقات المحملة على الجانب يمكنها المطالبة بهذا الإذن والحصول على وصول كامل إلى بيانات QuickAccessWalletService على الأجهزة التي تعمل بنظام Android 10 أو أقل. لمنع ذلك ، يوصى بأن تتحقق الخدمة من إصدار الإنشاء في onCreate وتمكين الخدمة فقط على الأجهزة التي تعمل بنظام Android 11 والإصدارات الأحدث. لا توجد أذونات تطبيقات أخرى مطلوبة بخلاف تلك اللازمة لتقديم خدمات الدفع لمضاهاة بطاقة المضيف.

إذا لم يقم تطبيق الدفع الافتراضي عبر NFC بتنفيذ QuickAccessWalletService أو تصديره ، فلن يتم عرض Quick Access Wallet UI.

الإعدادات في Android 12

لتمكين أو تعطيل محفظة الوصول السريع من شاشة القفل ، يمكن للمستخدمين استخدام تبديل إظهار المحفظة في الإعدادات > العرض > قفل الشاشة . لتعطيل المحفظة في الظل ، يجب على المستخدمين تحريرها يدويًا في ظل الإعدادات السريعة.

قم بالتبديل لتمكين أو تعطيل المحفظة من شاشة القفل

الشكل 5. إظهار تبديل المحفظة في صفحة شاشة القفل في الإعدادات.

الإعدادات في Android 11

يمكن للمستخدمين إيقاف تشغيل ميزة Quick Access Wallet من تطبيق الإعدادات. تم العثور على صفحة الإعدادات في الإعدادات > النظام > الإيماءات > البطاقات والممرات .

صفحة الإعدادات لتمكين أو تعطيل ميزة محفظة الوصول السريع
الشكل 6. صفحة الإعدادات لتمكين أو تعطيل ميزة محفظة الوصول السريع.

التخصيص

إضافة عرض محفظة الوصول السريع إلى موقع آخر في واجهة مستخدم النظام

تم تصميم Quick Access Wallet 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);
  }
}

تنفذ Quick Access Wallet UI تطبيق GlobalActionsPanelPlugin و PanelViewController . يحصل GlobalActionsDialog على مثيل للمكوِّن الإضافي للمحفظة باستخدام 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();

لإزالة Quick Access Wallet من قائمة الطاقة ، احذف هدف QuickAccessWallet من بنية النظام. لإزالة Quick Access Wallet من قائمة الطاقة مع إضافتها إلى طريقة عرض مختلفة مقدمة من System UI ، قم بتضمين هدف البناء وإزالة المراجع إلى GlobalActionsPanelPlugin من GlobalActionsImpl .

ضبط التكوينات الافتراضية

أندرويد 12

في Android 12 أو أعلى ، تظهر محفظة Quick Access Wallet دائمًا في ظل الإعدادات السريعة. يتم تحديد رؤية محفظة الوصول السريع في شاشة القفل من خلال الإعداد الآمن التالي: LOCKSCREEN_SHOW_WALLET . يتحكم هذا الإعداد في ظهور رمز محفظة الوصول السريع في الجزء السفلي الأيمن من شاشة القفل. يتم تعيين هذا الإعداد على " true " افتراضيًا ، ولكن يمكن للمستخدم إيقاف تشغيله في الإعدادات > العرض > شاشة القفل > إظهار المحفظة .

أندرويد 11

في Android 11 ، يتم تحديد رؤية محفظة الوصول السريع بواسطة إعدادين آمنين: GLOBAL_ACTIONS_PANEL_ENABLED و GLOBAL_ACTIONS_PANEL_AVAILABLE . يتحكم الإعداد AVAILABLE في إمكانية تشغيل الميزة وإيقاف تشغيلها في الإعدادات. تم تعيين هذا الإعداد على true بواسطة WalletPluginService . إذا لم يتم تضمين QuickAccessWallet في الإصدار ، فسيظل الإعداد false . يتم تعيين الإعداد ENABLED على true افتراضيًا في نفس المكان ، ولكن يمكن للمستخدم إيقاف تشغيله في الإعدادات. لتغيير السلوك الافتراضي ، قم بتعديل WalletPluginService#enableFeatureInSettings .

تصديق

للتحقق من صحة تنفيذك لـ Quick Access Wallet ، قم بتشغيل CTS والاختبارات اليدوية. يجب أن تمارس التغييرات التي يتم إجراؤها على المكون الإضافي أيضًا اختبارات robolectric المضمنة.

اختبارات CTS

قم بتشغيل اختبارات CTS الموجودة في cts/tests/quickaccesswallet .

الاختبارات اليدوية لنظام Android 12

يتطلب اختبار الميزات الأساسية لـ Quick Access Wallet محطة دفع NFC (حقيقية أو مزيفة) وتطبيق دفع NFC الذي ينفذ QuickAccessWalletService (تطبيق المحفظة). تشمل الميزات الأساسية التي يجب اختبارها: التوفر ، والحالة الصفرية ، واختيار البطاقة ، وسلوك قفل الشاشة.

التوفر

  • إذا كان تطبيق الدفع الافتراضي عبر NFC لا يدعم هذه الميزة ، فلا يمكن الوصول إلى محفظة الوصول السريع في الإعدادات السريعة ولا في شاشة القفل.
  • إذا كان تطبيق الدفع الافتراضي عبر NFC يدعم الميزة ، فيمكن الوصول إلى محفظة الوصول السريع في ظل الإعدادات السريعة.
  • إذا كان تطبيق الدفع الافتراضي عبر NFC يدعم الميزة وإذا كان إعداد LOCKSCREEN_SHOW_WALLET true ، فيمكن الوصول إلى محفظة الوصول السريع على شاشة القفل.
  • إذا كان تطبيق الدفع الافتراضي عبر NFC يدعم الميزة وإذا كان إعداد LOCKSCREEN_SHOW_WALLET false ، فلا يمكن الوصول إلى محفظة الوصول السريع على شاشة القفل.

حالة الصفر

  • إذا تم تمكين QuickAccessWalletService وتصديره ولكنه لا يوفر أي بطاقات ، فإن اللوحة الموجودة في Shade تظهر كما هو موضح في المثال في الشكل 7. يؤدي النقر فوق المربع إلى فتح تطبيق الدفع NFC الافتراضي.

    مثال على مربع في الظل يعرض تطبيق الدفع الافتراضي بتقنية NFC

    الشكل 7. مثال على مربع في الظل يعرض تطبيق الدفع الافتراضي بتقنية NFC.

  • يؤدي النقر فوق عرض الحالة الفارغة كما هو موضح في الشكل 8 إلى فتح تطبيق الدفع الافتراضي بتقنية NFC. يتم عرض عرض الحالة الفارغة هذا فقط عندما يكون لدى المستخدم بطاقة واحدة متبقية في المحفظة ، ويزيل البطاقة من صفحة تفاصيل البطاقة ، ثم يعود إلى عرض المحفظة.

  • تعرض شاشة القفل رمز المحفظة.

عرض الحالة الفارغ في محفظة الوصول السريع

الشكل 8. عرض الحالة الفارغة في Quick Access Wallet UI.

دولة غير صفرية

  • إذا كان تطبيق المحفظة يوفر بطاقة واحدة أو أكثر ، فسيظهر المربع الموجود في الظل كما هو موضح في الشكل 9.

    مثال على البلاط في الظل عندما يحتوي تطبيق المحفظة على بطاقة واحدة أو أكثر

    الشكل 9. مثال على مربع في الظل عندما يحتوي تطبيق المحفظة على بطاقة واحدة أو أكثر.

  • يؤدي النقر فوق المربع إلى إظهار دائرة البطاقة.

  • تعرض شاشة القفل زرًا يفتح محفظة الوصول السريع.

    Quick Access Wallet UI مع عرض بطاقة

    الشكل 10. Quick Access Wallet UI مع عرض بطاقة.

  • إذا كانت البطاقة المعروضة تمثل طريقة دفع NFC ، فإن تثبيت الهاتف أمام محطة دفع NFC يؤدي إلى استخدام طريقة الدفع هذه ورفض عرض المحفظة.

  • 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.

متطلبات

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 ).

التنفيذ

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 .

Permissions

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.

التخصيص

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 .

تصديق

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.

متطلبات

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 ).

التنفيذ

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 .

Permissions

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.

التخصيص

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 .

تصديق

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.