Engage SDK 社交:第三方技术集成说明

Google 正在构建一个设备端界面,它按垂直领域对用户的应用进行整理,并为个性化的应用内容使用和发现提供新的沉浸式体验。 此全屏体验为开发者合作伙伴提供了一个机会,让他们在应用之外的专用渠道中展示他们最好的富媒体内容。

本文档包含开发者合作伙伴使用 Engage SDK 集成其社交内容以填充此新区域的说明。

集成详细信息

以下部分包含集成详细信息。

术语

推荐 聚合显示来自单个开发者合作伙伴的个性化建议。

您的推荐采用以下结构

推荐聚合:包含来自同一开发者合作伙伴的一组推荐的 UI 视图。

每个推荐聚合包含以下两种类型的实体之一

  • PortraitMediaEntity
  • SocialPostEntity

PortraitMediaEntity 必须包含帖子的 1 张纵向图像。 与个人资料和互动相关的元数据是可选的。

  • 帖子

    • 纵向模式下的图像和时间戳,或
    • 纵向模式下的图像 + 文本内容和时间戳
  • 个人资料

    • 头像、名称或手柄、其他图像
  • 互动

    • 仅计数和标签,或
    • 计数和视觉效果(图标)

SocialPostEntity 包含个人资料、帖子和互动相关的元数据。

  • 个人资料

    • 头像、名称或手柄、其他文本、其他图像
  • 帖子

    • 文本和时间戳,或
    • 富媒体(图像或富链接)和时间戳,或
    • 文本和富媒体(图像或富链接)和时间戳,或
    • 视频预览(缩略图和持续时间)和时间戳
  • 互动

    • 仅计数和标签,或
    • 计数和视觉效果(图标)

准备工作

最低 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'
}

摘要

该设计基于对 绑定服务 的实现。

客户端可以发布的数据受以下限制,这些限制适用于不同的聚合类型

聚合类型 聚合限制 聚合中的最小实体限制 聚合中的最大实体限制
推荐聚合 最多 5 个 至少 5 个 (PortraitMediaEntitySocialPostEntity) 最多 25 个 (PortraitMediaEntitySocialPostEntity)

步骤 1:提供实体数据

SDK 定义了不同的实体来表示每种项目类型。SDK 支持以下用于社交类别的实体

  1. PortraitMediaEntity
  2. SocialPostEntity

以下图表概述了每种类型可用的属性和要求。

PortraitMediaEntity

属性 要求 描述 格式
操作 URI 必需

指向提供者应用程序中实体的深度链接。

注意:您可以使用深度链接进行归因。 请参阅此常见问题解答

URI
与帖子相关的元数据(必需)
图片 必需

图片应为纵向纵横比

当提供多个图片时,UI 可能只显示 1 张图片。但是,UI 可能会提供视觉指示,表明应用程序中还有更多图片。

如果帖子是视频,则提供者应提供视频的缩略图作为图片显示。

有关指导,请参阅 图片规范
文本内容 可选 帖子的主要文本,更新等。 字符串(推荐最大长度 140 个字符)
时间戳 可选 帖子发布的时间。 以毫秒为单位的纪元时间戳
是否为视频内容 可选 帖子是否为视频? 布尔值
视频时长 可选 视频的时长,以毫秒为单位。 长整型
与个人资料相关的元数据(可选)
姓名 必需 个人资料名称、ID 或句柄,例如“John Doe”、“@TeamPixel” 字符串(推荐最大长度 25 个字符)
头像 必需

用户的个人资料图片或头像。

正方形 1:1 图片

有关指导,请参阅 图片规范
附加图片 可选

个人资料徽章。例如 - 验证徽章

正方形 1:1 图片

有关指导,请参阅 图片规范
与互动相关的元数据(可选)
计数 可选

指示互动次数,例如“3.7 M.”。

注意:如果同时提供计数和计数值,则使用计数

字符串

推荐的文本大小:计数 + 标签组合的最大长度为 20 个字符

计数值 可选

互动次数的值。

注意:如果您的应用程序不处理如何针对不同显示尺寸优化大数字的逻辑,请提供计数值而不是计数。如果同时提供计数和计数值,则使用计数。

长整型
标签 可选 指示互动标签的用途。例如 - “喜欢”。

字符串

推荐的文本大小:计数 + 标签组合的最大长度为 20 个字符

视觉 可选

指示互动的用途。例如 - 显示喜欢图标、表情符号的图片。

可以提供多个图片,但并非所有图片都会在所有外形尺寸上显示。

注意:必须为正方形 1:1 图片

有关指导,请参阅 图片规范
DisplayTimeWindow(可选) - 设置内容在界面上显示的时间窗口
开始时间戳 可选

内容应在界面上显示的纪元时间戳。

如果未设置,则内容有资格在界面上显示。

以毫秒为单位的纪元时间戳
结束时间戳 可选

内容不再在界面上显示的纪元时间戳。

如果未设置,则内容有资格在界面上显示。

以毫秒为单位的纪元时间戳

SocialPostEntity

属性 要求 描述 格式
操作 URI 必需

指向提供者应用程序中实体的深度链接。

注意:您可以使用深度链接进行归因。 请参阅此常见问题解答

URI

与帖子相关的元数据(必需)

至少需要文本内容、图片或网页内容之一

图片 可选

图片应为纵向纵横比

当提供多个图片时,UI 可能只显示 1 张图片。但是,UI 可能会提供视觉指示,表明应用程序中还有更多图片。

如果帖子是视频,则提供者应提供视频的缩略图作为图片显示。

有关指导,请参阅 图片规范
文本内容 可选 帖子的主要文本,更新等。 字符串(推荐最大长度 140 个字符)
视频内容(可选)
时长 必需 视频的时长,以毫秒为单位。 长整型
图片 必需 视频内容的预览图片。 有关指导,请参阅 图片规范
链接预览(可选)
链接预览 - 标题 必需 指示网页内容标题的文本 字符串
链接预览 - 主机名 必需 指示网页所有者的文本,例如“INSIDER” 字符串
链接预览 - 图片 可选 网页内容的英雄图片 有关指导,请参阅 图片规范
时间戳 可选 帖子发布的时间。 以毫秒为单位的纪元时间戳
与个人资料相关的元数据(可选)
姓名 必需 个人资料名称、ID 或句柄,例如“John Doe”、“@TeamPixel”。 字符串(推荐最大长度 25 个字符)
附加文本 可选

可用作个人资料 ID 或句柄或附加元数据

例如“@John-Doe”、“500 万粉丝”、“您可能喜欢”、“趋势”、“5 个新帖子”

字符串(推荐最大长度 40 个字符)
头像 必需

用户的个人资料图片或头像。

正方形 1:1 图片

有关指导,请参阅 图片规范
附加图片 可选

个人资料徽章。例如 - 验证徽章

正方形 1:1 图片

有关指导,请参阅 图片规范
与互动相关的元数据(可选)
计数 必需 指示互动次数,例如“3.7 M.”。 字符串(推荐的计数 + 标签组合最大长度为 20 个字符)
标签

可选

如果未提供,则必须提供视觉

指示互动的用途。例如 - “喜欢”。 字符串(推荐的计数 + 标签组合最大长度为 20 个字符)
视觉

可选

如果未提供,则必须提供标签

指示互动的用途。例如 - 显示喜欢图标、表情符号的图片。

可以提供多个图片,但并非所有图片都会在所有外形尺寸上显示。

正方形 1:1 图片

有关指导,请参阅 图片规范
DisplayTimeWindow(可选) - 设置内容在界面上显示的时间窗口
开始时间戳 可选

内容应在界面上显示的纪元时间戳。

如果未设置,则内容有资格在界面上显示。

以毫秒为单位的纪元时间戳
结束时间戳 可选

内容不再在界面上显示的纪元时间戳。

如果未设置,则内容有资格在界面上显示。

以毫秒为单位的纪元时间戳

图片规范

图片需要托管在公共 CDN 上,以便 Google 能够访问它们。

文件格式

PNG、JPG、静态 GIF、WebP

最大文件大小

5120 KB

其他建议

  • 图片安全区域:将重要内容放在图片中心 80% 的区域内。
  • 使用透明背景,以便图片可以在深色和浅色主题设置中正确显示。

步骤 2:提供集群数据

建议在后台执行内容发布作业(例如,使用 WorkManager),并定期或基于事件进行调度(例如,每次用户打开应用程序时或用户刚刚关注新帐户时)。

AppEngageSocialClient 负责发布社交集群。

客户端中有以下 API 用于发布集群

  • isServiceAvailable
  • publishRecommendationClusters
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • 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 对象列表。

一个 RecommendationCluster 对象可以具有以下属性

属性 要求 描述
SocialPostEntity 或 PortraitMediaEntity 列表 必需 构成此推荐集群推荐的实体列表。单个集群中的实体必须属于同一类型。
标题 必需

推荐集群的标题(例如,来自您朋友的最新消息)。

推荐的文本大小:少于 25 个字符(过长的文本可能会显示省略号)

副标题 可选 推荐集群的副标题。
操作 URI 可选

合作伙伴应用程序中页面的深度链接,用户可以在该页面上查看完整的推荐列表。

注意:您可以使用深度链接进行归因。 请参阅此常见问题解答

Kotlin

client.publishRecommendationClusters(
            PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Latest from your friends")
                        .build())
                .build())

Java

client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Latest from your friends")
                        .build())
                .build());

当服务收到请求时,以下操作将在一个事务中执行

  • 删除所有现有的推荐集群数据。
  • 解析来自请求的数据并将其存储在新的推荐集群中。

如果出现错误,则整个请求将被拒绝,并且保持现有状态。

publishUserAccountManagementRequest

此 API 用于发布登录卡。登录操作将用户引导至应用程序的登录页面,以便应用程序可以发布内容(或提供更个性化的内容)。

以下元数据是登录卡的一部分 -

属性 要求 描述
操作 URI 必需 指向操作的深度链接(即导航到应用程序登录页面)
图片 可选 - 如果未提供,则必须提供标题

在卡片上显示的图片

16x9 纵横比图片,分辨率为 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();

当服务收到请求时,它会从推荐集群中删除现有数据。如果出现错误,则整个请求将被拒绝,并且保持现有状态。

deleteUserManagementCluster

此 API 用于删除 UserAccountManagement 集群的内容。

Kotlin

client.deleteUserManagementCluster()

Java

client.deleteUserManagementCluster();

当服务收到请求时,它会从 UserAccountManagement 集群中删除现有数据。如果出现错误,则整个请求将被拒绝,并且保持现有状态。

deleteClusters

此 API 用于删除给定集群类型的内容。

Kotlin

client.deleteClusters(
    DeleteClustersRequest.Builder()
      .addClusterType(ClusterType.TYPE_RECOMMENDATION)
      ...
      .build())

Java

client.deleteClusters(
            new DeleteClustersRequest.Builder()
                .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 返回,其中包含原因作为错误代码。

错误代码 注意
SERVICE_NOT_FOUND 给定设备上没有此服务。
SERVICE_NOT_AVAILABLE 给定设备上存在此服务,但在调用时不可用(例如,它被明确禁用)。
SERVICE_CALL_EXECUTION_FAILURE 任务执行失败,原因是线程问题。在这种情况下,可以重试。
SERVICE_CALL_PERMISSION_DENIED 调用方无权进行服务调用。
SERVICE_CALL_INVALID_ARGUMENT 请求包含无效数据(例如,超过允许的集群数量)。
SERVICE_CALL_INTERNAL 服务端发生错误。
SERVICE_CALL_RESOURCE_EXHAUSTED 服务调用过于频繁。

步骤 3:处理广播意图

除了通过作业进行发布内容 API 调用外,还需要设置一个 BroadcastReceiver 来接收内容发布请求。

广播意图的主要目标是应用重新激活和强制数据同步。广播意图并非设计为频繁发送。它仅在 Engage 服务确定内容可能已过时(例如,一周前)时触发。这样,即使应用程序长时间未执行,用户也能更有信心获得新鲜的内容体验。

必须通过以下两种方式设置 BroadcastReceiver

  • 使用 Context.registerReceiver() 动态注册 BroadcastReceiver 类的实例。这使仍然驻留在内存中的应用程序能够进行通信。
class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION 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));

}

  • 在您的 AndroidManifest.xml 文件中使用 <receiver> 标签静态声明一个实现。这允许应用程序在未运行时接收广播意图,并允许应用程序发布内容。
<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>
   </receiver>
</application>

服务将发送以下 意图

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION 建议在收到此意图时启动 publishRecommendationClusters 调用。

集成工作流程

有关完成集成后验证集成的分步指南,请参阅 Engage 开发者集成工作流程

常见问题解答

有关常见问题解答,请参阅 Engage SDK 常见问题解答

联系方式

如有任何集成过程中的问题,请联系 [email protected]。我们的团队将尽快回复。

后续步骤

完成此集成后,您的后续步骤如下:

  • 发送电子邮件至 [email protected],并附上您已准备好供 Google 测试的集成 APK。
  • Google 将执行验证并进行内部审查,以确保集成按预期工作。如果需要更改,Google 会与您联系,提供必要的详细信息。
  • 测试完成后,如果不需要进行任何更改,Google 会与您联系,通知您您可以开始将更新的集成 APK 发布到 Play 商店。
  • Google 确认您已将更新的 APK 发布到 Play 商店后,您的推荐、集群将发布并对用户可见。