通过通知付款

快速付款演示集成说明

某些商家需要提供快速付款的功能,以便用户获得或重新获得服务的使用权限(例如:移动流量套餐、家庭帐单、服务升级或之前被拒绝的付款)。商家通常会通过移动设备向用户通知这些事件。但是,要执行实际付款操作,用户必须切换上下文并花费很多时间浏览各种表单,而这会大大降低完成付款的机会。

这种模式可帮助您直接将付款操作添加到通知中,让用户可以立即采取操作,只需两次点按即可完成付款。在本指南中,您将学习如何在 Android 应用中打造类似体验。

要求

本指南假定您的 Android 应用已集成了有效的 Google Pay。如果您尚未添加任何集成服务,可以先参阅我们的教程或者分步引导式 Codelab

基础组件

将 Google Pay 按钮添加到通知这一操作基于 Android 的两个基础组件:

自定义通知布局

Android 上的常规通知有一个明确的剖析定义,可以适应多种视觉上下文。使用标准模板有助于确保无论设备的屏幕方向、设备类型和操作系统版本如何,通知都能正确显示,因此建议您借助此方法向用户通知需要他们注意的事件。

如果标准布局不符合需求,您可以使用自定义通知布局提供自己的布局。在本指南中,您会使用自定义布局将 Google Pay 按钮添加到通知中,让用户可以直接从通知发起付款。

活动

活动有助于在您的应用中向用户展示功能。活动通常具有关联的界面,并构成应用中可浏览的屏幕层次结构。

当用户按 Google Pay 按钮时,Google 会返回可用的付款方式列表,供用户完成交易。此付款表格必须从托管活动中启动。您可以使用透明的活动来创建展示,让付款表格直接显示在通知之上。

定义通知的布局

为通知创建布局的过程非常类似于为常规活动定义界面的过程。类似于微件,通知也使用 RemoteViews 类管理布局中的元素。因此,与常规布局相比,可用的支持视图列表项更少。

首先,在 res/layout/ 文件夹中创建布局资源文件,描述您想要的通知外观。请参考示例应用中的 notification_account_top_up.xml

自定义通知布局示例
图 1. 自定义通知布局示例。

添加 Google Pay 按钮

当布局准备就绪后,最后一步就是将 Google Pay 按钮添加到其中。要添加按钮,只需从预构建的 Google Pay 资产集合中将相应的按钮资源包括到布局 XML 文件中。这些资产包含按钮的图片资源,可以适应多种屏幕尺寸、分辨率和语言,并遵循 Google Pay 的品牌推广指南。您可以直接从品牌推广指南部分下载它们。

<include
  android:id="@+id/googlePayButton"
  layout="@layout/buy_with_googlepay_button"
  android:layout_width="wrap_content"
  android:layout_height="48sp" />

现在,当您查看布局的设计视图时,可以看到 Google Pay 按钮:

包含 Google Pay 按钮的自定义通知示例
图 2. 包含 Google Pay 按钮的自定义通知示例。

触发通知

根据应用或服务中的互动流程,您可以分发通知以响应不同的事件。一种常见模式是使用消息传递服务从后端服务器发出推送通知。如果您尚未向 Android 应用添加推送功能,请查看 Firebase Cloud Messaging 和这份绝佳教程,了解如何开始添加。

创建并设置视图

为了初始化通知布局及其中包含的视图,该流程的工作方式与常规活动稍有不同。请分别配置视图的结构和对用户互动的响应。每当状态更新时,您都必须重绘通知。

首先,创建一个 RemoteViews 对象来保存布局层次结构:

Kotlin

    val notificationLayout = RemoteViews(packageName, R.layout.large_notification)

Java

    RemoteViews notificationLayout = new RemoteViews(packageName, R.layout.large_notification);

您现在可以使用 notificationLayout 对象更改底层视图(按钮、文本、图片等),以便修改其样式或配置它们来响应用户互动。在此示例中,Google Pay 按钮会捕获点按事件以启动付款流程:

Kotlin

    val selectOptionIntent = Intent(context, PaymentNotificationIntentService::class.java)
      selectOptionIntent.action = ACTION_SELECT_PREFIX + option
      notificationLayout.setOnClickPendingIntent(buttonId, PendingIntent.getService(
              context, 0, selectOptionIntent, PendingIntent.FLAG_UPDATE_CURRENT))

Java

    Intent payIntent = new Intent(context, PaymentTransparentActivity.class);
    payIntent.setAction(ACTION_PAY_GOOGLE_PAY);
    payIntent.putExtra(OPTION_PRICE_EXTRA, OPTION_PRICE_CENTS.get(selectedOption));
    notificationLayout.setOnClickPendingIntent(
        R.id.googlePayButton, pendingIntentForActivity(context, payIntent));

在这种情况下,用于显示付款表格的 Intent 包含能够标识 Intent 目标的操作,并包含额外信息(如选定商品的价格)。此外,Intent 会将事件与 Google Pay 按钮相关联,每当用户点按此按钮时,Intent 都会执行并将付款活动置于前台。

显示通知

创建和配置通知后,最后一步是向用户显示该通知。为此,请使用上述定义的参数和其他配置来构建通知对象,以确定其行为方式:

Kotlin

    val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(context.getString(R.string.notification_title))
            .setContentText(context.getString(R.string.notification_text))
            .setCustomBigContentView(notificationLayout)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setAutoCancel(false)
            .setOnlyAlertOnce(true)
            .build()

Java

    Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle(context.getString(R.string.notification_title))
        .setContentText(context.getString(R.string.notification_text))
        .setCustomBigContentView(notificationLayout)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setAutoCancel(false)
        .setOnlyAlertOnce(true)
        .build();

此配置中的一些属性可显示此通知的工作方式,而在您的应用中,其他属性的行为可能根据您的偏好设置和用例而不同。其中部分字段为:

字段 说明
通知渠道 NOTIFICATION_CHANNEL_ID 从 Android 8.0(API 级别 26)开始,您必须将所有通知分配给一个渠道。渠道会按用户可管理的分类主题,对通知进行分组。您可以在 Android 文档中详细了解通知渠道
自定义大型内容视图 notificationLayout 您之前准备好的布局将在这里与通知关联。
自动取消 false 如果您将通知设置为可互动(例如本示例中使用的通知),可以将自动取消参数设置为 false,以确保当用户轻触其中的任意一个视图时,通知不会自动关闭。
仅提醒一次 true 此通知会对用户输入做出响应。将此参数设置为 true 以避免在通知更新时发出声音、提示和振动。

要了解与通知有关的其他配置和一般概念,请查看 Android 文档中的自定义通知概览部分。

最后,要触发并显示通知,请使用 notify 方法传入之前创建的 notification 对象:

Kotlin

    NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, notification)

Java

    NotificationManagerCompat.from(context).notify(NOTIFICATION_ID, notification);

NOTIFICATION_ID 是用于标识通知的任意整数,以后更新或移除通知时需要用到。

付款

当用户点按 Google Pay 按钮时,即显示付款表格,以便用户可以选择付款方式来完成交易。您可以使用 Google Pay API 在活动之上显示付款表格。因为通知会启动新的付款流程,所以使此活动变得透明,便可以让用户感觉不必打开您的应用即可完成操作。我们来看一下此活动的 onCreate 方法:

Kotlin

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // Dismiss the notification UI if the activity was opened from a notification
    if (Notifications.ACTION_PAY_GOOGLE_PAY == intent.action) {
      sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
    }

    // Initialise the payments client
    startPayment()
  }

Java

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Dismiss the notification UI if the activity was opened from a notification
    if (Notifications.ACTION_PAY_GOOGLE_PAY.equals(getIntent().getAction())) {
      sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
    }

    // Initialise the payments client
    startPayment();
  }

如您所见,此活动几乎什么都没发生过。具有 Intent 常量 ACTION_CLOSE_SYSTEM_DIALOGS 的广播会关闭通知菜单。请记住,此活动只能通过通知中的 Google Pay 按钮进行访问,如果没有广播,通知对话框会保持打开状态。

除此之外,此活动唯一需要执行的操作是显示付款表格,该表格通过 showPaymentsSheet 方法启动。然后,只需调用 Google Pay API 中的 loadPaymentData 方法即可。请查看示例应用中的 PaymentTransparentActivity.java 文件,探索活动中的所有逻辑。