אישורים על בעיות שקשורות ל-Android SDK

אחרי שיוצרים כרטיס ומקודדים אותו ב-JWT, אפשר להנפיק אותו באפליקציה ל-Android. כדי לעשות את זה, צריך לוודא ש-Google Wallet API זמין במכשיר של המשתמש, להציג לו את הכפתור "הוספה ל-Google Wallet" ולשמור את הכרטיס ב-Google Wallet שלו אחרי שהוא לוחץ על הכפתור.

דרישות מוקדמות

לפני שמנסים להנפיק כרטיס, צריך לוודא שהשלבים הבאים הושלמו:

1. התקנת Google Wallet Android SDK

כדי להשתמש ב-Google Wallet Android SDK, מוסיפים את com.google.android.gms:play-services-pay לקטע dependencies בקובץ build.gradle ברמת האפליקציה:

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

2. איך בודקים אם Google Wallet API זמין

לפני ששומרים את האובייקט החדש, צריך לוודא ש-Google Wallet API זמין במכשיר היעד. כדי לעשות את זה, מפעילים את השיטה getPayApiAvailabilityStatus במחלקה PayClient.

קודם כל, מוסיפים משתנה חבר לפעילות שבה יוצג הלחצן, ויוצרים מופע שלו כשהפעילות נוצרת:

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 (למשל: רכיבים בממשק המשתמש, תוצאת הפעילות) ואת הלוגיקה התפעולית במודל התצוגה (למשל: יצירת מופע של לקוח, טריגרים של קריאות לרשת).

אחר כך, משתמשים ב-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 Services לא עדכניות, או כי Google Wallet לא זמין במדינה של המשתמש.

אם ה-API לא זמין, כדאי להסתיר את הכפתור ולהשתמש בשילוב אחר (למשל, באמצעות קישור JWT). חשוב לדעת שהמשתמש עשוי להיות זכאי להשתמש ב-API בעתיד.

3. הוספת הלחצן "הוספה ל-Google Wallet"

ב-Google Wallet יש כפתור מוכר שאתם יכולים להשתמש בו כדי להפעיל את התהליך "הוספה ל-Google Wallet" באפליקציה שלכם. נכסים וקטוריים של הלחצן זמינים בהנחיות בנושא לחצנים.

אפשר לייבא נכסים וקטוריים ב-Android Studio בקטע File > New > Vector Asset. בוחרים באפשרות "קובץ מקומי" באשף, מוסיפים שם (למשל: add_to_google_wallet_button.xml) ומאתרים את הקובץ בכונן המקומי כדי לייבא אותו.

  • הכפתור "הוספה ל-Google Wallet"
  • כפתור "הוספה ל-Google Wallet" בגרסה מקוצרת

עכשיו אפשר להשתמש ב-drawable המיובא כדי להוסיף את הכפתור לממשק המשתמש:

    <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 של 48dp וצריך להיות ברוחב של 200dp לפחות.

4. הוספת כרטיס ל-Google Wallet של משתמש

אפשר להוסיף את OfferObject על ידי העברת JWT לא חתום ל-method‏ savePasses. אתם יכולים להתחיל את פעולת ההוספה בלחיצה על הכפתור של 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
}

טיפול בתוצאות

ה-method‏ savePasses מפעילה את תהליך השמירה ומפעילה את ה-method‏ 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.