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

通过在用户所在之处触达用户来提升应用互动。集成 Engage SDK 可将个性化推荐和延续内容直接传递给用户,覆盖多个设备端界面,例如收藏夹娱乐空间和 Play 商店。该集成将平均 APK 的大小增加不到 50 KB(压缩后),并且大多数应用只需大约一周的开发时间。在我们的商业网站了解更多信息。

本指南包含开发者合作伙伴向 Engage 内容界面传递社交媒体内容的说明。

集成详情

以下部分介绍了集成详情。

术语

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

您的推荐采用以下结构:

推荐集群:包含来自同一开发者合作伙伴的一组推荐的 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'
}

摘要

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

客户端可以发布的数据受以下不同集群类型的限制:

集群类型 集群限制 集群中的实体最少限制 集群中的实体最多限制
推荐集群 最多 7 个 至少 1 个(PortraitMediaEntitySocialPostEntity 最多 50 个(PortraitMediaEntitySocialPostEntity

第 1 步:提供实体数据

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

  1. PortraitMediaEntity
  2. SocialPostEntity

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

PortraitMediaEntity

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

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

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

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

图片应采用竖向宽高比。

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

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

请参阅图片规格以获取指导。
文本内容 可选 帖子、更新等的主要文本。 字符串(建议最多 140 个字符)
时间戳 可选 帖子发布时间。 毫秒级 Epoch 时间戳
是否为视频内容 可选 帖子是视频吗? 布尔值
视频时长 可选 视频时长(毫秒)。 长整型
个人资料相关元数据(可选)
名称 必需 个人资料名称、ID 或句柄,例如“John Doe”、“@TeamPixel” 字符串(建议最多 25 个字符)
头像 必需

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

方形 1:1 图片

请参阅图片规格以获取指导。
附加图片 可选

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

方形 1:1 图片

请参阅图片规格以获取指导。
互动相关元数据(可选)
计数 可选

表示互动次数,例如 -“3.7 M”。

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

字符串

建议文本大小:计数 + 标签组合后最多 20 个字符

计数数值 可选

互动次数的数值。

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

长整型
标签 可选 表示互动的标签是什么。例如 -“点赞”。

字符串

建议文本大小:计数 + 标签组合后最多 20 个字符

视觉效果 可选

表示互动是什么。例如 - 显示点赞图标、表情符号的图片。

可以提供多张图片,但并非所有图片都可能在所有外形规格上显示。

注意:必须是方形 1:1 图片

请参阅图片规格以获取指导。
DisplayTimeWindow(可选)- 为内容设置在界面上显示的时间窗口
开始时间戳 可选

内容应在此 Epoch 时间戳之后显示在界面上。

如果未设置,内容可显示在界面上。

毫秒级 Epoch 时间戳
结束时间戳 可选

内容在此 Epoch 时间戳之后不再显示在界面上。

如果未设置,内容可显示在界面上。

毫秒级 Epoch 时间戳

SocialPostEntity

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

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

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

URI

帖子相关元数据(必需)

TextContent、Image 或 WebContent 至少需要其中一个

图片 可选

图片应采用竖向宽高比。

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

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

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

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

例如“@John-Doe”、“5M 粉丝”、“您可能会喜欢”、“热门”、“5 个新帖子”

字符串(建议最多 40 个字符)
头像 必需

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

方形 1:1 图片

请参阅图片规格以获取指导。
附加图片 可选

个人资料徽章,例如 - 已验证徽章

方形 1:1 图片

请参阅图片规格以获取指导。
互动相关元数据(可选)
计数 必需 表示互动次数,例如 -“3.7 M”。 字符串(建议计数 + 标签组合后最多 20 个字符)
标签

可选

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

表示互动是什么。例如 -“点赞。” 字符串(建议计数 + 标签组合后最多 20 个字符)
视觉效果

可选

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

表示互动是什么。例如 - 显示点赞图标、表情符号的图片。

可以提供多张图片,但并非所有图片都可能在所有外形规格上显示。

方形 1:1 图片

请参阅图片规格以获取指导。
DisplayTimeWindow(可选)- 为内容设置在界面上显示的时间窗口
开始时间戳 可选

内容应在此 Epoch 时间戳之后显示在界面上。

如果未设置,内容可显示在界面上。

毫秒级 Epoch 时间戳
结束时间戳 可选

内容在此 Epoch 时间戳之后不再显示在界面上。

如果未设置,内容可显示在界面上。

毫秒级 Epoch 时间戳

图片规格

图片需要托管在公共 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 建议发布登录卡片。如果提供商因任何原因无法发布登录卡片,我们建议调用 updatePublishStatus API,并将状态码设置为 NOT_PUBLISHED_REQUIRES_SIGN_IN

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 Cluster 的内容。

Kotlin

client.deleteUserManagementCluster()

Java

client.deleteUserManagementCluster();

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

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 的形式返回,原因包含在错误码中。

错误码 错误名称 注意
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
}

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> 标签静态声明一个实现。这允许应用在未运行时接收广播 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>
   </receiver>
</application>

服务将发送以下Intent

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

集成工作流程

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

常见问题解答

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

联系方式

如果在集成过程中有任何疑问,请联系engage-developers@google.com。我们的团队将尽快回复。

后续步骤

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

  • 发送电子邮件至engage-developers@google.com,并附上您已集成且可供 Google 测试的 APK。
  • Google 将进行验证和内部审查,以确保集成按预期工作。如果需要更改,Google 将与您联系并提供任何必要的详细信息。
  • 当测试完成且无需更改时,Google 会通知您可以开始将更新和集成的 APK 发布到 Play 商店。
  • 在 Google 确认您更新的 APK 已发布到 Play 商店后,您的推荐集群将发布并对用户可见。