Hướng dẫn này cung cấp cho nhà phát triển thông tin về cách chia sẻ dữ liệu về gói thuê bao và quyền của ứng dụng với Google TV bằng Engage SDK. Người dùng có thể tìm thấy nội dung mà họ có quyền truy cập và cho phép Google TV cung cấp các đề xuất nội dung có mức độ liên quan cao cho người dùng, ngay trong trải nghiệm Google TV trên TV, thiết bị di động và máy tính bảng.
Điều kiện tiên quyết
Bạn phải tham gia nguồn cấp dữ liệu hành động với nội dung nghe nhìn thì mới có thể sử dụng API quyền của thiết bị. Nếu bạn chưa hoàn tất, hãy hoàn tất quy trình tham gia nguồn cấp dữ liệu hành động đối với nội dung nghe nhìn.
Chuẩn bị trước
Trước khi bắt đầu, hãy hoàn tất các bước sau: Xác minh rằng ứng dụng của bạn nhắm đến API cấp 19 trở lên cho quá trình tích hợp này
Thêm thư viện
com.google.android.engage
vào ứng dụng của bạn:Có các SDK riêng biệt để sử dụng trong quá trình tích hợp: một cho ứng dụng di động và một cho ứng dụng truyền hình.
Dành cho thiết bị di động
dependencies { implementation 'com.google.android.engage:engage-core:1.5.5 }
cho TV
dependencies { implementation 'com.google.android.engage:engage-tv:1.0.2 }
Đặt môi trường dịch vụ Engage thành môi trường phát hành chính thức trong tệp
AndroidManifest.xml
.Đối với tệp apk di động
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
Tệp APK cho TV
<meta-data android:name="com.google.android.engage.service.ENV" android:value="PRODUCTION"> </meta-data>
Trước khi gửi APK cho Google, hãy đặt môi trường dịch vụ tương tác thành môi trường sản xuất trong tệp AndroidManifest.xml. Để đạt hiệu suất tối ưu và khả năng tương thích trong tương lai, bạn chỉ nên xuất bản dữ liệu khi ứng dụng ở nền trước và người dùng đang tích cực tương tác với ứng dụng, chẳng hạn như khi khởi chạy ứng dụng, sau khi đăng nhập hoặc trong quá trình sử dụng. Không nên xuất bản từ các quy trình nền.
Xuất bản thông tin về lượt đăng ký đối với các sự kiện sau:
- Người dùng đăng nhập vào ứng dụng của bạn.
- Người dùng chuyển đổi giữa các hồ sơ (nếu được hỗ trợ).
- Người dùng mua một gói thuê bao mới.
- Người dùng nâng cấp một gói thuê bao hiện có.
- Gói thuê bao của người dùng hết hạn.
Tích hợp
Phần này cung cấp các đoạn mã ví dụ và hướng dẫn cần thiết để triển khai AccountProfile
và SubscriptionEntity
nhằm quản lý nhiều loại gói thuê bao.
Tài khoản và hồ sơ người dùng
Để cho phép các tính năng cá nhân hoá trên Google TV, hãy cung cấp thông tin tài khoản. Sử dụng AccountProfile
để cung cấp:
- Mã tài khoản: Giá trị nhận dạng riêng biệt đại diện cho tài khoản của người dùng. Đây có thể là mã tài khoản thực tế hoặc một phiên bản được làm rối một cách thích hợp.
// 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();
Gói thuê bao chung
Đối với người dùng có gói thuê bao cơ bản cho các dịch vụ của nhà cung cấp nội dung nghe nhìn, chẳng hạn như một dịch vụ có một cấp thuê bao cấp quyền truy cập vào tất cả nội dung có tính phí, hãy cung cấp những thông tin thiết yếu sau:
Loại gói thuê bao: Nêu rõ gói thuê bao cụ thể mà người dùng đã mua.
SUBSCRIPTION_TYPE_ACTIVE
: Người dùng đang có một gói thuê bao có tính phí còn hiệu lực.SUBSCRIPTION_TYPE_ACTIVE_TRIAL
: Người dùng có gói thuê bao dùng thử.SUBSCRIPTION_TYPE_INACTIVE
: Người dùng có tài khoản nhưng không có gói thuê bao hoặc gói dùng thử đang hoạt động.
Thời gian hết hạn: Thời gian không bắt buộc tính bằng mili giây. Nêu rõ thời điểm gói thuê bao hết hạn.
Tên gói của nhà cung cấp: Chỉ định tên gói của ứng dụng xử lý gói thuê bao.
Ví dụ về nguồn cấp dữ liệu mẫu của nhà cung cấp nội dung nghe nhìn.
"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
}
Ví dụ sau đây tạo một SubscriptionEntity
cho người dùng:
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();
Gói thuê bao Premium
Nếu ứng dụng cung cấp các gói thuê bao cao cấp nhiều cấp, bao gồm nội dung hoặc tính năng mở rộng ngoài cấp thông thường, hãy thể hiện điều này bằng cách thêm một hoặc nhiều quyền vào gói thuê bao.
Quyền này có các trường sau:
- Giá trị nhận dạng: Chuỗi giá trị nhận dạng bắt buộc cho quyền này. Giá trị này phải khớp với một trong các giá trị nhận dạng quyền (xin lưu ý rằng đây không phải là trường mã nhận dạng) có trong nguồn cấp dữ liệu của nhà cung cấp nội dung nghe nhìn được xuất bản trên Google TV.
- Tên: Đây là thông tin phụ và được dùng để so khớp quyền. Mặc dù không bắt buộc, nhưng việc cung cấp tên quyền dễ đọc sẽ giúp cả nhà phát triển và nhóm hỗ trợ hiểu rõ hơn về quyền của người dùng. Ví dụ: Sling Orange.
- Expiration TimeMillis: Bạn có thể chỉ định thời gian hết hạn (theo mili giây) cho quyền này (nếu khác với thời gian hết hạn của gói thuê bao). Theo mặc định, quyền này sẽ hết hạn khi gói thuê bao hết hạn.
Đối với đoạn mã nguồn cấp dữ liệu mẫu sau đây của nhà cung cấp nội dung nghe nhìn:
"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"
}
Ví dụ sau đây sẽ tạo một SubscriptionEntity
cho người dùng đã đăng ký:
// 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();
Gói thuê bao cho dịch vụ được liên kết
Mặc dù gói thuê bao thường thuộc về nhà cung cấp nội dung đa phương tiện của ứng dụng gốc, nhưng bạn có thể chỉ định tên gói dịch vụ được liên kết trong gói thuê bao để phân bổ gói thuê bao cho một gói dịch vụ được liên kết.
Mẫu mã sau đây minh hoạ cách tạo gói thuê bao của người dùng.
// 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();
Ngoài ra, nếu người dùng có một gói thuê bao khác cho dịch vụ phụ, hãy thêm một gói thuê bao khác và đặt tên gói dịch vụ được liên kết cho phù hợp.
// 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();
Bạn cũng có thể thêm quyền sử dụng cho gói thuê bao của dịch vụ được liên kết (không bắt buộc).
Cung cấp bộ thuê bao
Chạy tác vụ xuất bản nội dung trong khi ứng dụng đang chạy ở nền trước.
Sử dụng phương thức publishSubscriptionCluster()
của lớp AppEngagePublishClient
để xuất bản một đối tượng SubscriptionCluster
.
Sử dụng isServiceAvailable
để kiểm tra xem dịch vụ có thể tích hợp hay không.
client.publishSubscription(
PublishSubscriptionRequest.Builder()
.setAccountProfile(accountProfile)
.setSubscription(subscription)
.build();
)
Sử dụng setSubscription()
để xác minh rằng người dùng chỉ có một gói thuê bao cho dịch vụ.
Sử dụng addLinkedSubscription()
hoặc addLinkedSubscriptions()
(chấp nhận danh sách các gói thuê bao được liên kết) để cho phép người dùng có từ 0 gói thuê bao được liên kết trở lên.
Khi dịch vụ nhận được yêu cầu, một mục mới sẽ được tạo và mục cũ sẽ tự động bị xoá sau 60 ngày. Hệ thống luôn sử dụng mục nhập mới nhất. Trong trường hợp xảy ra lỗi, toàn bộ yêu cầu sẽ bị từ chối và trạng thái hiện tại sẽ được duy trì.
Luôn cập nhật gói thuê bao
- Để cung cấp thông tin cập nhật ngay lập tức khi có thay đổi, hãy gọi
publishSubscriptionCluster()
bất cứ khi nào trạng thái gói thuê bao của người dùng thay đổi, chẳng hạn như kích hoạt, huỷ kích hoạt, nâng cấp, hạ cấp. Để xác thực thường xuyên nhằm đảm bảo độ chính xác liên tục, hãy gọi
publishSubscriptionCluster()
ít nhất một lần mỗi tháng.Để xoá dữ liệu Khám phá video, hãy xoá dữ liệu của người dùng theo cách thủ công khỏi máy chủ Google TV trước thời hạn lưu giữ tiêu chuẩn là 60 ngày bằng phương thức
client.deleteClusters()
. Thao tác này sẽ xoá tất cả dữ liệu hiện có về video khám phá cho hồ sơ tài khoản hoặc cho toàn bộ tài khoản, tuỳ thuộc vàoDeleteReason
đã cho.Đoạn mã để xoá gói thuê bao của người dùng
// 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() )
Thử nghiệm
Phần này cung cấp hướng dẫn từng bước để kiểm thử việc triển khai gói thuê bao. Xác minh độ chính xác của dữ liệu và chức năng phù hợp trước khi ra mắt.
Xuất bản danh sách kiểm tra tích hợp
Bạn nên xuất bản khi ứng dụng ở nền trước và người dùng đang tích cực tương tác với ứng dụng.
Xuất bản khi:
- Người dùng đăng nhập lần đầu tiên.
- Người dùng thay đổi hồ sơ (nếu được hỗ trợ).
- Người dùng mua gói thuê bao mới.
- Người dùng nâng cấp gói thuê bao.
- Gói thuê bao của người dùng hết hạn.
Kiểm tra xem ứng dụng có đang gọi đúng API
isServiceAvailable()
vàpublishClusters()
trong logcat hay không, khi xuất bản các sự kiện.Xác minh rằng dữ liệu hiển thị trong ứng dụng xác minh. Ứng dụng xác minh sẽ hiển thị gói thuê bao dưới dạng một hàng riêng biệt. Khi API xuất bản được gọi, dữ liệu sẽ xuất hiện trong ứng dụng xác minh.
- Xác minh rằng Cờ dịch vụ tương tác KHÔNG được đặt thành phiên bản phát hành trong tệp kê khai Android của ứng dụng.
- Cài đặt và mở ứng dụng Engage Verification.
- Nếu giá trị của
isServiceAvailable
làfalse
trong ứng dụng xác minh, hãy nhấp vào nútToggle
trong ứng dụng xác minh để đặt giá trị này thànhtrue
. - Nhập tên gói của ứng dụng. Hệ thống sẽ tự động cho thấy dữ liệu đã xuất bản.
Chuyển đến ứng dụng rồi thực hiện từng thao tác sau:
- Đăng nhập.
- chuyển đổi giữa các hồ sơ (nếu được hỗ trợ).
- Mua gói thuê bao mới.
- Nâng cấp gói thuê bao hiện có.
- Hết hạn gói thuê bao.
Xác minh quá trình tích hợp
Để kiểm thử quá trình tích hợp, hãy dùng ứng dụng xác minh.
Ứng dụng xác minh là một ứng dụng Android mà nhà phát triển có thể dùng để xác minh rằng SDK tích hợp đang hoạt động. Ứng dụng này có những chức năng giúp nhà phát triển xác minh dữ liệu và ý định truyền tin. Điều này giúp xác minh độ chính xác của dữ liệu và chức năng phù hợp trước khi ra mắt.
- Đối với mỗi sự kiện, hãy kiểm tra xem ứng dụng đã gọi API
publishSubscription
hay chưa. Xác minh dữ liệu đã xuất bản trong ứng dụng xác minh. Xác minh rằng mọi thứ đều có màu xanh lục trong ứng dụng xác minh Nếu tất cả thông tin của thực thể đều chính xác, thì hệ thống sẽ hiển thị dấu kiểm màu xanh lục "Tất cả đều ổn" trong tất cả các thực thể.
Hình 1. Đăng ký thành công Các vấn đề cũng được làm nổi bật trong ứng dụng xác minh
Hình 2.Đăng ký không thành công Để xem các vấn đề trong gói thuê bao kết hợp, hãy dùng điều khiển từ xa của TV để chuyển tiêu điểm đến gói thuê bao kết hợp cụ thể đó rồi nhấp để xem các vấn đề. Trước tiên, bạn có thể phải tập trung vào hàng rồi di chuyển sang phải để tìm thẻ Gói thuê bao. Các vấn đề được đánh dấu màu đỏ như trong Hình 3. Ngoài ra, hãy dùng điều khiển từ xa để di chuyển xuống dưới và xem các vấn đề về quyền trong gói thuê bao
Hình 3.Lỗi về gói thuê bao Để xem các vấn đề trong quyền, hãy dùng điều khiển từ xa của TV để tập trung vào quyền cụ thể đó rồi nhấp để xem các vấn đề. Các vấn đề được đánh dấu màu đỏ.
Hình 4.Thông tin chi tiết về lỗi gói thuê bao
Tải xuống
Trước khi tải xuống, bạn phải đồng ý với các điều khoản và điều kiện sau.