이 가이드에는 개발자가 Engage SDK를 사용하여 앱 정기 결제 및 권한 데이터를 Google TV와 공유하는 방법에 관한 안내가 포함되어 있습니다. 사용자는 자격이 있는 콘텐츠를 찾고 Google TV가 TV, 모바일, 태블릿의 Google TV 환경 내에서 사용자에게 매우 관련성 높은 콘텐츠 추천을 제공하도록 설정할 수 있습니다.
기본 요건
기기 권한 API를 사용하려면 미디어 작업 피드를 온보딩해야 합니다. 아직 완료하지 않았다면 미디어 작업 피드 온보딩 프로세스를 완료합니다.
사전 작업
시작하기 전에 다음 단계를 완료하세요. 이 통합을 위해 앱이 API 수준 19 이상을 타겟팅하는지 확인하세요.
다음과 같이
com.google.android.engage
라이브러리를 앱에 추가합니다.통합에 사용할 SDK는 모바일 앱용과 TV 앱용으로 구분됩니다.
모바일
dependencies { implementation 'com.google.android.engage:engage-core:1.5.5 }
TV의 경우
dependencies { implementation 'com.google.android.engage:engage-tv:1.0.2 }
AndroidManifest.xml
파일에서 Engage 서비스 환경을 프로덕션으로 설정합니다.모바일 APK
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
TV APK
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
APK를 Google에 전송하기 전에 AndroidManifest.xml 파일에서 참여 서비스 환경을 프로덕션으로 설정합니다. 최적의 성능과 향후 호환성을 위해 앱이 포그라운드에 있고 사용자가 앱 실행, 로그인 후 또는 활성 사용 중과 같이 앱과 적극적으로 상호작용할 때만 데이터를 게시하세요. 백그라운드 프로세스에서 게시하는 것은 권장되지 않습니다.
다음 이벤트에 대한 정기 결제 정보를 게시합니다.
- 사용자가 앱에 로그인합니다.
- 사용자가 프로필 간에 전환합니다 (프로필이 지원되는 경우).
- 사용자가 새 정기 결제를 구매합니다.
- 사용자가 기존 정기 결제를 업그레이드합니다.
- 사용자 구독이 만료됩니다.
통합
이 섹션에서는 다양한 구독 유형을 관리하기 위해 AccountProfile
및 SubscriptionEntity
를 구현하는 데 필요한 코드 예시와 안내를 제공합니다.
사용자 계정 및 프로필
Google TV에서 맞춤 기능을 허용하려면 계정 정보를 제공하세요. AccountProfile
를 사용하여 다음을 제공합니다.
- 계정 ID: 사용자의 계정을 나타내는 고유 식별자입니다. 실제 계정 ID 또는 적절하게 난독화된 버전일 수 있습니다.
// Set the account ID to which the subscription applies.
// Don't set the profile ID because subscription applies to account level.
val accountProfile = AccountProfile.Builder()
.setAccountId("user_account_id")
.setProfileId("user_profile id")
.build();
일반 등급 구독
미디어 제공업체 서비스의 기본 구독이 있는 사용자(예: 모든 유료 콘텐츠에 대한 액세스 권한을 부여하는 구독 등급이 하나인 서비스)의 경우 다음 필수 세부정보를 제공하세요.
구독 유형: 사용자가 보유한 특정 구독 요금제를 명확하게 표시합니다.
SUBSCRIPTION_TYPE_ACTIVE
: 사용자에게 활성 상태의 유료 구독이 있습니다.SUBSCRIPTION_TYPE_ACTIVE_TRIAL
: 사용자에게 무료 체험 구독이 있습니다.SUBSCRIPTION_TYPE_INACTIVE
: 사용자에게 계정이 있지만 활성 구독 또는 무료 체험이 없습니다.
만료 시간: 선택사항인 시간(밀리초)입니다. 정기 결제가 만료되도록 설정된 시점을 지정합니다.
공급자 패키지 이름: 정기 결제를 처리하는 앱의 패키지 이름을 지정합니다.
샘플 미디어 제공업체 피드의 예
"actionAccessibilityRequirement": [
{
"@type": "ActionAccessSpecification",
"category": "subscription",
"availabilityStarts": "2022-06-01T07:00:00Z",
"availabilityEnds": "2026-05-31T07:00:00Z",
"requiresSubscription": {
"@type": "MediaSubscription",
// Don't match this string,
// ID is only used to for reconciliation purpose
"@id": "https://www.example.com/971bfc78-d13a-4419",
// Don't match this, as name is only used for displaying purpose
"name": "Basic common name",
"commonTier": true
}
다음 예시에서는 사용자의 SubscriptionEntity
를 만듭니다.
val subscription = SubscriptionEntity
.Builder()
setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds since epoch
.setExpirationTimeMillis(1767052800000)
.build();
Premium 구독
앱에서 일반 등급을 넘어 확장된 콘텐츠나 기능이 포함된 다단계 프리미엄 정기 결제 패키지를 제공하는 경우 정기 결제에 하나 이상의 권한을 추가하여 이를 나타냅니다.
이 권한에는 다음 필드가 있습니다.
- 식별자: 이 혜택에 필요한 식별자 문자열입니다. 이는 Google TV에 게시된 미디어 제공업체의 피드에 제공된 사용 권한 식별자 중 하나와 일치해야 합니다 (ID 필드가 아님).
- 이름: 보조 정보이며 권한 일치에 사용됩니다. 선택사항이지만 사람이 읽을 수 있는 권한 이름을 제공하면 개발자와 지원팀 모두 사용자 권한을 더 잘 이해할 수 있습니다. 예: Sling Orange
- 만료 시간(밀리초): 정기 결제 만료 시간과 다른 경우 이 혜택의 만료 시간을 밀리초 단위로 선택적으로 지정합니다. 기본적으로 구독이 만료되면 혜택도 만료됩니다.
다음 샘플 미디어 제공업체 피드 스니펫의 경우
"actionAccessibilityRequirement": [
{
"@type": "ActionAccessSpecification",
"category": "subscription",
"availabilityStarts": "2022-06-01T07:00:00Z",
"availabilityEnds": "2026-05-31T07:00:00Z",
"requiresSubscription": {
"@type": "MediaSubscription",
// Don't match this string,
// ID is only used to for reconciliation purpose
"@id": "https://www.example.com/971bfc78-d13a-4419",
// Don't match this, as name is only used for displaying purpose
"name": "Example entitlement name",
"commonTier": false,
// match this identifier in your API. This is the crucial
// entitlement identifier used for recommendation purpose.
"identifier": "example.com:entitlementString1"
}
다음 예시에서는 구독한 사용자의 SubscriptionEntity
를 만듭니다.
// Subscription with entitlements.
// The entitlement expires at the same time as its subscription.
val subscription = SubscriptionEntity
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds
.setExpirationTimeMillis(1767052800000)
.addEntitlement(
SubscriptionEntitlement.Builder()
// matches with the identifier in media provider feed
.setEntitlementId("example.com:entitlementString1")
.setDisplayName("entitlement name1")
.build()
)
.build();
// Subscription with entitlements
// The entitement has different expiration time from its subscription
val subscription = SubscriptionEntity
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds
.setExpirationTimeMillis(1767052800000)
.addEntitlement(
SubscriptionEntitlement.Builder()
.setEntitlementId("example.com:entitlementString1")
.setDisplayName("entitlement name1")
// You may set the expiration time for entitlement
// December 15, 2025 10:00:00 AM in milliseconds
.setExpirationTimeMillis(1765792800000)
.build())
.build();
연결된 서비스 패키지 구독
정기 결제는 일반적으로 시작 앱의 미디어 제공업체에 속하지만, 정기 결제 내에서 연결된 서비스 패키지 이름을 지정하여 연결된 서비스 패키지에 정기 결제를 귀속시킬 수 있습니다.
다음 코드 샘플은 사용자 구독을 만드는 방법을 보여줍니다.
// Subscription for linked service package
val subscription = SubscriptionEntity
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("com.google.android.example")
// Optional
// December 30, 2025 12:00:00AM in milliseconds since epoch
.setExpirationTimeMillis(1767052800000)
.build();
또한 사용자가 자회사 서비스의 다른 구독을 보유하고 있는 경우 다른 구독을 추가하고 연결된 서비스 패키지 이름을 적절하게 설정합니다.
// Subscription for linked service package
val linkedSubscription = Subscription
.Builder()
.setSubscriptionType(
SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
)
.setProviderPackageName("linked service package name")
// Optional
// December 30, 2025 12:00:00AM in milliseconds since epoch
.setExpirationTimeMillis(1767052800000)
.addBundledSubscription(
BundledSubscription.Builder()
.setBundledSubscriptionProviderPackageName(
"bundled-subscription-package-name"
)
.setSubscriptionType(SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE)
.setExpirationTimeMillis(111)
.addEntitlement(
SubscriptionEntitlement.Builder()
.setExpirationTimeMillis(111)
.setDisplayName("Silver subscription")
.setEntitlementId("subscription.tier.platinum")
.build()
)
.build()
)
.build();
원하는 경우 연결된 서비스 구독에 권한을 추가할 수도 있습니다.
정기 결제 세트 제공
앱이 포그라운드에 있는 동안 콘텐츠 게시 작업을 실행합니다.
AppEngagePublishClient
클래스의 publishSubscriptionCluster()
메서드를 사용하여 SubscriptionCluster
객체를 게시합니다.
isServiceAvailable
를 사용하여 서비스를 통합에 사용할 수 있는지 확인합니다.
client.publishSubscription(
PublishSubscriptionRequest.Builder()
.setAccountProfile(accountProfile)
.setSubscription(subscription)
.build();
)
setSubscription()
을 사용하여 사용자에게 서비스 정기 결제가 하나만 있어야 하는지 확인합니다.
연결된 정기 결제 목록을 허용하는 addLinkedSubscription()
또는 addLinkedSubscriptions()
를 사용하여 사용자가 연결된 정기 결제를 0개 이상 보유하도록 지원합니다.
서비스가 요청을 수신하면 새 항목이 생성되고 60일 후에 이전 항목이 자동으로 삭제됩니다. 시스템은 항상 최신 항목을 사용합니다. 오류가 발생하면 전체 요청이 거부되고 기존 상태가 유지됩니다.
구독을 최신 상태로 유지
- 변경사항이 발생하면 즉시 업데이트를 제공하려면 활성화, 비활성화, 업그레이드, 다운그레이드와 같이 사용자의 정기 결제 상태가 변경될 때마다
publishSubscriptionCluster()
를 호출하세요. 정확성을 지속적으로 검증하려면 한 달에 한 번 이상
publishSubscriptionCluster()
를 호출하세요.동영상 탐색 데이터를 삭제하려면 표준 60일 보관 기간 전에 Google TV 서버에서 사용자의 데이터를 수동으로 삭제하고
client.deleteClusters()
메서드를 사용하세요. 이렇게 하면 지정된DeleteReason
에 따라 계정 프로필 또는 전체 계정의 기존 동영상 탐색 데이터가 모두 삭제됩니다.사용자 정기 결제를 삭제하는 코드 스니펫
// If the user logs out from your media app, you must make the following call // to remove subscription and other video discovery data from the current // google TV device. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile( AccountProfile .Builder() .setAccountId() .setProfileId() .build() ) .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT) .build() ) ``` Following code snippet demonstrates removal of user subscription when user revokes the consent. ```Kotlin // If the user revokes the consent to share across device, make the call // to remove subscription and other video discovery data from all google // TV devices. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile( AccountProfile .Builder() .setAccountId() .setProfileId() .build() ) .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT) .build() ) ``` Following code demonstrates how to remove subscription data on user profile deletion. ```Kotlin // If the user delete a specific profile, you must make the following call // to remove subscription data and other video discovery data. client.deleteClusters( new DeleteClustersRequest.Builder() .setAccountProfile( AccountProfile .Builder() .setAccountId() .setProfileId() .build() ) .setReason(DeleteReason.DELETE_REASON_ACCOUNT_PROFILE_DELETION) .build() )
테스트
이 섹션에서는 정기 결제 구현을 테스트하는 방법을 단계별로 안내합니다. 출시 전에 데이터 정확성과 적절한 기능을 확인하세요.
통합 게시 체크리스트
앱이 포그라운드에 있고 사용자가 앱과 적극적으로 상호작용할 때 게시가 이루어져야 합니다.
다음과 같은 경우 게시
- 사용자가 처음으로 로그인합니다.
- 사용자가 프로필을 변경합니다 (프로필이 지원되는 경우).
- 사용자가 새 정기 결제를 구매합니다.
- 사용자가 구독을 업그레이드합니다.
- 사용자 구독이 만료됩니다.
앱이 게시 이벤트에서 Logcat의
isServiceAvailable()
및publishClusters()
API를 올바르게 호출하는지 확인합니다.데이터가 인증 앱에 표시되는지 확인합니다. 인증 앱에는 구독이 별도의 행으로 표시되어야 합니다. 게시 API가 호출되면 데이터가 인증 앱에 표시됩니다.
- 앱의 Android 매니페스트 파일에서 Engage Service Flag가 프로덕션으로 설정되어 있지 않은지 확인합니다.
- Engage Verification 앱을 설치하고 엽니다.
- 인증 앱에서
isServiceAvailable
값이false
이면 인증 앱 내에서Toggle
버튼을 클릭하여true
로 설정합니다. - 앱의 패키지 이름을 입력합니다. 게시된 데이터가 자동으로 표시됩니다.
앱으로 이동하여 다음 각 작업을 수행합니다.
- 로그인합니다.
- 프로필 간 전환 (지원되는 경우)
- 새 정기 결제를 구매합니다.
- 기존 정기 결제를 업그레이드합니다.
- 정기 결제를 만료합니다.
통합 확인
통합을 테스트하려면 인증 앱을 사용하세요.
인증 앱은 개발자가 통합이 작동하는지 확인하는 데 사용할 수 있는 Android 애플리케이션입니다. 앱에는 개발자가 데이터를 확인하고 인텐트를 브로드캐스트하는 데 도움이 되는 기능이 포함되어 있습니다. 출시 전에 데이터 정확성과 적절한 기능을 확인하는 데 도움이 됩니다.
- 각 이벤트에 대해 앱이
publishSubscription
API를 호출했는지 확인합니다. 인증 앱에서 게시된 데이터를 확인합니다. 인증 앱에서 모든 항목이 녹색인지 확인 엔티티의 모든 정보가 올바르면 모든 엔티티에 'All Good'(모두 정상) 녹색 체크표시가 표시됩니다.
그림 1. 구독 성공 확인 앱에서도 문제가 강조 표시됨
그림 2.구독 실패 번들로 제공되는 구독의 문제를 확인하려면 TV 리모컨을 사용하여 해당 번들 구독에 포커스를 맞추고 클릭하여 문제를 확인하세요. 먼저 행에 초점을 맞추고 오른쪽으로 이동하여 번들 구독 카드를 찾아야 할 수 있습니다. 문제는 그림 3과 같이 빨간색으로 강조 표시됩니다. 또한 리모컨을 사용하여 아래로 이동하여 번들 구독 내의 혜택 문제를 확인합니다.
그림 3.구독 오류 권한의 문제를 확인하려면 TV 리모컨을 사용하여 해당 권한에 포커스를 맞추고 클릭하여 문제를 확인합니다. 문제는 빨간색으로 강조 표시됩니다.
그림 4.구독 오류 세부정보
다운로드
다운로드하기 전에 다음 이용약관에 동의해야 합니다.