Problema relativo alle tessere con l'SDK Android

Dopo aver creato una tessera e averla codificata in un JWT, puoi emetterla nella tua app Android. A tale scopo, dovrai verificare che l'API Google Wallet sia disponibile sul dispositivo dell'utente, presentare all'utente un pulsante "Aggiungi a Google Wallet", quindi salvare la tessera nel suo account Google Wallet dopo che ha toccato il pulsante.

Prerequisiti

Prima di provare a emettere una tessera, assicurati di aver completato i seguenti passaggi:

1. Installa l'SDK Google Wallet per Android

Per utilizzare l'SDK Google Wallet per Android, aggiungi com.google.android.gms:play-services-pay alla sezione dependencies del tuo file build.gradle a livello di app:

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

2. Verificare la disponibilità dell'API Google Wallet

Prima di salvare il nuovo oggetto, assicurati che l'API Google Wallet sia disponibile sul dispositivo di destinazione chiamando il metodo getPayApiAvailabilityStatus nella classe PayClient.

Per iniziare, aggiungi una variabile membro all'attività in cui visualizzerai il pulsante e crea un'istanza quando l'attività viene creata:

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
}

Se utilizzi altri pattern di progettazione, valuta la possibilità di posizionare correttamente la logica di business specifica del dominio. Ad esempio, se utilizzi il pattern MVVM, inserisci la logica di business relativa all'interfaccia utente nell'attività o nel frammento (ad es. Elementi UI, risultato di attività) e logica operativa nel modello di visualizzazione (ad esempio, documentazione dei clienti, attivatori di chiamate di rete).

Dopodiché utilizza l'PayClient per verificare se l'API è disponibile:

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
    });
}

Infine, chiama il metodo appena definito nell'applicazione quando devi determinare la disponibilità dell'API.

Gestisci quando l'API non è disponibile

Alcuni motivi per cui l'API potrebbero non essere disponibili sono le versioni di Android o Google Play Services non aggiornate oppure il fatto che Google Wallet non è disponibile nel paese dell'utente.

Se l'API non è disponibile, valuta la possibilità di nascondere il pulsante e di ricorrere a un'integrazione diversa (ad es. utilizzando un link JWT). Tieni presente che l'utente potrebbe diventare idoneo a utilizzare l'API in futuro.

3. Aggiungi il pulsante "Aggiungi a Google Wallet"

Google Wallet fornisce un pulsante familiare che puoi utilizzare per attivare il flusso Aggiungi a Google Wallet nella tua applicazione. Gli asset vettoriali per il pulsante sono disponibili nelle linee guida per i pulsanti.

Puoi importare asset vettoriali in Android Studio in File > New > Vector Asset. Seleziona "File locale" nella procedura guidata, aggiungi un nome (ad esempio: add_to_google_wallet_button.xml) e individua il file nell'unità locale per importarlo.

  • Pulsante Aggiungi a Google Wallet
  • Pulsante Aggiungi a Google Wallet ridotto

A questo punto, puoi utilizzare il disegno importato per aggiungere il pulsante all'interfaccia utente:

    <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" />

Il pulsante ha un valore layout_height di 48 dp e deve avere una larghezza di almeno 200 dp.

4. Aggiungere una tessera all'account Google Wallet di un utente

Il EventObject può essere aggiunto passando un JWT non firmato al metodo savePasses. Puoi avviare l'operazione di aggiunta facendo clic sul pulsante Google Wallet.

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
}

Gestione dei risultati

Il metodo savePasses attiva il flusso di salvataggio e richiama il metodo onActivityResult dopo il completamento del flusso di salvataggio. L'implementazione di onActivityResult dovrebbe essere simile alla seguente:

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
      }
    }
  }
}

Una volta aggiunta correttamente la tessera, resultCode contiene il valore di Activity.RESULT_OK.