通过在用户所在之处触达他们,提高应用互动度。集成 Engage SDK,即可直接向用户在多个设备端界面(例如 收藏、娱乐空间和 Play 商店)投放个性化推荐和续播内容。集成 Engage SDK 后,平均 APK 大小会增加不到 50 KB(压缩后),且大多数应用仅需约一周的开发者时间即可完成集成。如需了解详情,请访问我们的 业务网站。
本指南包含供开发者合作伙伴遵循的说明,介绍如何将阅读内容(电子书、有声读物、漫画/日漫)投放到 Engage 内容界面。
集成详情
术语
此集成包含以下三种类别:推荐、续播和精选。
推荐类别显示来自单个开发者合作伙伴的个性化内容阅读建议。
您的推荐采用以下结构
推荐类别:一个 UI 视图,其中包含来自单个开发者合作伙伴的一组推荐。
图 1. 娱乐空间 UI 显示了来自单个合作伙伴的推荐类别。 实体:代表类别中单个项的对象。实体可以是电子书、有声读物、图书系列等。如需查看支持的实体类型列表,请参阅提供实体数据部分。
图 2. 娱乐空间 UI 显示了单个合作伙伴的推荐类别中的单个实体。
续播类别在单个 UI 分组中显示来自多个开发者合作伙伴的未完成书籍。每个开发者合作伙伴最多可在续播类别中广播 10 个实体。
图 3. 娱乐空间 UI 显示了包含来自多个合作伙伴的未完成推荐的续播类别(目前仅显示一个推荐)。 精选类别在单个 UI 分组中展示来自多个开发者合作伙伴的精选内容。精选类别将是单个类别,显示在 UI 顶部附近,优先级高于所有推荐类别。每个开发者合作伙伴最多可在精选类别中广播 10 个实体。
图 4. 娱乐空间 UI 显示了包含来自多个合作伙伴的推荐的精选类别(目前仅显示一个推荐)。
准备工作
最低 API 级别:19
将 com.google.android.engage:engage-core
库添加到您的应用中
dependencies {
// Make sure you also include that repository in your project's build.gradle file.
implementation 'com.google.android.engage:engage-core:1.5.2'
}
摘要
此设计基于绑定服务的实现。
客户端可以发布的数据受不同类别类型的以下限制
类别类型 | 类别限制 | 类别中实体数量上限 |
---|---|---|
推荐类别 | 最多 7 个 | 最多 50 个 |
续播类别 | 最多 1 个 | 最多 20 个 |
精选类别 | 最多 1 个 | 最多 20 个 |
第 1 步:提供实体数据
SDK 定义了不同的实体来表示每种项类型。阅读类别支持以下实体
EbookEntity
AudiobookEntity
BookSeriesEntity
下表概述了每种类型可用的属性和要求。
EbookEntity
EbookEntity
对象表示电子书(例如,米歇尔·奥巴马所著《成为》的电子书)。
属性 | 要求 | 备注 |
---|---|---|
名称 | 必需 | |
海报图片 | 必需 | 必须至少提供一张图片。请参阅图片规范以获取指导。 |
作者 | 必需 | 必须至少提供一个作者姓名。 |
操作链接 URI | 必需 |
指向电子书提供方应用的深层链接。 注意:您可以使用深层链接进行归因。请参阅此常见问题解答 |
发布日期 | 可选 | 如果提供,以纪元毫秒为单位。 |
描述 | 可选 | 如果提供,必须在 200 个字符以内。 |
价格 | 可选 | 自由文本 |
页数 | 可选 | 如果提供,必须是正整数。 |
流派 | 可选 | 与图书关联的流派列表。 |
系列名称 | 可选 | 电子书所属系列的名称(例如《哈利·波特》)。 |
系列单元索引 | 可选 | 电子书在系列中的索引,其中 1 是系列中的第一本电子书。例如,如果《哈利·波特与阿兹卡班囚徒》是系列中的第 3 本书,则应将其设置为 3。 |
续读图书类型 | 可选 |
TYPE_CONTINUE - 继续未完成的图书。 TYPE_NEXT - 继续系列中的新书。 TYPE_NEW - 新发布。 |
上次互动时间 | 有条件要求 |
当项位于续播类别中时必须提供。 “新”获得的电子书可以是续读类别的一部分。 以纪元毫秒为单位。 |
完成百分比进度 | 有条件要求 |
当项位于续播类别中时必须提供。 值必须大于 0 且小于 100。 |
DisplayTimeWindow - 为内容在界面上显示设置时间窗口 | ||
开始时间戳 | 可选 |
内容应在界面上显示后的纪元时间戳。 如果未设置,内容有资格在界面上显示。 以纪元毫秒为单位。 |
结束时间戳 | 可选 |
内容在界面上不再显示后的纪元时间戳。 如果未设置,内容有资格在界面上显示。 以纪元毫秒为单位。 |
AudiobookEntity
AudiobookEntity
对象表示有声读物(例如,米歇尔·奥巴马所著《成为》的有声读物)。
属性 | 要求 | 备注 |
---|---|---|
名称 | 必需 | |
海报图片 | 必需 | 必须至少提供一张图片。请参阅图片规范以获取指导。 |
作者 | 必需 | 必须至少提供一个作者姓名。 |
操作链接 URI | 必需 |
指向有声读物提供方应用的深层链接。 注意:您可以使用深层链接进行归因。请参阅此常见问题解答 |
旁白 | 可选 | 必须至少提供一个旁白姓名。 |
发布日期 | 可选 | 如果提供,以纪元毫秒为单位。 |
描述 | 可选 | 如果提供,必须在 200 个字符以内。 |
价格 | 可选 | 自由文本 |
时长 | 可选 | 如果提供,必须是正值。 |
流派 | 可选 | 与图书关联的流派列表。 |
系列名称 | 可选 | 有声读物所属系列的名称(例如《哈利·波特》)。 |
系列单元索引 | 可选 | 有声读物在系列中的索引,其中 1 是系列中的第一本有声读物。例如,如果《哈利·波特与阿兹卡班囚徒》是系列中的第 3 本书,则应将其设置为 3。 |
续读图书类型 | 可选 |
TYPE_CONTINUE - 继续未完成的图书。 TYPE_NEXT - 继续系列中的新书。 TYPE_NEW - 新发布。 |
上次互动时间 | 有条件要求 | 当项位于续播类别中时必须提供。 以纪元毫秒为单位。 |
完成百分比进度 | 有条件要求 |
当项位于续播类别中时必须提供。 “新”获得的有声读物可以是续读类别的一部分。 值必须大于 0 且小于 100。 |
DisplayTimeWindow - 为内容在界面上显示设置时间窗口 | ||
开始时间戳 | 可选 |
内容应在界面上显示后的纪元时间戳。 如果未设置,内容有资格在界面上显示。 以纪元毫秒为单位。 |
结束时间戳 | 可选 |
内容在界面上不再显示后的纪元时间戳。 如果未设置,内容有资格在界面上显示。 以纪元毫秒为单位。 |
BookSeriesEntity
BookSeriesEntity
对象表示图书系列(例如,《哈利·波特》系列,共有 7 本书)。
属性 | 要求 | 备注 |
---|---|---|
名称 | 必需 | |
海报图片 | 必需 | 必须至少提供一张图片。请参阅图片规范以获取指导。 |
作者 | 必需 | 必须至少有一个作者姓名。 |
操作链接 URI | 必需 |
指向有声读物或电子书提供方应用的深层链接。 注意:您可以使用深层链接进行归因。请参阅此常见问题解答 |
图书数量 | 必需 | 系列中的图书数量。 |
描述 | 可选 | 如果提供,必须在 200 个字符以内。 |
流派 | 可选 | 与图书关联的流派列表。 |
续读图书类型 | 可选 |
TYPE_CONTINUE - 继续未完成的图书。 TYPE_NEXT - 继续系列中的新书。 TYPE_NEW - 新发布。 |
上次互动时间 | 有条件要求 | 当项位于续播类别中时必须提供。 以纪元毫秒为单位。 |
完成百分比进度 | 有条件要求 | 当项位于续播类别中时必须提供。 “新”获得的图书系列可以是续读类别的一部分。 值必须大于 0 且小于 100。 |
DisplayTimeWindow - 为内容在界面上显示设置时间窗口 | ||
开始时间戳 | 可选 |
内容应在界面上显示后的纪元时间戳。 如果未设置,内容有资格在界面上显示。 以纪元毫秒为单位。 |
结束时间戳 | 可选 |
内容在界面上不再显示后的纪元时间戳。 如果未设置,内容有资格在界面上显示。 以纪元毫秒为单位。 |
图片规范
图片素材的必需规范如下所示
宽高比 | 要求 | 最低像素 | 推荐像素 |
---|---|---|---|
方形 (1:1) | 必需 | 300x300 | 1200x1200 |
横向 (1.91:1) | 可选 | 600x314 | 1200x628 |
纵向 (4:5) | 可选 | 480x600 | 960x1200 |
文件格式
PNG、JPG、静态 GIF、WebP
文件大小上限
5120 KB
其他建议
- 图片安全区域:将重要内容放置在图片的中央 80% 区域。
示例
AudiobookEntity audiobookEntity =
new AudiobookEntity.Builder()
.setName("Becoming")
.addPosterImage(
new Image.Builder()
.setImageUri(Uri.parse("http://www.x.com/image.png"))
.setImageHeightInPixel(960)
.setImageWidthInPixel(408)
.build())
.addAuthor("Michelle Obama")
.addNarrator("Michelle Obama")
.setActionLinkUri(Uri.parse("https://play.google/audiobooks/1"))
.setDurationMillis(16335L)
.setPublishDateEpochMillis(1633032895L)
.setDescription("An intimate, powerful, and inspiring memoir")
.setPrice("$16.95")
.addGenre("biography")
.build();
第 2 步:提供类别数据
建议在后台执行内容发布作业(例如,使用 WorkManager),并定期或基于事件(例如,用户每次打开应用或用户刚将商品添加到购物车时)安排执行。
AppEngagePublishClient
负责发布类别。客户端中提供以下 API
isServiceAvailable
publishRecommendationClusters
publishFeaturedCluster
publishContinuationCluster
publishUserAccountManagementRequest
updatePublishStatus
deleteRecommendationsClusters
deleteFeaturedCluster
deleteContinuationCluster
deleteUserManagementCluster
deleteClusters
isServiceAvailable
此 API 用于检查服务是否可用于集成以及内容是否可以在设备上显示。
Kotlin
client.isServiceAvailable.addOnCompleteListener { task -> if (task.isSuccessful) { // Handle IPC call success if(task.result) { // Service is available on the device, proceed with content // publish calls. } else { // Service is not available, no further action is needed. } } else { // The IPC call itself fails, proceed with error handling logic here, // such as retry. } }
Java
client.isServiceAvailable().addOnCompleteListener(task - > { if (task.isSuccessful()) { // Handle success if(task.getResult()) { // Service is available on the device, proceed with content publish // calls. } else { // Service is not available, no further action is needed. } } else { // The IPC call itself fails, proceed with error handling logic here, // such as retry. } });
publishRecommendationClusters
此 API 用于发布 RecommendationCluster
对象的列表。
Kotlin
client.publishRecommendationClusters( PublishRecommendationClustersRequest.Builder() .addRecommendationCluster( RecommendationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .setTitle("Reconnect with yourself") .build()) .build())
Java
client.publishRecommendationClusters( new PublishRecommendationClustersRequest.Builder() .addRecommendationCluster( new RecommendationCluster.Builder() .addEntity(entity1) .addEntity(entity2) .setTitle("Reconnect with yourself") .build()) .build());
当服务收到请求时,会在一个事务中执行以下操作
- 开发者合作伙伴现有的
RecommendationCluster
数据将被移除。 - 请求中的数据会被解析并存储在更新后的推荐类别中。
如果发生错误,整个请求将被拒绝并保留现有状态。
publishFeaturedCluster
此 API 用于发布 FeaturedCluster
对象的列表。
Kotlin
client.publishFeaturedCluster( PublishFeaturedClusterRequest.Builder() .setFeaturedCluster( FeaturedCluster.Builder() ... .build()) .build())
Java
client.publishFeaturedCluster( new PublishFeaturedClusterRequest.Builder() .setFeaturedCluster( new FeaturedCluster.Builder() ... .build()) .build());
当服务收到请求时,会在一个事务中执行以下操作
- 开发者合作伙伴现有的
FeaturedCluster
数据将被移除。 - 请求中的数据会被解析并存储在更新后的精选类别中。
如果发生错误,整个请求将被拒绝并保留现有状态。
publishContinuationCluster
此 API 用于发布 ContinuationCluster
对象。
Kotlin
client.publishContinuationCluster( PublishContinuationClusterRequest.Builder() .setContinuationCluster( ContinuationCluster.Builder() .addEntity(book_entity1) .addEntity(book_entity2) .build()) .build())
Java
client.publishContinuationCluster( PublishContinuationClusterRequest.Builder() .setContinuationCluster( ContinuationCluster.Builder() .addEntity(book_entity1) .addEntity(book_entity2) .build()) .build())
当服务收到请求时,会在一个事务中执行以下操作
- 开发者合作伙伴现有的
ContinuationCluster
数据将被移除。 - 请求中的数据会被解析并存储在更新后的续播类别中。
如果发生错误,整个请求将被拒绝并保留现有状态。
publishUserAccountManagementRequest
此 API 用于发布登录卡片。登录操作会将用户定向到应用的登录页面,以便应用可以发布内容(或提供更多个性化内容)
以下元数据是登录卡片的一部分 -
属性 | 要求 | 描述 |
---|---|---|
操作 URI | 必需 | 指向操作的深层链接(即导航到应用登录页面) |
图片 | 可选 - 如果未提供,则必须提供标题 |
卡片上显示的图片 宽高比为 16:9,分辨率为 1264x712 的图片 |
标题 | 可选 - 如果未提供,则必须提供图片 | 卡片上的标题 |
操作文本 | 可选 | CTA 上显示的文本(即登录) |
副标题 | 可选 | 卡片上的可选副标题 |
Kotlin
var SIGN_IN_CARD_ENTITY = SignInCardEntity.Builder() .addPosterImage( Image.Builder() .setImageUri(Uri.parse("http://www.x.com/image.png")) .setImageHeightInPixel(500) .setImageWidthInPixel(500) .build()) .setActionText("Sign In") .setActionUri(Uri.parse("http://xx.com/signin")) .build() client.publishUserAccountManagementRequest( PublishUserAccountManagementRequest.Builder() .setSignInCardEntity(SIGN_IN_CARD_ENTITY) .build());
Java
SignInCardEntity SIGN_IN_CARD_ENTITY = new SignInCardEntity.Builder() .addPosterImage( new Image.Builder() .setImageUri(Uri.parse("http://www.x.com/image.png")) .setImageHeightInPixel(500) .setImageWidthInPixel(500) .build()) .setActionText("Sign In") .setActionUri(Uri.parse("http://xx.com/signin")) .build(); client.publishUserAccountManagementRequest( new PublishUserAccountManagementRequest.Builder() .setSignInCardEntity(SIGN_IN_CARD_ENTITY) .build());
当服务收到请求时,会在一个事务中执行以下操作
- 开发者合作伙伴现有的
UserAccountManagementCluster
数据将被移除。 - 请求中的数据会被解析并存储在更新后的 UserAccountManagementCluster 类别中。
如果发生错误,整个请求将被拒绝并保留现有状态。
updatePublishStatus
如果由于任何内部业务原因,没有发布任何类别,我们强烈建议使用 updatePublishStatus API 更新发布状态。这很重要,因为
- 在所有场景中提供状态,即使内容已发布(STATUS == PUBLISHED),对于填充使用此显式状态来传达您的集成健康状况和其他指标的仪表板至关重要。
- 如果未发布任何内容但集成状态未损坏(STATUS == NOT_PUBLISHED),Google 可以避免在应用健康状况仪表板中触发警报。这确认内容未发布是提供方根据预期情况造成的。
- 这有助于开发者深入了解数据何时发布,何时未发布。
- Google 可能会使用状态代码来提示用户在应用中执行某些操作,以便他们可以查看应用内容或克服问题。
符合条件的发布状态代码列表为
// Content is published
AppEngagePublishStatusCode.PUBLISHED,
// Content is not published as user is not signed in
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN,
// Content is not published as user is not subscribed
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SUBSCRIPTION,
// Content is not published as user location is ineligible
AppEngagePublishStatusCode.NOT_PUBLISHED_INELIGIBLE_LOCATION,
// Content is not published as there is no eligible content
AppEngagePublishStatusCode.NOT_PUBLISHED_NO_ELIGIBLE_CONTENT,
// Content is not published as the feature is disabled by the client
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_FEATURE_DISABLED_BY_CLIENT,
// Content is not published as the feature due to a client error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_CLIENT_ERROR,
// Content is not published as the feature due to a service error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_SERVICE_ERROR,
// Content is not published due to some other reason
// Reach out to engage-developers@ before using this enum.
AppEngagePublishStatusCode.NOT_PUBLISHED_OTHER
如果内容因用户未登录而未发布,Google 建议发布登录卡片。如果提供方因任何原因无法发布登录卡片,我们建议使用状态代码 NOT_PUBLISHED_REQUIRES_SIGN_IN 调用 updatePublishStatus API
Kotlin
client.updatePublishStatus( PublishStatusRequest.Builder() .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN) .build())
Java
client.updatePublishStatus( new PublishStatusRequest.Builder() .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN) .build());
deleteRecommendationClusters
此 API 用于删除推荐类别的内容。
Kotlin
client.deleteRecommendationClusters()
Java
client.deleteRecommendationClusters();
当服务收到请求时,它会从推荐类别中移除现有数据。如果发生错误,整个请求将被拒绝并保留现有状态。
deleteFeaturedCluster
此 API 用于删除精选类别的内容。
Kotlin
client.deleteFeaturedCluster()
Java
client.deleteFeaturedCluster();
当服务收到请求时,它会从精选类别中移除现有数据。如果发生错误,整个请求将被拒绝并保留现有状态。
deleteContinuationCluster
此 API 用于删除续播类别的内容。
Kotlin
client.deleteContinuationCluster()
Java
client.deleteContinuationCluster();
当服务收到请求时,它会从续播类别中移除现有数据。如果发生错误,整个请求将被拒绝并保留现有状态。
deleteUserManagementCluster
此 API 用于删除 UserAccountManagement 类别的内容。
Kotlin
client.deleteUserManagementCluster()
Java
client.deleteUserManagementCluster();
当服务收到请求时,它会从 UserAccountManagement 类别中移除现有数据。如果发生错误,整个请求将被拒绝并保留现有状态。
deleteClusters
此 API 用于删除给定类别类型的内容。
Kotlin
client.deleteClusters( DeleteClustersRequest.Builder() .addClusterType(ClusterType.TYPE_FEATURED) .addClusterType(ClusterType.TYPE_RECOMMENDATION) ... .build())
Java
client.deleteClusters( new DeleteClustersRequest.Builder() .addClusterType(ClusterType.TYPE_FEATURED) .addClusterType(ClusterType.TYPE_RECOMMENDATION) ... .build());
当服务收到请求时,它会从与指定类别类型匹配的所有类别中移除现有数据。客户端可以选择传递一个或多个类别类型。如果发生错误,整个请求将被拒绝并保留现有状态。
错误处理
强烈建议监听发布 API 返回的任务结果,以便可以采取后续操作来恢复并重新提交成功的任务。
client.publishRecommendationClusters(
new PublishRecommendationClustersRequest.Builder()
.addRecommendationCluster(...)
.build())
.addOnCompleteListener(
task -> {
if (task.isSuccessful()) {
// do something
} else {
Exception exception = task.getException();
if (exception instanceof AppEngageException) {
@AppEngageErrorCode
int errorCode = ((AppEngageException) exception).getErrorCode();
if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
// do something
}
}
}
});
错误以 AppEngageException
的形式返回,其中包含错误代码作为原因。
错误代码 | 错误名称 | 备注 |
---|---|---|
1 |
SERVICE_NOT_FOUND |
服务在给定设备上不可用。 |
2 |
SERVICE_NOT_AVAILABLE |
服务在给定设备上可用,但在调用时不可用(例如,它已被明确禁用)。 |
3 |
SERVICE_CALL_EXECUTION_FAILURE |
任务执行因线程问题而失败。在这种情况下,可以重试。 |
4 |
SERVICE_CALL_PERMISSION_DENIED |
调用方不允许进行服务调用。 |
5 |
SERVICE_CALL_INVALID_ARGUMENT |
请求包含无效数据(例如,超出允许的类别数量)。 |
6 |
SERVICE_CALL_INTERNAL |
服务端出现错误。 |
7 |
SERVICE_CALL_RESOURCE_EXHAUSTED |
服务调用过于频繁。 |
第 3 步:处理广播 Intent
除了通过作业进行内容发布 API 调用之外,还需要设置 BroadcastReceiver
来接收内容发布请求。
广播 Intent 的主要目的是应用重新激活和强制数据同步。广播 Intent 不会频繁发送。仅当 Engage 服务确定内容可能已过时(例如,已过时一周)时,才会触发它。这样,即使应用长时间未运行,用户也可以更有信心地获得新鲜的内容体验。
BroadcastReceiver
必须通过以下两种方式设置
- 使用
Context.registerReceiver()
动态注册BroadcastReceiver
类的一个实例。这使得内存中仍在运行的应用能够进行通信。
class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
// is received
// Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received
// Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is
// received
}
public static void registerBroadcastReceivers(Context context) {
context = context.getApplicationContext();
// Register Recommendation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_RECOMMENDATION));
// Register Featured Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_FEATURED));
// Register Continuation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_CONTINUATION));
}
- 在
AndroidManifest.xml
文件中使用<receiver>
标记静态声明实现。这允许应用在未运行时接收广播 Intent,并且还允许应用发布内容。
<application>
<receiver
android:name=".AppEngageBroadcastReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.engage.action.PUBLISH_FEATURED" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.engage.action.PUBLISH_CONTINUATION" />
</intent-filter>
</receiver>
</application>
服务将发送以下 Intent
com.google.android.engage.action.PUBLISH_RECOMMENDATION
建议在收到此 Intent 时开始publishRecommendationClusters
调用。com.google.android.engage.action.PUBLISH_FEATURED
建议在收到此 Intent 时开始publishFeaturedCluster
调用。com.google.android.engage.action.PUBLISH_CONTINUATION
建议在收到此 Intent 时开始publishContinuationCluster
调用。
集成工作流程
如需分步指南来验证集成是否已完成,请参阅Engage 开发者集成工作流程。
常见问题解答
如需常见问题解答,请参阅Engage SDK 常见问题解答。
联系我们
如果在集成过程中有任何问题,请联系 engage-developers@google.com。我们的团队将尽快回复。
后续步骤
完成此集成后,您的后续步骤如下
- 发送电子邮件至 engage-developers@google.com,并附上您已集成且可供 Google 测试的 APK。
- Google 将在内部执行验证和审核,以确保集成按预期工作。如果需要更改,Google 将与您联系并提供所有必要详情。
- 测试完成后且无需更改时,Google 将通知您可以开始将更新后的集成 APK 发布到 Play 商店。
- Google 确认您的更新版 APK 已发布到 Play 商店后,您的推荐、精选和续播类别将发布并对用户可见。