Cartões de problemas com o SDK do Android

Depois de criar um cartão e codificá-lo em um JWT, você estará pronto para emiti-lo no app Android. Para isso, verifique se a API Google Wallet está disponível no dispositivo do usuário, mostre um botão "Adicionar à Carteira do Google" e salve o cartão na Carteira do Google quando o usuário tocar no botão.

Pré-requisitos

Antes de emitir um cartão, verifique se você concluiu as seguintes etapas:

1. Instalar o SDK da Carteira do Google para Android

Para usar o SDK da Carteira do Google para Android, adicione com.google.android.gms:play-services-pay à seção dependencies do arquivo build.gradle do app:

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

2. Verificar a disponibilidade da API Google Wallet

Antes de salvar o novo objeto, confira se a API Google Wallet está disponível no dispositivo de destino chamando o método getPayApiAvailabilityStatus na classe PayClient.

Comece adicionando uma variável de membro à atividade em que você vai mostrar o botão e instanciá-la quando a atividade for criada:

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 você estiver usando outros padrões de design, considere usar a lógica de negócios específica do domínio de maneira adequada. Por exemplo, se você estiver usando o padrão MVVM, coloque a lógica de negócios relacionada à interface na sua atividade ou fragmento (por exemplo, elementos da IU, resultado da atividade) e a lógica operacional no modelo de visualização (por exemplo, instanciação do cliente, gatilhos de chamadas de rede).

Em seguida, use o PayClient para verificar se a API está disponível:

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

Por fim, chame o método que você acabou de definir no aplicativo quando precisar determinar a disponibilidade da API.

Processar quando a API estiver indisponível

Alguns motivos para a API não estar disponível incluem as versões do Android ou do Google Play Services estarem desatualizadas ou a Carteira do Google estar indisponível no país do usuário.

Se a API não estiver disponível, oculte o botão e use uma integração diferente (por exemplo, usando um link JWT). É possível que o usuário se qualifique para usar a API no futuro.

3. Adicionar o botão "Adicionar à Carteira do Google"

A Carteira do Google oferece um botão conhecido que pode ser usado para acionar o fluxo "Adicionar à Carteira do Google" no aplicativo. Os recursos vetoriais do botão estão disponíveis nas Diretrizes de botões.

É possível importar recursos vetoriais no Android Studio em File > New > Vector Asset. Selecione "Arquivo local" no assistente, adicione um nome (por exemplo, add_to_google_wallet_button.xml) e encontre o arquivo no drive local para importar.

  • Botão "Adicionar à Carteira do Google"
  • Botão "Adicionar à Carteira do Google" compacto

Agora, é possível usar o drawable importado para adicionar o botão à interface do usuário:

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

O botão tem um layout_height de 48 dp e precisa ter pelo menos 200 dp de largura.

4. Adicionar um cartão à Carteira do Google de um usuário

O LoyaltyObject pode ser adicionado transmitindo um JWT não assinado para o método savePasses. É possível iniciar a operação de adição clicando no botão "Carteira do 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
}

Processamento de resultados

O método savePasses aciona o fluxo de salvamento e invoca o método onActivityResult depois que ele é concluído. A implementação do onActivityResult precisa ser semelhante a esta:

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

Quando o cartão é adicionado, o resultCode tem o valor de Activity.RESULT_OK.