1. 准备工作
借助 Google Wallet API,您可以通过各种预定义的卡券类型与用户互动:会员卡、优惠券、礼品卡、活动门票、公交票卡和登机牌。这些卡券类型都具有特定于用例的字段和功能。但我们知道,这些类型可能并非在任何用例中都适用,因此我们创建了一个通用卡券类型。顾名思义,如果您的用例不属于任何其他专用类型,则应使用通用卡券类型。以下是通用卡券类型的一些用例:
- 停车券
- 图书馆会员卡
- 储值代金券
- 健身房会员卡
- 保险卡
- 各种预订
凡是能够以卡片(最多包含 3 行信息,可选择提供条形码和详细信息部分)形式向用户展示的用例,只要符合使用限制政策的要求,您都可以为其使用通用卡券。
借助 Google Wallet API,您可以创建:
- 卡券类。您可以将类视为模板,其中包含属于某个项目或活动的所有卡券共享的通用信息。所有卡券对象都属于一个类。
- 卡券对象服务于与您的商家活动和用户相关的具体用途(例如,停车券、健身房会员卡)。这些项都与之前定义的类相关联,并会继承类的通用属性。
此 Codelab 将为您提供一个预定义的类,并指导您为卡券对象定义 JSON,以及向您的 Android 应用添加“Add to Google Wallet”按钮,以允许用户将卡券保存到 Google 钱包。
如需详细了解 Google Wallet API 或如何向 Android 应用添加“Add to Google Wallet”按钮,请访问 Google 钱包开发者文档。
前提条件
- 一台安装了 Android Studio 的计算机。
- 能够在 Android Studio 中创建和运行项目。
- 已安装 Git。
学习内容
- 如何将 Google Wallet SDK 添加到您的 Android 应用。
- 如何检查 Wallet API 是否可用。
- 如何实现界面,以允许用户将卡券添加到 Google 钱包。
2. 进行设置
创建临时发卡机构帐号
如需为用户创建卡券,您首先需要创建发卡机构帐号,启用 Wallet API,然后创建类。所有这些操作都可以通过 Google Pay 商家控制台完成。不过,只有在审批流程结束后,您才能获得访问权限。因此,在此 Codelab 中,我们将为您创建一个临时发卡机构帐号,以及一个卡券类。
- 记下发卡机构 ID 和类 ID,您在后续步骤中会用到这些 ID。
克隆 Git 代码库
使用以下命令克隆包含您要修改的 Android 项目的 Git 代码库:
git clone -b wallet-lab git@github.com:google-pay/android-quickstart.git
在 Android Studio 中打开
打开 Android Studio,从欢迎屏幕中选择“Open”,然后在新克隆的代码库中选择 kotlin
文件夹,并以项目的形式将其打开。
3. 将 Google Wallet SDK 添加到您的应用
Android 项目包含一个空 activity,我们很快将修改此 activity,但首先,我们要将 Google Wallet SDK 添加为依赖项。在 Android Studio 中,选择模块级“build.gradle”脚本,并将以下代码行添加到 dependencies
部分:
dependencies {
...
implementation 'com.google.android.gms:play-services-pay:16.0.3'
}
更改后,点击 Android Studio 右上角的 Gradle“Sync Project”按钮。
4. 添加“Add to Google Wallet”按钮
接下来,您将向 activity 添加“Add to Google Wallet”按钮。该按钮的相关资源已为您添加到项目中,您只需将其添加到布局文件中即可。为此,我们建议您创建一个包含该按钮的单独布局:
add_to_google_wallet_button.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="48sp"
android:background="@drawable/add_to_google_wallet_button_background_shape"
android:contentDescription="@string/add_to_google_wallet_button_content_description">
<ImageView
android:layout_width="227dp"
android:layout_height="26dp"
android:layout_gravity="center"
android:duplicateParentState="true"
android:src="@drawable/add_to_google_wallet_button_foreground"/>
</FrameLayout>
该按钮如下所示:
然后,将其添加到布局文件中:
<include
android:id="@+id/addToGoogleWalletButton"
layout="@layout/add_to_google_wallet_button"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="10dp"/>
5. 检查 API 是否可用
现在该开始编码了。在 Android Studio 中打开您将在其中调用 Google Wallet API 的文件(如果您使用的是示例应用,则打开 CheckoutActivity.kt
文件),然后将 PayClient
作为类成员实例化。此对象可帮助您调用 Google Wallet API。getClient
方法会接收实例化类的上下文(在本例中,就是调用 activity 的上下文)。
private lateinit var walletClient: PayClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
walletClient = Pay.getClient(this)
...
}
接下来,确保 Google Wallet SDK 和应用在设备上可用。在类中创建一个新方法(例如:fetchCanUseGoogleWalletApi
),以确定 Google Wallet API 是否可用;如果该 API 可用,则创建另一个方法,以通过显示“Add to Google Wallet”按钮来响应结果。
private fun fetchCanUseGoogleWalletApi() {
walletClient
.getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
.addOnSuccessListener { status ->
if (status == PayApiAvailabilityStatus.AVAILABLE)
layout.passContainer.visibility = View.VISIBLE
}
.addOnFailureListener {
// Hide the button and optionally show an error message
}
}
最后,在 onCreate
方法中调用 fetchCanUseGoogleWalletApi
方法,以确定 Google Wallet API 是否可用:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
fetchCanUseGoogleWalletApi()
}
现在,当您运行应用时,应该会在界面中看到“Add to Google Wallet”按钮:
6. 向 Google 钱包添加卡券
现在您已经验证了 Google Wallet API 可用,接下来您可以提示用户将卡券添加到 Google 钱包。在此之前,请花点时间查看以下研讨会中创建的卡券:
该布局利用通用卡券的灵活性来创建可用作身份徽章的对象,同时还支持用于提醒参与者在活动期间收集积分的提示。该通用对象如下所示:
{
"id": "999999.d1fa-4cca1...",
"classId": "999999.a92b-129f...",
"genericType": "GENERIC_TYPE_UNSPECIFIED",
"hexBackgroundColor": "#4285f4",
"logo": { ... },
"cardTitle": { ... },
"subheader": { ... },
"header": { ... },
"barcode": { ... },
"heroImage": { ... },
"textModulesData": []
}
如需插入对象,该 API 需要封装新元素的未签名 JWT 主体:
{
"iss": <owner-email-address>,
"aud": "google",
"typ": "savetowallet",
"iat": <unix-time>,
"origins": [],
"payload": {
"genericObjects": [],
"genericClasses": [],
...
}
}
将这些元素组合起来(使用您之前创建临时发卡机构帐号时获取的值),并将生成的对象分配给类中的某个变量:
private val issuerEmail = "<insert-your-issuer-email-address>"
private val issuerId = "<insert-your-issuer-id>"
private val passClass = "<insert-your-class-id>"
private val passId = UUID.randomUUID().toString()
private val newObjectJson = """
{
"iss": "$issuerEmail",
"aud": "google",
"typ": "savetowallet",
"iat": ${Date().time / 1000L},
"origins": [],
"payload": {
"genericObjects": [
{
"id": "$issuerId.$passId",
"classId": "$passClass",
"genericType": "GENERIC_TYPE_UNSPECIFIED",
"hexBackgroundColor": "#4285f4",
"logo": {
"sourceUri": {
"uri": "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"
}
},
"cardTitle": {
"defaultValue": {
"language": "en",
"value": "Google I/O '22 [DEMO ONLY]"
}
},
"subheader": {
"defaultValue": {
"language": "en",
"value": "Attendee"
}
},
"header": {
"defaultValue": {
"language": "en",
"value": "Alex McJacobs"
}
},
"barcode": {
"type": "QR_CODE",
"value": "$passId"
},
"heroImage": {
"sourceUri": {
"uri": "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/google-io-hero-demo-only.jpg"
}
},
"textModulesData": [
{
"header": "POINTS",
"body": "${Random.nextInt(0, 9999)}",
"id": "points"
},
{
"header": "CONTACTS",
"body": "${Random.nextInt(1, 99)}",
"id": "contacts"
}
]
}
]
}
}
"""
最后,返回 onCreate
方法,向“Add to Google Wallet”按钮添加点击处理程序,以便使用客户端中的 savePasses
方法启动操作:
private val addToGoogleWalletRequestCode = 1000
private lateinit var layout: ActivityCheckoutBinding
private lateinit var addToGoogleWalletButton: View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Use view binding to access the UI elements
layout = ActivityCheckoutBinding.inflate(layoutInflater)
setContentView(layout.root)
addToGoogleWalletButton = layout.addToGoogleWalletButton.root
addToGoogleWalletButton.setOnClickListener {
walletClient.savePasses(newObjectJson, this, addToGoogleWalletRequestCode)
}
...
}
这样一来,您就使用之前创建的发卡机构 ID 和类 ID 为新对象定义了 JSON。当用户点击“Add to Google Wallet”按钮时,系统会调用 payClient.savePasses
,并提示用户将新的卡券对象添加到 Google 钱包:
7. 处理结果
即将大功告成。最后,处理操作结果(成功或失败)。替换 onActivityResult
方法以包含以下代码:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == addToGoogleWalletRequestCode) {
when (resultCode) {
RESULT_OK ->
// Pass saved successfully. Consider informing the user.
RESULT_CANCELED -> {
// Save canceled
}
PayClient.SavePassesResult.SAVE_ERROR -> data?.let { intentData ->
val errorMessage = intentData.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)
// Handle error. Consider informing the user.
}
else -> {
// Handle unexpected (non-API) exception
}
}
}
}
借助此代码,您可以处理卡券添加成功状态、用户取消操作以及可能出现的任何错误。再次运行应用,确认是否可以按预期添加卡券并处理结果。
8. 恭喜
恭喜,您已成功在 Android 设备上集成 Google Wallet API!
了解详情
如需查看完整示例,请参阅 GitHub 中的示例应用中的完整集成。
注册发卡机构帐号
当您准备好在生产环境中发布自己的卡券时,请前往 Google Pay 和钱包控制台,请求对 Google Wallet API 的访问权限,并授权您的 Android 应用对该 API 发出调用。如需了解详情,请参阅此文档。