Android SDK 시작하기

Android SDK를 시작하기 전에 기본 요건을 완료해야 합니다.

Android SDK를 사용하면 Google 월렛에 패스를 추가할 수 있습니다. 앱에 Google 월렛 버튼을 추가하면 사용자가 Google 월렛에 패스를 추가하여 간편하고 즐거운 경험을 할 수 있습니다.

단계에 따라 Android 애플리케이션에 Google 월렛 버튼을 추가합니다.

1. 패스 객체 만들기

참고: 패스 객체를 만들려면 패스 클래스가 필요합니다. 아직 패스 클래스를 만들지 않았다면 패스 클래스 만들기 방법에 대한 안내를 따르세요. 다음 필수 속성을 포함하여 상응하는 FlightObject를 정의합니다.

  • classId: 기본 요건에서 만든 패스 클래스의 ID입니다.
  • id: 객체의 고유 ID입니다.

  • passenterName: 탑승권에 표시되는 승객 이름입니다.
  • reservationInfo: 항공편 예약에 관한 정보입니다.
  • state: 이 필드는 객체가 표시되는 방식을 결정하는 데 사용됩니다. 예를 들어 비활성 객체는 '만료된 패스' 섹션으로 이동합니다.

이러한 속성이 탑승권에 표시되는 방식에 관한 자세한 내용은 레이아웃 템플릿을 참고하세요.

다음은 샘플 탑승권의 정의입니다.

JSON

      
{
  "id": "ISSUER_ID.OBJECT_ID",
  "classId": "ISSUER_ID.CLASS_ID",
  "passengerName": "Alex McJacobs",
  "reservationInfo": {
    "confirmationCode": "123456",
    "eticketNumber": "0000000000000",
    "frequentFlyerInfo": {
      "frequentFlyerProgramName": {
        "defaultValue": {
          "language": "en",
          "value": "Flying rewards program"
        }
      },
      "frequentFlyerNumber": "123456789"
    }
  },
  "state": "ACTIVE"
}
      
    

2. 객체로 서명되지 않은 JWT 만들기

FlightObject가 생성되면 다음 스니펫과 같이 payload.FlightObjects 속성이 있는 서명되지 않은 JWT로 래핑합니다.

JSON

{
  "iss": "OWNER_EMAIL_ADDRESS",
  "aud": "google",
  "typ": "savetowallet",
  "iat": "UNIX_TIME",
  "origins": [],
  "payload": {
      "flightObjects": [ NEW_OBJECT ]
  }
}

3. UI에 Google 월렛 버튼 포함

Google 월렛은 애플리케이션에서 'Google 월렛에 추가' 흐름을 트리거하는 데 사용할 수 있는 익숙한 버튼을 제공합니다. 버튼의 벡터 애셋은 버튼 가이드라인에서 확인할 수 있습니다.

Android 스튜디오의 File > New > Vector Asset 아래에서 벡터 애셋을 가져올 수 있습니다. 마법사에서 'Local file'을 선택하고 이름 (예: add_to_google_wallet_button.xml) 로컬 드라이브에서 파일을 찾아 가져올 파일을 찾습니다.

이제 가져온 드로어블을 사용하여 사용자 인터페이스에 버튼을 추가할 수 있습니다.

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

이제 클라이언트를 사용하여 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의 사용 가능 여부를 확인해야 할 때 애플리케이션에서 위에 정의된 메서드를 호출합니다.

5. Google 월렛에 객체 추가

2단계의 서명되지 않은 JWT를 savePasses 메서드에 전달하여 FlightObject를 추가할 수 있습니다. 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
      }
    }
  }
}

패스가 성공적으로 추가되면 resultCodeActivity.RESULT_OK의 값이 포함됩니다.

[테스트 전용] 통과

아직 데모 모드일 때는 생성하는 모든 패스의 패스 제목에 '[테스트 전용]'이라는 추가 텍스트가 표시됩니다. 이는 데모 패스와 라이브 패스를 구분하기 위함입니다. Google팀의 프로덕션 승인을 받으면 사용자가 연결된 기기에서 월렛 앱을 다시 열 때 이 데모 모드 패스에 더 이상 추가 텍스트가 표시되지 않습니다.

다음 단계