Android SDK による問題パス

パスを作成して JWT でエンコードしたら、Android アプリで発行できます。そのためには、ユーザーのデバイスで Google Wallet API が利用可能であることを確認して、[Google ウォレットに追加] ボタンを表示し、ユーザーがボタンをタップしたらパスを Google ウォレットに保存する必要があります。

前提条件

パスの発行を試みる前に、次の手順を完了してください。

1. Google ウォレット Android SDK をインストールする

Google ウォレット Android SDK を使用するには、アプリレベルの build.gradle ファイルの dependencies セクションに com.google.android.gms:play-services-pay を追加します。

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

2. Google Wallet API の可用性を確認する

新しいオブジェクトを保存する前に、PayClient クラスの getPayApiAvailabilityStatus メソッドを呼び出して、Google Wallet API が対象デバイスで使用可能であることを確認します。

まず、ボタンを表示するアクティビティにメンバー変数を追加し、そのアクティビティが作成されたときに変数をインスタンス化します。

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 パターンを使用する場合は、UI 関連のビジネス ロジック(UI 要素、アクティビティの結果など)を Activity または Fragment に配置し、操作ロジック(クライアントのインスタンス化、ネットワーク呼び出しのトリガーなど)をビューモデルに配置します。

次に、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 ウォレットにパスを追加する

GiftCardObject を追加するには、無署名の JWT を savePasses メソッドに渡します。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 になります。