Privacy Sandbox on Android 开发者预览版现已推出!了解如何开始使用,并继续提供反馈

通过 Topics API 针对用户兴趣投放广告

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

提供反馈

关于 Topics API

在移动广告中,广告客户希望投放与用户兴趣相关的广告。例如,如果用户对与烹饪相关的信息感兴趣,他们可能会发现与烹饪相关的广告比与自己兴趣无关的广告更贴合自己的需求。

针对用户兴趣投放广告 (IBA) 是一种个性化广告,即根据用户过去互动过的应用推测用户的兴趣,然后据此为用户选择广告。这种广告不同于内容相关广告,后者仅根据用户当前所查看的内容来推测用户感兴趣的广告。与内容相关广告相比,IBA 的优势之一在于,IBA 可让应用向用户展示更具相关性和吸引力的广告。

Topics API 可根据用户的应用使用情况来粗略推断设备上的兴趣信号。系统会将这些信号(称为“主题”)共享给广告客户,以支持 IBA 用例,而无需跨应用跟踪单个用户。

主要概念

  • “主题”是指简单易懂的用户兴趣主题,是“主题”分类的一部分。
  • 如果某个调用方(应用或应用中使用的第三方 SDK)在过去 3 个周期内通过与某个主题相关联的应用发出了 Topics API 请求,此调用方就会观察该主题。
  • “周期”是指主题计算期限,例如一周。

运作方式

在此方案中,Topics API 会根据用户的应用使用情况,为调用方提供粗略的兴趣广告主题。 这些主题可用于补充与想要展示广告的应用相关的任何上下文信息,也可组合在一起以帮助为用户查找合适的广告。

请参阅 Topics API 开发者指南中的相关代码示例,了解如何为“针对用户兴趣投放广告”设置主题提取功能。注意:这些 API 尚未最终确定。

主题是从预定义的开源分类中选择的。

平台使用分类器模型来推断主题。Topics API 实现及其对分类器的使用将包含在 Android 开源项目中,并将随着时间的推移而不断改进。

注册广告技术平台

若要访问 Topics API,所有广告技术平台(包括 Google 的广告技术平台平台)都需要完成一个简易的注册流程。该流程的细节仍在开发中,我们欢迎您提供反馈。

如果有合理的业务需求(例如运营多个独立的产品线),企业可以注册多次,但不得合并通过多次注册获得的数据来绕过隐私保护限制。

应用开发者可以将广告技术开发者的注册 ID 添加到应用清单内,以便于管理哪些广告技术开发者可以访问 Topics API。

详细信息

  • 系统会使用设备端信息来计算用户的 5 个热门主题,此计算每个周期进行一次(例如,每周一次)。

    • 调用 Topics API 后,平台会检查是否已为调用此 API 的应用分配主题。如果未分配任何主题,系统会按以下方式选择一个主题,并将所选主题分配给该应用,且有效期为相应周期的剩余时间。
      • 如果概率为 95%,系统会从为此周期计算的 5 个热门主题列表中随机选择一个主题。
      • 如果概率为 5%,系统会从分类中随机选择一个主题。
    • 之所以让每个应用分别获取多个主题中的一个,是为了确保不同的应用能够获得不同的主题,让不同应用难以对同一用户进行互相关。
      • 例如,应用 A 可能会看到用户主题 T1,但应用 B 可能会看到主题 T2。这样一来,这两个应用就更加难以确定相关信息是与同一用户相关联的了。
  • Topics API 会返回一个最多包含 3 个主题的列表,过去 3 个周期分别有 1 个主题。

    • 通过提供最多 3 个主题,不常用的应用将拥有足够的主题用于查找相关的广告,但常用应用每周最多可以获取 1 个新主题。
    • 返回的主题信息包含与分类中的条目相对应的主题 ID (int)、分类版本和分类器模型版本。
    • 只有在过去 3 个周期内观察到用户使用了与主题相关联的应用的调用方才能接收此主题。
    • 返回的所有主题都表示用户的兴趣,您可以选择其中任何或所有主题,以用于在广告请求中进行广告个性化。
  • 将某个主题分配给调用 Topics API 的应用后,平台会确定调用方是否可以接收此主题。

    • 只有在过去 3 个周期内观察到用户与主题的关联应用进行了互动的调用方才能接收此主题。
    • 如果调用方过去未在与此主题有关的应用中针对相应用户调用该 API,此主题就不会包含在该 API 返回的列表中。
    • 如果调用方在过去 3 个周期内未收到任何主题,Topics API 将返回空列表。

    例如,假设用户在设备上安装了 7 个应用:A、B、C、D、E、F 和 G。假设应用的主题分类以及这些应用中的广告技术 SDK 如下所示:

    应用 主题分类 广告技术 SDK
    A T1、T5 ad-sdk1、ad-sdk2
    B T2 ad-sdk2
    C T3、T6 ad-sdk3、ad-sdk4
    D T1, T4 ad-sdk1
    E T5 ad-sdk4、ad-sdk5
    F T6 ad-sdk2、ad-sdk3、ad-sdk4
    G T7 ad-sdk2
    • 第 1 周结束时:Topics API 会针对此周期生成用户的 5 个热门主题。
    热门主题 可获取此主题的调用方
    T1 ad-sdk1、ad-sdk2
    T2 ad-sdk2
    T3 ad-sdk3、ad-sdk4
    T4 ad-sdk1
    T5 ad-sdk1、ad-sdk2、ad-sdk4、ad-sdk5
    • 在第 2 周,如果任何应用中的某个调用方调用此 API,返回的主题列表将仅包含符合以下条件的主题:该调用方包含在主题在相应周期内针对相关应用的“可获取此主题的调用方”列中。
    • 计算每个调用方可用的主题时用到的历史期限为 3 个周期(或 3 周)。
    • 仅使用与调用 Topics API(直接调用,或通过广告 SDK 调用)的应用相关联的主题。这意味着,如果某个应用不包含任何调用 Topics API 的广告 SDK,其本身也不调用此 API,与其他应用或广告 SDK 共享的主题中便不会包含与该应用相关联的主题。
    • 应用还可以通过新的清单和 XML 元素明确停用 Topics API,以禁止广告 SDK 针对该应用使用此 API。每周主题的计算不会考虑与选择停用的应用相关联的主题。本文档的内容会进行更新,以包含相关实现详情。
  • 如果应用使用情况数据不足,导致平台无法推断出 5 个主题,平台可能会考虑随机生成剩余主题等选项。

分类

  • 在当前方案中,初始分类包含的主题数量在几百到几千之间。在未来对本文档的更新中,我们将与您分享初始分类方案的相关信息。
  • 此分类将由人工挑选,以确保其中不含敏感主题。
  • 我们会根据可在 Android 移动应用中展示的广告类别调整此分类。
  • 分类是开源的,可能会发生变化。您可以使用此页面顶部的反馈按钮提交建议。

主题分类器

兴趣主题衍生自基于公开的应用信息(例如应用名称、说明和软件包名称)进行训练的分类器模型。

  • 在使用分类器模型进行推理以计算给定周期的主题时,所用的那组信号会保留在设备上。这组信号可能包含已安装的应用或最近使用过的应用,之后还可能会进行扩展,以包含其他信号。
  • 初始模型将由 Google 进行训练,其训练数据包含人工挑选的公开的应用信息标签。应用开发者可免费使用此模型进行测试,以了解其应用会归类为哪些主题。
  • 初始模型将基于来自一组有限的应用商店(例如 Google Play 商店)的公开应用信息进行训练。
  • 应用可能会映射到多个主题,可能未映射到任何主题,也可能未向用户的主题历史记录添加任何内容。如果某个应用映射到分类中的多个主题,为此应用选择的主题数量将按上限限定为 3 个。

用户控制功能

  • 此设计旨在让用户能够查看和移除与其应用使用情况相关联的主题。此用户控制功能正处于实现阶段,将包含在未来的更新中。
  • 如果用户卸载了某个应用,而此应用在过去 3 个周期的推断主题的选择过程中贡献过数据,系统不会从针对过去 3 个周期返回的主题列表中移除相应主题,以避免泄露与卸载相关的信息。

为了方便测试最终用户体验,您还可以启动一个应用内 intent,以便查看 Topics 的设置界面(与最终用户看到的界面类似)。该调用的示例如下所示:

//Button that launches settings UI
private Button mSettingsAppButton;
private static final String RB_SETTING_APP_INTENT = "android.adservices.ui.SETTINGS";

//Does setup for button on screen that will launch settings UI to observe Topics
private void registerLauchSettingsAppButton() {
    mSettingsAppButton.setOnClickListener(
        new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Context context = getApplicationContext();
                Intent activity2Intent = new Intent(RB_SETTING_APP_INTENT);
                activity2Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(activity2Intent);
            }
        });
}