如何配置 Attribution Reporting 的触发事件和报告阈值?

解读

Attribution Reporting(归因报告)是 Android 13+ 引入的隐私沙盒(Privacy Sandbox)核心组件,用于在限制广告 ID(GAID)的前提下,让广告平台仍能衡量广告点击/浏览到后续转化(如激活、下单)的效果。国内面试中,面试官想确认两点:

  1. 你是否把“触发事件”理解为“转化事件”(Trigger),而非“点击/浏览事件”(Source);
  2. 你是否知道国内主流渠道(华为、OPPO、VIVO、小米)已同步支持 Privacy Sandbox,并兼容 MMP(AppsFlyer、Adjust)的聚合 SDK,因此配置方式与 GMS 差异不大,但需额外在厂商后台登记转化 ID。
    回答时要体现“SDK 声明 + 服务器端联合”的双端配置思路,并给出可落地的阈值公式,避免只背官方文档。

知识点

  1. 双轨事件模型
    • Source:广告点击或浏览,由 Ad SDK 调用 registerSource(Uri) 上报。
    • Trigger:用户激活、注册、付费等,由 App 业务代码调用 registerTrigger(Uri) 上报。
  2. 报告类型
    • Event-level:仅返回 1 位加密噪声数据,优先级低。
    • Aggregatable:返回加密直方图,需与 Attribution Reporting API 后端做 PCC(Private Compute Core)解密。
  3. 阈值体系
    • 触发优先级(priority):32 位有符号整型,高者优先出报告。
    • 过滤键(filter_data):JSON 键值对,用于做“白名单”过滤,防止刷量。
    • 报告窗口(expiry):最大 30 天,国内渠道默认 7 天。
    • 噪声缩放(epsilon):隐私预算,默认 ε=16,可下调到 4 降低噪声,但会减少有效样本。
  4. 国内合规
    • 需在《隐私政策》中单独章节声明“使用 Privacy Sandbox 进行广告效果衡量”,并支持用户一键关闭。
    • 华为、OPPO 要求额外在“转化跟踪”模块登记 destination 包名,与 GP 一致,否则会被过滤。

答案

步骤一:在 AndroidManifest 中声明权限与 PCC 组件

<uses-permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION" />
<property android:name="android.adservices.AD_SERVICES_CONFIG"
          android:resource="@xml/ad_services_config" />

ad_services_config.xml

<ad-services-config>
    <attribution allowAllToAccess="false">
        <allow-package>com.example.partner1</allow-package>
        <allow-package>com.mmp.adjust</allow-package>
    </attribution>
</ad-services-config>

步骤二:登记 Source(以点击为例)

val sourceUri = Uri.parse(
    "https://yourserver.com/attribution/source?" +
    "destination=cn.company.app&" +
    "source_event_id=123456&" +
    "priority=100&" +
    "expiry=86400000&" +   // 1 天,单位毫秒
    "filter_data.campaign=618&" +
    "filter_data.channel=huawei")
val future = Attribution.getAttributionClient(this)
    .registerSource(sourceUri)

步骤三:登记 Trigger(转化)

val triggerUri = Uri.parse(
    "https://yourserver.com/attribution/trigger?" +
    "event_trigger_data=eyJwIjoxMDAsInYiOjB9&" + // base64 编码的 {"p":100,"v":0}
    "aggregatable_trigger_data.key=pay&" +
    "aggregatable_values.pay=5000") // 5000 分 = 50 元
Attribution.getAttributionClient(this)
    .registerTrigger(triggerUri)

步骤四:服务器端配置阈值(以 Aggregatable 为例)

  1. 设定每日隐私预算 ε=8,则有效触发数 = 真实触发数 × (1 – 1/(1+exp(ε/2))) ≈ 真实触发数 × 0.98。
  2. 若要求 95% 置信、相对误差 <5%,则最小转化量 N ≥ 4×(1.96/0.05)²×(1+exp(ε/2)) ≈ 6400。
  3. 低于 6400 的 campaign 自动降级到 Event-level 报告,并在后台打标签“low_volume”,用于后续拼接。

步骤五:国内渠道额外登记

  • 华为:登录 AppGallery Connect → 增长 → 转化跟踪 → 新建事件 → 填写 destination 与公钥(PEM)。
  • OPPO:开放平台 → 广告追踪 → 归因配置 → 上传同一套公钥,并勾选“支持 Privacy Sandbox”。
    公钥用于 PCC 加密,必须与服务器侧 /attribution/.well-known/aggregation_service.json 内的 public_key 字段一致,否则报告会被丢弃。

拓展思考

  1. 折叠屏与多窗口场景下,同一设备可能产生多份 Source,如何防止重复归因?
    可在 filter_data 中增加 session_id,由客户端生成 UUID,并在服务器端做 24 h 去重窗口。
  2. 国内小程序(快应用)跳端转化无法直接调用 registerTrigger,业界通用方案是:
    快应用落地页把转化信息写入系统剪贴板(带 5 min TTL),App 首次启动时读取并立即上报 Trigger,同时清空剪贴板,该方案已通过华为审核。
  3. 未来 Privacy Sandbox 将引入 Topics API 与 Protected Audience,Attribution Reporting 会与二者共享隐私预算。面试中可以主动提出“预算池”设计:把 ε 拆成 ε_attribution + ε_topics,用服务器端动态分配算法,保证总 ε≤16,体现你对整个隐私沙盒体系的深度理解。