이 가이드에는 개발자가 Engage SDK를 사용하여 앱 구독 및 사용 권한 데이터를 Google TV와 공유하는 방법에 관한 안내가 포함되어 있습니다. 사용자는 시청 권한이 있는 콘텐츠를 찾고 TV, 모바일, 태블릿의 Google TV 환경에서 직접 Google TV가 사용자에게 매우 관련성 높은 콘텐츠 추천을 제공하도록 할 수 있습니다.
기본 요건
기기 사용 권한 API를 사용하려면 먼저 미디어 작업 피드를 온보딩해야 합니다. 아직 완료하지 않았다면 미디어 작업 피드 온보딩 프로세스를 완료하세요.
사전 작업
시작하기 전에 다음 단계를 완료하여 앱이 이 통합을 위해 API 수준 19 이상을 타겟팅하는지 확인합니다.
다음과 같이
com.google.android.engage
라이브러리를 앱에 추가합니다.통합에 사용할 수 있는 SDK는 모바일 앱용 SDK와 TV 앱용 SDK로 각각 다릅니다.
모바일용
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 구독
앱에서 일반적인 등급을 넘어 확장된 콘텐츠 또는 기능이 포함된 다층 프리미엄 정기 결제 패키지를 제공하는 경우 정기 결제에 하나 이상의 사용 권한을 추가하여 이를 나타냅니다.
이 사용 권한에는 다음 필드가 있습니다.
- 식별자: 이 사용 권한에 필요한 식별자 문자열입니다. 이 ID는 Google TV에 게시된 미디어 제공업체 피드에 제공된 사용 권한 식별자 (ID 필드가 아님) 중 하나와 일치해야 합니다.
- 이름: 보조 정보이며 사용 권한 일치에 사용됩니다. 사람이 읽을 수 있는 사용 권한 이름을 제공하는 것은 선택사항이지만 개발자와 지원팀 모두의 사용자 사용 권한 이해를 향상시킵니다. 예: Sling Orange
- Expiration TimeMillis: 이 사용 권한의 만료 시간이 정기 결제 만료 시간과 다른 경우 만료 시간을 밀리초 단위로 지정할 수 있습니다. 기본적으로 사용 권한은 구독이 만료되면 만료됩니다.
다음 샘플 미디어 제공업체 피드 스니펫을 예로 들 수 있습니다.
"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가 호출되면 데이터가 인증 앱에 표시됩니다.
- Engage Service Flag가 앱의 Android 매니페스트 파일에서 프로덕션으로 설정되지 않았는지 확인합니다.
- 참여 인증 앱을 설치하고 엽니다.
- 인증 앱에서
isServiceAvailable
값이false
인 경우 인증 앱 내에서Toggle
버튼을 클릭하여true
로 설정합니다. - 앱의 패키지 이름을 입력합니다. 그러면 게시된 데이터가 자동으로 표시됩니다.
앱으로 이동하여 다음 작업을 각각 실행합니다.
- 로그인합니다.
- 프로필 간에 전환합니다 (지원되는 경우).
- 새 정기 결제를 구매합니다.
- 기존 정기 결제를 업그레이드합니다.
- 정기 결제를 만료합니다.
통합 확인
통합을 테스트하려면 인증 앱을 사용하세요.
인증 앱은 개발자가 통합이 작동하는지 확인하는 데 사용할 수 있는 Android 애플리케이션입니다. 앱에는 개발자가 데이터를 확인하고 인텐트를 브로드캐스트하는 데 도움이 되는 기능이 포함되어 있습니다. 출시 전에 데이터 정확성과 적절한 기능을 확인하는 데 도움이 됩니다.
- 각 이벤트에 대해 앱이
publishSubscription
API를 호출했는지 확인합니다. 인증 앱에서 게시된 데이터를 확인합니다. 인증 앱에서 모든 항목이 녹색인지 확인 모든 항목의 정보가 올바르면 모든 항목에 '좋음' 녹색 체크표시가 표시됩니다.
그림 1. 구독 완료 인증 앱에서도 문제가 강조 표시됩니다.
그림 2.구독 실패 번들 정기 결제의 문제를 보려면 TV 리모컨을 사용하여 특정 번들 정기 결제에 초점을 맞추고 클릭하여 문제를 확인합니다. 번들 구독 카드를 찾으려면 먼저 행에 초점을 맞추고 오른쪽으로 이동해야 할 수 있습니다. 문제는 그림 3과 같이 빨간색으로 강조 표시됩니다. 또한 리모컨을 사용하여 아래로 이동하여 번들 구독 내 사용 권한의 문제를 확인합니다.
그림 3.구독 오류 사용 권한에서 문제를 보려면 TV 리모컨을 사용하여 특정 사용 권한에 초점을 맞추고 클릭하여 문제를 확인합니다. 문제가 빨간색으로 강조 표시됩니다.
그림 4.구독 오류 세부정보