Android SDK 的问题传递

创建卡券并将其编码到 JWT 中后,您就可以在 Android 应用中发布卡券了。为此,您需要检查用户设备上是否提供了 Google Wallet API,向其显示“添加到 Google 钱包”按钮,然后在用户点按该按钮后,将卡券保存到其 Google 钱包。

前提条件

在尝试发放卡券之前,请确保您已完成以下操作:

1. 安装 Google 钱包 Android SDK

如需使用 Google 钱包 Android SDK,请将 com.google.android.gms:play-services-pay 添加到应用级 build.gradle 文件的 dependencies 部分:

  implementation "com.google.android.gms:play-services-pay:16.4.0"

2. 检查 Google Wallet API 的可用性

在保存新对象之前,请调用 PayClient 类中的 getPayApiAvailabilityStatus 方法,以确保 Google Wallet API 在目标设备上可用。

首先,向将在其中显示按钮的 activity 添加一个成员变量,并在创建 activity 时对其进行实例化:

Kotlin

import com.google.android.gms.pay.PayClient

private lateinit var walletClient: PayClient

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

  walletClient = Pay.getClient(this)

  // Additional logic in your onCreate method
}

Java

import com.google.android.gms.pay.PayClient;

private final PayClient walletClient;

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

  walletClient = Pay.getClient(application);

  // Additional logic in your onCreate method
}

如果您使用的是其他设计模式,请考虑适当放置特定于网域的业务逻辑。例如,如果您使用的是 MVVM 模式,请将与界面相关的业务逻辑放置在 activity 或 fragment 中(例如:界面元素、activity 结果)和视图模型中的操作逻辑(例如,客户端实例化、网络调用触发器)。

接下来,使用 PayClient 检查该 API 是否可用:

Kotlin

import com.google.android.gms.pay.PayApiAvailabilityStatus

private fun fetchCanUseGoogleWalletApi() {
  walletClient
    .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
    .addOnSuccessListener { status ->
      if (status == PayApiAvailabilityStatus.AVAILABLE) {
        // The API is available, show the button in your UI
      } else {
        // The user or device is not eligible for using the Pay API
      }
    }
    .addOnFailureListener {
      // Hide the button and optionally show an error message
    }
}

Java

import com.google.android.gms.pay.PayApiAvailabilityStatus;

private void fetchCanAddPassesToGoogleWallet() {
  walletClient
    .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
    .addOnSuccessListener(status -> {
      if (status == PayApiAvailabilityStatus.AVAILABLE) {
        // The API is available, show the button in your UI
      } else {
        // The user or device is not eligible for using the Pay API
      };
    })
    .addOnFailureListener(exception -> {
      // Google Play Services is too old, or API availability not verified
      // Hide the button and optionally show an error message
    });
}

最后,当需要确定 API 的可用性时,请调用您刚在应用中定义的方法。

在 API 不可用时处理

该 API 不可用的一些原因包括 Android 或 Google Play 服务版本过旧,或者 Google 钱包在用户所在的国家/地区不可用。

如果 API 不可用,请考虑隐藏该按钮并回退到其他集成(例如使用 JWT 链接)。请注意,用户将来可能有资格使用该 API。

3. 添加“添加到 Google 钱包”按钮

Google 钱包提供了一个熟悉的按钮,您可以使用该按钮在您的应用中触发“添加到 Google 钱包”流程。按钮指南中提供了按钮的矢量资源。

您可以在 Android Studio 中的 File > New > Vector Asset 下导入矢量资源。在向导中选择“Local file”,添加一个名称(例如: add_to_google_wallet_button.xml),然后在本地驱动器中找到该文件以将其导入。

  • “添加到 Google 钱包”按钮
  • “添加到 Google 钱包”按钮精简

现在,您可以使用导入的可绘制对象将按钮添加到界面中:

    <ImageButton
        android:id="@+id/addToGoogleWalletButton"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:minWidth="200dp"
        android:clickable="true"
        android:src="@drawable/add_to_google_wallet_button" />

按钮的 layout_height 为 48 dp,宽度必须至少为 200 dp。

4. 将卡券添加到用户的 Google 钱包

可以通过将未签名的 JWT 传递给 savePasses 方法来添加 GiftCardObject。点击“Google 钱包”按钮即可开始添加操作。

Kotlin

import android.os.Bundle
import android.view.View
import com.google.android.gms.samples.wallet.databinding.ActivityCheckoutBinding

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
  addToGoogleWalletButton.setOnClickListener {
    walletClient.savePasses(newObjectJson, this, addToGoogleWalletRequestCode)
  }

  // Additional logic in your onCreate method
}

Java

import android.os.Bundle;
import android.view.View;
import com.google.android.gms.samples.wallet.databinding.ActivityCheckoutBinding;

private static final int ADD_TO_GOOGLE_WALLET_REQUEST_CODE = 999;

private ActivityCheckoutBinding layout:
private View addToGoogleWalletButton;

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

  // Use view binding to access the UI elements
  layout = ActivityCheckoutBinding.inflate(getLayoutInflater());
  setContentView(layout.getRoot());

  addToGoogleWalletButton = layout.addToGoogleWalletButton;
  addToGoogleWalletButton.setOnClickListener(v -> {
    walletClient.savePasses(newObjectJson, this, ADD_TO_GOOGLE_WALLET_REQUEST_CODE);
  });

  // Additional logic in your onCreate method
}

结果处理

savePasses 方法会触发保存流程,并在保存流程完成后调用 onActivityResult 方法。onActivityResult 的实现应与以下代码类似:

Kotlin

import android.content.Intent

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  super.onActivityResult(requestCode, resultCode, data)

  if (requestCode == addToGoogleWalletRequestCode) {
    when (resultCode) {
      RESULT_OK -> {
        // Pass saved successfully
      }

      RESULT_CANCELED -> {
        // Save operation canceled
      }

      PayClient.SavePassesResult.SAVE_ERROR -> data?.let { intentData ->
        val errorMessage = intentData.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)
        // Handle error
      }

      else -> {
          // Handle unexpected (non-API) exception
      }
    }
  }
}

Java

import android.content.Intent;

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
  super.onActivityResult(requestCode, resultCode, data);

  if (requestCode == ADD_TO_GOOGLE_WALLET_REQUEST_CODE) {
    switch (resultCode) {
      case RESULT_OK: {
        // Pass saved successfully
        break;
      }

      case RESULT_CANCELED: {
        // Save operation canceled
        break;
      }

      case PayClient.SavePassesResult.SAVE_ERROR: {
        if (data != null) {
          String apiErrorMessage = data.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE);
          // Handle error
        }
        break;
      }

      default: {
        // Handle unexpected (non-API) exception
      }
    }
  }
}

成功添加卡券后,resultCode 会包含 Activity.RESULT_OK 的值。