Android 版 FLEDGE 开发者指南

在阅读 Privacy Sandbox on Android 文档时,请使用开发者预览版Beta 版按钮选择您所使用的程序版本,因为说明可能会有所不同。


Android 版 FLEDGE 包含 Custom Audience API 和 Ad Selection API。广告技术平台和广告主可以使用这些 API 根据用户之前的应用互动情况投放定制广告,既限制应用之间共享标识符的行为,也限制与第三方共享用户的应用互动信息的行为。

Custom Audience API 以“自定义受众群体”(代表一组具有共同意向的用户)抽象为中心。广告主可以为用户注册自定义受众群体,并将相关广告与其相关联。此信息存储在本地,可用于为广告主出价、广告过滤和广告呈现提供依据。

Ad Selection API 提供了一个框架,可以让多个开发者在本地针对自定义受众群体运行竞价。为了做到这一点,系统会考虑与自定义受众群体关联的相关广告,并对广告技术平台向设备返回的广告执行额外的处理。

广告技术平台可以集成这些 API,以实现保护用户隐私的再营销。我们计划在未来的版本中提供对其他用例(包括应用安装广告)的支持。如需详细了解 Android 版 FLEDGE,请参阅设计方案

本开发者指南将介绍如何使用 Android 版 FLEDGE 执行以下操作:

  1. 管理自定义受众群体
  2. 在设备上设置和运行广告选择
  3. 报告广告展示次数

准备工作

在开始之前,请完成以下步骤:

  1. 为 Privacy Sandbox on Android 设置开发环境
  2. 将系统映像安装到受支持的设备上设置支持 Privacy Sandbox on Android 的模拟器
  3. 在终端中,使用以下 adb 命令启用对 FLEDGE API 的访问权限(默认处于停用状态)。

      adb shell device_config put adservices ppapi_app_allow_list \"*\"
    
  4. 在应用清单中添加 ACCESS_ADSERVICES_CUSTOM_AUDIENCE 权限:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE" />
    
  5. 在清单的 <application> 元素中引用广告服务配置:

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
                android:resource="@xml/ad_services_config" />
    
  6. 指定清单中引用的广告服务 XML 资源,例如 res/xml/ad_services_config.xml详细了解广告服务权限和 SDK 访问权限控制

      <ad-services-config>
        <custom-audiences allowAllToAccess="true" />
      </ad-services-config>
    
  7. 默认情况下,Ad Selection API 会对竞价或展示报告脚本可以分配的最大内存量施加限制。如需使用内存限制功能,需要使用 WebView 版本 105.0.5195.58 或更高版本。平台会强制执行版本检查,如果不符合此版本要求,对 selectAdsreportImpression API 的调用将失败。您可以通过以下两种方式进行此设置:

    • 方式 1:运行以下 adb 命令以停用此检查:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • 方式 2:从 Google Play 商店安装 WebView Beta 版。此版本必须等于或高于上述版本。

加入自定义受众群体

自定义受众群体代表一组由广告主应用确定出的具有共同意向或兴趣的用户。应用或 SDK 可使用自定义受众群体来指示特定受众群体,例如在购物车中添加商品却未结账的用户。如需异步创建或加入自定义受众群体,请执行以下操作:

  1. 初始化 CustomAudienceManager 对象。
  2. 通过指定买方软件包和相关名称等关键参数来创建 CustomAudience 对象。然后,使用 CustomAudience 对象初始化 JoinCustomAudienceRequest 对象。
  3. 使用 JoinCustomAudienceRequest 对象及相关的 ExecutorOutcomeReceiver 对象调用异步 joinCustomAudience()

Kotlin

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a custom audience.
val audience = CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build()

// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
    JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver)

Java

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build();

// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
    new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver);

以下参数的组合可以唯一标识设备上的每个 CustomAudience 对象

  • owner:所有者应用的软件包名称。该变量会隐式设置为调用方应用的软件包名称。
  • buyer:买方广告网络的标识符(此广告网络负责管理面向此自定义受众群体的广告)。
  • name:自定义受众群体的任意名称或标识符。

使用不同的 CustomAudience 实例反复调用 joinCustomAudience() 时,将会更新任何具有匹配的 owner, buyername 参数的现有 CustomAudience。为了帮助保护隐私,该 API 的结果不区分“创建”和“更新”。

此外,必须使用以下必需参数创建 CustomAudience

  • 每日更新网址每天在后台查询的 HTTPS 网址,用于更新自定义受众群体的用户出价信号、可信出价数据以及广告的呈现网址和元数据。
  • 出价逻辑网址:在广告选择过程中查询的 HTTPS 网址,用于提取买方的 JavaScript 出价逻辑。查看此 JavaScript 中必需的函数签名

CustomAudience 对象的可选参数可能包括:

  • 启用时间:自定义受众群体只能在其启用时间之后参与广告选择和每日更新。例如,这有助于吸引已流失的应用用户。
  • 到期时间:未来的某个时间,超过此时间后,自定义受众群体将从设备中移除。
  • 用户出价信号:一个 JSON 字符串,包含买方的出价逻辑 JavaScript 会使用的用户信号(例如用户的首选语言区域),用于在广告选择流程中生成出价。此格式有助于广告技术平台跨平台重复使用代码并简化 JavaScript 函数的使用。
  • 可信出价数据:广告选择流程中使用的 HTTPS 网址和字符串列表,用于从可信的键值对服务器中提取出价信号。
  • 广告:与要参与广告选择的广告相对应的 AdData 对象列表。每个 AdData 对象都包含:
    • 呈现网址:为呈现最终广告而查询的 HTTPS 网址。
    • 元数据:已序列化为字符串的 JSON 对象,包含买方出价逻辑在广告选择流程中要使用的信息。

下面是一个 CustomAudience 对象实例化的示例:

Kotlin

// Minimal initialization of a CustomAudience object
val customAudience: CustomAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build()

Java

// Minimal initialization of a CustomAudience object
CustomAudience customAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build();

处理 joinCustomAudience() 结果

异步 joinCustomAudience() 方法使用 OutcomeReceiver 对象来指示 API 调用的结果。

  • onResult() 回调表示已成功创建或更新自定义受众群体。
  • onError() 回调表示两种可能的情况。

下面是一个关于处理 joinCustomAudience() 结果的示例:

Kotlin

var callback: OutcomeReceiver<Void, AdServicesException> =
    object : OutcomeReceiver<Void, AdServicesException> {
    override fun onResult(result: Void) {
        Log.i("CustomAudience", "Completed joinCustomAudience")
    }

    override fun onError(error: AdServicesException) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error)
    }
};

Java

OutcomeReceiver callback = new OutcomeReceiver<Void, AdServicesException>() {
    @Override
    public void onResult(@NonNull Void result) {
        Log.i("CustomAudience", "Completed joinCustomAudience");
    }

    @Override
    public void onError(@NonNull AdServicesException error) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error);
    }
};

退出自定义受众群体

如果用户不再符合给定自定义受众群体的商家标准,应用或 SDK 可以调用 leaveCustomAudience() 从设备中移除自定义受众群体。如需根据其唯一参数移除 CustomAudience,请执行以下操作:

  1. 初始化 CustomAudienceManager 对象。
  2. 使用自定义受众群体的 buyername 初始化 LeaveCustomAudienceRequest。如需详细了解这些输入字段,请参阅加入自定义受众群体
  3. 使用 LeaveCustomAudienceRequest 对象及相关的 ExecutorOutcomeReceiver 对象调用异步 leaveCustomAudience() 方法。

Kotlin

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a LeaveCustomAudienceRequest
val leaveCustomAudienceRequest: LeaveCustomAudienceRequest =
    JoinCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build()

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver)

Java

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a LeaveCustomAudienceRequest
LeaveCustomAudienceRequest leaveCustomAudienceRequest =
    new JoinCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build();

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver);

与调用 joinCustomAudience() 类似,OutcomeReceiver 会发出信号来表明 API 调用已结束。为了帮助保护隐私,错误结果不区分内部错误和无效参数。当 API 调用完成后,无论是否已成功移除匹配的自定义受众群体,系统都会调用 onResult() 回调。

运行广告选择

如需使用 FLEDGE 选择广告,请调用 selectAds() 方法:

  1. 初始化 AdSelectionManager 对象。
  2. 构建 AdSelectionConfig 对象。
  3. 使用 AdSelectionConfig 对象及相关的 ExecutorOutcomeReceiver 对象调用异步 selectAds() 方法。

Kotlin

val adSelectionManager: AdSelectionManager =
    context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionConfig
val adSelectionConfig: AdSelectionConfig =
        AdSelectionConfig.Builder()
                .setSeller(seller)
                .setDecisionLogicUrl(decisionLogicUrl)
                .setCustomAudienceBuyers(customAudienceBuyers)
                .setAdSelectionSignals(adSelectionSignals)
                .setSellerSignals(sellerSignals)
                .setPerBuyerSignals(perBuyerSignals)
                .build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionConfig,
    executor,
    outcomeReceiver)

Java

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionConfig
AdSelectionConfig adSelectionConfig =
        new AdSelectionConfig.Builder()
                .setSeller(seller)
                .setDecisionLogicUrl(decisionLogicUrl)
                .setCustomAudienceBuyers(customAudienceBuyers)
                .setAdSelectionSignals(adSelectionSignals)
                .setSellerSignals(sellerSignals)
                .setPerBuyerSignals(perBuyerSignals)
                .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionConfig,
    executor,
    outcomeReceiver);

selectAds() 方法需要 AdSelectionConfig 输入,您必须在该输入中指定以下必需参数:

  • 卖方:发起广告选择的卖方广告网络的标识符。
  • 决策逻辑网址:为获取卖方广告网络的 JavaScript 逻辑而查询的 HTTPS 网址。查看此 JavaScript 中必需的函数签名
  • 自定义受众群体买方:卖方允许参与广告选择流程的买方广告网络标识符的完整列表。这些买方标识符对应于参与的自定义受众群体的 CustomAudience.getBuyer()。

您可以选择性地指定以下参数,提高广告选择的定制程度:

  • 广告选择信号:已序列化为字符串的 JSON 对象,包含从 CustomAudience.getBiddingLogicUrl() 提取的买方出价逻辑 JavaScript 要使用的信号。
  • 卖方信号:已序列化为字符串的 JSON 对象,包含从 AdSelectionConfig.getDecisionLogicUrl() 提取的卖方 JavaScript 决策逻辑所使用的信号。
  • 每个买方的信号:已序列化为字符串的 JSON 对象映射,包含从 CustomAudience.getBiddingLogicUrl() 提取的特定买方出价逻辑 JavaScript 要使用的信号,这些信号通过参与的自定义受众群体的买方字段来标识。

选择广告后,结果、出价和信号将在内部保留,供日后报告之用。您将从 OutcomeReceiver.onResult() 回调中获得包含以下内容的 AdSelectionOutcome

  • 胜出的广告的呈现网址,从 AdData.getRenderUrl() 获取。
  • 设备用户独有的广告选择 ID。此 ID 用于报告广告展示次数。

如果广告选择因参数无效、超时或资源消耗过多等原因而无法成功完成,OutcomeReceiver.onError() 回调会以如下行为抛出 AdServicesException

  • 如果使用无效参数发起广告选择,会收到 AdServicesException,表明 IllegalArgumentException 是错误原因。
  • 所有其他错误会收到 AdServicesException,以 IllegalStateException 为错误原因。

报告广告展示次数

通过广告选择工作流程选择胜出的广告后,您可以使用 AdSelectionManager.reportImpression() 方法向参与的买方和卖方平台报告展示次数。如需报告广告展示次数,请执行以下操作:

  1. 初始化 AdSelectionManager 对象。
  2. 使用广告选择 ID 构建 ReportImpressionRequest 对象。
  3. 使用 AdSelectionConfig 对象及相关的 ExecutorOutcomeReceiver 对象调用异步 reportImpression() 方法。

Java

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportImpressionRequest
ReportImpressionRequest adSelectionConfig =
        new ReportImpressionRequest.Builder()
                .setAdSelectionId(adSelectionId)
                .setAdSelectionConfig(adSelectionConfig);
                .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver);

Kotlin

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize a ReportImpressionRequest
val adSelectionConfig: ReportImpressionRequest =
    ReportImpressionRequest.Builder()
        .setAdSelectionId(adSelectionId)
        .setAdSelectionConfig(adSelectionConfig);
        .build()

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver)

使用以下必需参数初始化 ReportImpressionRequest

  • 广告选择 ID:设备用户独有的唯一 ID,用于标识成功的广告选择。
  • 广告选择配置selectAds() 调用中使用的相同配置,以提供的广告选择 ID 标识。

异步 reportImpression() 方法使用 OutcomeReceiver 对象来指示 API 调用的结果。

  • onResult() 回调指示广告选择是否已完成。
  • onError() 回调表示以下可能的情况:
    • 如果使用无效输入参数初始化调用,会收到 AdServicesException,表明 IllegalArgumentException 是错误原因。
    • 所有其他错误会收到 AdServicesException,以 IllegalStateException 为错误原因。

展示次数报告端点

报告展示次数 API 将向卖方平台提供的端点和胜出的买方平台提供的端点发出 HTTPS GET 请求:

买方平台端点:

  • 该 API 将使用自定义受众群体中指定的出价逻辑网址来提取买方的出价逻辑 JavaScript。
  • 调用 reportResult() JavaScript 函数,该函数应返回买方的展示次数报告网址。

卖方平台端点:

  • 使用 AdSelectionConfig 对象中指定的决策逻辑网址来提取卖方的决策逻辑 JavaScript。
  • 调用 reportWin() JavaScript 函数,该函数应返回买方的展示次数报告网址。

尽最大努力报告展示次数

reportImpression() 旨在尽最大努力完成报告。

每日后台更新

创建自定义受众群体时,您的应用或 SDK 可以初始化自定义受众群体元数据。此外,平台还可以通过每日后台更新进程更新以下自定义受众群体元数据。

  • 用户出价信号
  • 可信出价数据
  • AdData 列表

此进程会查询自定义受众群体中定义的每日更新网址,该网址可能会返回 JSON 响应。

  • JSON 响应可能包含任何支持且需要更新的元数据字段。
  • 每个 JSON 字段都会进行独立验证。客户端会忽略任何格式错误的字段,这种情况将导致响应中的特定字段不更新。
  • HTTP 响应为空或 JSON 对象“{}”为空将导致元数据无法更新。
  • 响应消息的大小不得超过 10 KB。
  • 所有 URI 都必须使用 HTTPS。
  • trusted_bidding_uri 必须与买方位于同一个 ETLD+1 下。

示例:后台每日更新的 JSON 响应

{
    "user_bidding_signals" : { ... },  // Valid JSON object
    "trusted_bidding_data" : {
        "trusted_bidding_uri" : 'example-dsp1-key-value-service.com',
        "trusted_bidding_keys" : [ 'campaign123', 'campaign456', ... ]
    },
    'ads' : [
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign123.html',
            'metadata' : { ... }  // Valid JSON object
        },
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign456.html',
            'metadata' : { ... }  // Valid JSON object
        },
        ...
    ]
}

用于广告选择的 JavaScript

广告选择工作流程会编排买方提供和卖方提供的 JavaScript 的执行。

买方提供的 JavaScript 从自定义受众群体中指定的出价逻辑网址中提取。返回的 JavaScript 应包含以下函数:

卖方提供的 JavaScript 是从广告选择 API 的 AdSelectionConfig 参数中指定的决策逻辑网址中提取的。返回的 JavaScript 应包含以下函数:

generateBid()

function generateBid(
  ad,
  auction_signals,
  per_buyer_signals,
  trusted_bidding_signals,
  contextual_signals,
  user_signals,
  custom_audience_signals) {
  return {'status': 0, 'ad': ad, 'bid': ad.metadata.result };
}

输入参数:

  • ad:具有以下格式变量的 JSON 对象:ad = { 'render_url': url, 'metadata': json_metadata }
  • auction_signals, per_buyer_signals:在竞价配置对象中指定的 JSON 对象
  • custom_audience_signals:平台生成的 JSON 对象。此 JSON 对象的格式如下:

    var custom_audience_signals = {
      "owner":"ca_owner",
      "buyer":"ca_buyer",
      "name":"ca_name",
      "activation_time":"ca_activation_time_epoch_ms",
      "expiration_time":"ca_expiration_time_epoch_ms",
      "user_bidding_signals":"ca_user_bidding_signals"
    }
    

    其中:

    • owner, buyername 是从参与广告选择的自定义受众群体的同名属性中获取的字符串
    • activation_timeexpiration_time 是自定义受众群体的启用时间和到期时间,以自 Unix 公元纪年以来的秒数表示
    • ca_user_bidding_signals 是创建 CustomAudience 时在其 userBiddingSignals 字段中指定的 JSON 字符串
    • trusted_bidding_signals, contextual_signalsuser_signals 是 JSON 对象,目前作为空对象传递,在未来的版本中会进行填充。其格式并非由平台强制执行,而是由广告技术平台进行管理。

结果:

  • ad:是出价所涉及的广告。允许该脚本返回其所收到的具有不同元数据的广告副本。广告的 render_url 属性应保持不变。
  • bid:表示此广告出价金额的浮点值
  • status:一个整数值,其具体值可为:
    • 0:表示执行成功
    • 1(或任何非零值):如果有任何输入信号无效。如果生成出价返回非零值,那么所有 CA 广告的出价流程都会失效

scoreAd()

function scoreAd(
  ad,
  bid,
  ad_selection_config,
  seller_signals,
  trusted_scoring_signals,
  contextual_signal,
  user_signal,
  custom_audience_signal) {
    return {'status': 0, 'score': score };
}

输入参数:

  • ad:请参阅 generateBid 文档
  • bid:广告的出价金额
  • ad_selection_config:一个 JSON 对象,表示 selectAds API 的 AdSelectionConfig 参数。格式如下:

    var ad_selection_config = {
      'seller': 'seller',
      'decision_logic_url': 'url_of_decision_logic',
      'custom_audience_buyers': ['buyer1', 'buyer2'],
      'auction_signals': auction_signals,
      'per_buyer_signals': per_buyer_signals,
      'contextual_ads': [ad1, ad2]
    }
    
  • seller_signals:从 sellerSignals AdSelectionConfig API 参数读取的 JSON 对象

  • trusted_scoring_signal:读取自 AdSelectionConfig API 参数中的 adSelectionSignals 字段

  • contextual_signals, user_signals:JSON 对象,目前作为空对象传递,在未来的版本中会进行填充。其格式并非由平台强制执行,而是由广告技术平台进行管理

  • per_buyer_signals:从 AdSelectionConfig API 参数的 perBuyerSignal 映射中读取的 JSON 对象,用作当前自定义受众群体买方的键。如果映射不包含任何给定买方的条目,则为空。

输出:

  • score:表示此广告得分值的浮点值
  • status:一个整数值,其具体值可为:
    • 0:表示执行成功
    • 1:如果 customAudienceSignals 无效
    • 2:如果 AdSelectionConfig 无效
    • 3:如果任何其他信号无效
    • 任何非零值都会导致流程失败,该值会决定抛出的异常类型

reportResult()

function reportResult(ad_selection_config, render_url, bid, contextual_signals) {
   return {
      'status': status,
      'results': {'signals_for_buyer': signals_for_buyer, 'reporting_url': reporting_url }
   };
}

输入参数:

  • ad_selection_config:请参阅 scoreAds 的文档
  • render_url:胜出的广告的呈现网址
  • bid:对胜出的广告的出价
  • contextual_signals:请参阅 generateBid 的文档

输出:

  • status: 0 表示成功,非零表示失败
  • results:包含以下内容的 JSON 对象:
    • signals_for_buyer:将传递给 reportWin 函数的 JSON 对象
    • reporting_url:平台将用于向买方通知展示次数的网址

reportWin()

function reportWin(
   ad_selection_signals,
   per_buyer_signals,
   signals_for_buyer,
   contextual_signals,
   custom_audience_signals) {
   return {'status': 0, 'results': {'reporting_url': reporting_url } };
}

输入参数:

  • ad_selection_signals, per_buyer_signals:请参阅 scoreAd 的文档
  • signals_for_buyerreportResult 返回的 JSON 对象
  • contextual_signals, custom_audience_signals:请参阅 generateBid 的文档

输出:

  • status: 0 表示成功,非零表示失败
  • results:包含以下内容的 JSON 对象:
    • reporting_url:平台将用于向卖方通知展示次数的网址

测试

为了帮助您着手使用 FLEDGE,我们已使用 Kotlin 和 Java 创建了示例应用,您可以在 GitHub 上找到这些应用。

前提条件

在广告选择和展示报告过程中,FLEDGE 需要一些 JavaScript。 您可以通过两种方法在测试环境中提供此 JavaScript:

  • 运行具有所需 JavaScript 端点的服务器来返回 JavaScript
  • 通过提供来自本地来源的必要代码来替换远程提取

这两种方法都需要设置 HTTPS 端点来处理展示报告。

HTTPS 端点

如需测试广告选择和展示次数报告,您需要设置 7 个可通过测试设备或模拟器进行访问的 HTTPS 端点:

  1. 提供出价逻辑 JavaScript 的买方端点。
  2. 提供出价信号的端点。
  3. 提供决策逻辑 JavaScript 的卖方端点。
  4. 提供评分信号的端点。
  5. 胜出的买方的展示次数报告端点。
  6. 卖方的展示次数报告端点。
  7. 用于为自定义受众群体提供每日更新的端点。

为方便起见,GitHub 代码库提供用于测试的基本 JavaScript 代码。它还包含 OpenAPI 服务定义,您可将这些定义部署到受支持的模拟或微服务平台。如需了解详情,请参阅项目自述文件

替换 JavaScript 的远程提取

此功能旨在用于端到端测试。如需替换远程提取,您的应用必须在启用开发者选项的调试模式下运行。

如需为您的应用启用调试模式,请将以下行添加到 AndroidManifest.xml 的应用属性中:

<application
  android:debuggable="true">

如需查看如何使用这些替换项的示例,请参阅 GitHub 上的 FLEDGE 示例应用

您需要自行添加自定义 JavaScript 来处理广告选择例程(例如出价、评分决策和报告)。您可以在 GitHub 代码库中找到处理所有必需请求的基本 JavaScript 代码示例。FLEDGE 示例应用演示了如何从该文件中读取代码并将其准备好用作替换项。

您可以自行独立替换卖方和买方 JavaScript 提取,但您可能并未为一些 JavaScript 提供替换项,这就需要通过 HTTPS 端点来处理这些 JavaScript。如需了解如何设置服务器以处理这些情况,请参阅自述文件

只能替换您的软件包拥有的自定义受众群体的 JavaScript 提取。

替换卖方 JavaScript

如需设置卖方 JavaScript 替换项,请按照以下代码示例操作:

  1. 初始化 AdSelectionManager 对象。
  2. AdSelectionManager 对象获取对 TestAdSelectionManager 的引用。
  3. 构建 AdSelectionConfig 对象。
  4. 使用 AdSelectionConfig 对象和 String(表示您计划用作替换项的 JavaScript)构建 AddAdSelectionOverrideRequest
  5. 使用 AddAdSelectionOverrideRequest 对象及相关的 ExecutorOutcomeReceiver 对象调用异步 overrideAdSelectionConfigRemoteInfo() 方法。

Kotlin

val testAdSelectionManager: TestAdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java).getTestAdSelectionManager()

// Initialize AdSelectionConfig =
val adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build()

// Initialize AddAddSelectionOverrideRequest
val request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build()

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver)

Java

TestAdSelectionManager testAdSelectionManager =
  context.getSystemService(AdSelectionManager.class).getTestAdSelectionManager();

// Initialize AdSelectionConfig =
AdSelectionConfig adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build();

// Initialize AddAddSelectionOverrideRequest
AddAdSelectionOverrideRequest request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build();

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver);

如需详细了解 AdSelectionConfig 中的每个字段的含义,请参阅运行广告选择部分。关键区别在于,可以将 decisionLogicUrl 设置为占位值,因为该值将被忽略。

为了替换广告选择过程中使用的 JavaScript,decisionLogicJs 必须包含适当的卖方函数签名。如需查看如何以字符串形式读取 JavaScript 文件的示例,请参阅 GitHub 上的 FLEDGE 示例应用

异步 overrideAdSelectionConfigRemoteInfo() 方法使用 OutcomeReceiver 对象来指示 API 调用的结果。

onResult() 回调表示已成功应用替换。对 selectAds() 的后续调用将使用您传入作为替换项的任何决策和报告逻辑。

onError() 回调表示两种可能的情况:

  • 如果尝试使用无效参数进行替换,会收到 AdServiceException,表明 IllegalArgumentException 是错误原因。
  • 如果尝试对未在启用开发者选项的调试模式下运行的应用进行替换,会收到 AdServiceException,表明 IllegalStateException 是错误原因。

重置卖方替换项

本部分假定您已经替换了卖方 JavaScript,并且您已经引用上一部分中所使用的 TestAdSelectionManagerAdSelectionConfig

如需重置所有 AdSelectionConfigs 的替换项,请执行以下操作:

  1. 使用相关 OutcomeReceiver 对象调用异步 resetAllAdSelectionConfigRemoteOverrides() 方法。

Kotlin

// Resets overrides for all AdSelectionConfigs
testAadSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
  outComeReceiver)

Java

// Resets overrides for all AdSelectionConfigs
testAdSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
    outComeReceiver);

重置卖方替换项后,对 selectAds() 的调用将使用存储在 AdSelectionConfig 中的任何 decisionLogicUrl 来尝试获取所需的 JavaScript。

如果对 resetAllAdSelectionConfigRemoteOverrides() 的调用失败,OutComeReceiver.onError() 回调将抛出 AdServiceException。 如果尝试为未在启用开发者选项的调试模式下运行的应用移除替换项,会收到 AdServiceException,表明 IllegalStateException 是错误原因。

替换买方 JavaScript

  1. 按照相应步骤加入自定义受众群体
  2. 构建要用作替换项的出价逻辑和数据,并使用要替换的自定义受众群体的买方名称构建 AddCustomAudienceOverrideRequest
  3. 使用 AddCustomAudienceOverrideRequest 对象及相关的 ExecutorOutcomeReceiver 对象调用异步 overrideCustomAudienceRemoteInfo() 方法

Kotlin

val testCustomAudienceManager: TestCustomAudienceManager =
  context.getSystemService(CustomAudienceManager::class.java).getTestCustomAudienceManager()

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
val request = AddCustomAudienceOverrideRequest.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setBiddingLogicJs(biddingLogicJS)
    .setTrustedBiddingSignals(trustedBiddingSignals)
    .build()

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver)

Java

TestCustomAudienceManager testCustomAudienceManager =
  context.getSystemService(CustomAudienceManager.class).getTestCustomAudienceManager();

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
AddCustomAudienceOverrideRequest request =
    AddCustomAudienceOverrideRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .setBiddingLogicJs(biddingLogicJS)
        .setTrustedBiddingSignals(trustedBiddingSignals)
        .build();

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver);

买方名称的值就是创建自定义受众群体时所使用的值。详细了解这些字段

此外,您还可以另外指定两个参数:

  • biddingLogicJs:此 JavaScript 包含要在广告选择过程中使用的买方逻辑。查看此 JavaScript 中必需的函数签名
  • trustedBiddingSignals:在广告选择过程中使用的出价信号。为便于测试,它可以是空字符串。

异步 overrideCustomAudienceRemoteInfo() 方法使用 OutcomeReceiver 对象来指示 API 调用的结果。

onResult() 回调表示已成功应用替换。对 selectAds() 的后续调用将使用您传入作为替换项的任何出价和报告逻辑。

onError() 回调表示两种可能的情况。

  • 如果尝试使用无效参数进行替换,会收到 AdServiceException,表明 IllegalArgumentException 是错误原因。
  • 如果尝试对未在启用开发者选项的调试模式下运行的应用进行替换,会收到 AdServiceException,表明 IllegalStateException 是错误原因。

重置买方替换项

本部分假定您已经替换了买方 JavaScript,并且您已经引用上一部分中所使用的 TestCustomAudienceManager

如需重置所有自定义受众群体的替换项,请执行以下操作:

  1. 使用相关的 ExecutorOutcomeReceiver 对象调用异步 resetAllCustomAudienceOverrides() 方法。

Kotlin

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

Java

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

重置买方替换项后,对 selectAds() 的后续调用将使用存储在 CustomAudience 中的 biddingLogicUrltrustedBiddingData 来尝试获取所需的 JavaScript。

如果对 resetCustomAudienceRemoteInfoOverride() 的调用失败,OutComeReceiver.onError() 回调将抛出 AdServiceException。如果尝试为未在启用开发者选项的调试模式下运行的应用移除替换项,会收到 AdServiceException,表明 IllegalStateException 是错误原因。

设置报告服务器

使用远程提取替换项时,您仍然需要设置一个服务器,以便设备或模拟器访问该服务器来响应报告事件。返回 200 的简单端点足以满足测试需求。GitHub 代码库包含 OpenAPI 服务定义,您可将这些定义部署到受支持的模拟或微服务平台。如需了解详情,请参阅项目自述文件

在查找 OpenAPI 定义时,请查找 reporting-server.json。 此文件包含一个可返回 200(代表 HTTP 响应代码)的简单端点。在 selectAds() 期间,此端点用于向 FLEDGE 发送展示报告已成功完成的信号。

需要测试的功能

  • 根据之前的用户操作,加入或退出和设置自定义受众群体。
  • 通过远程托管的 JavaScript 在设备上启动广告选择。
  • 观察应用与自定义受众群体设置之间的关联如何影响广告选择结果。
  • 在广告选择完成后,进行展示次数报告。

限制

下表列出了有关 FLEDGE 处理的限制。显示的限制可能会根据反馈而发生变化。如需了解正在开发中的功能,请参阅版本说明

组件 限制说明 限制值
自定义受众群体 (CA) 每个 CA 的广告数量上限 100
每个应用的 CA 数量上限 1000
可以创建 CA 的应用数量上限 1000
从创建时间算起的 CA 启用时间延迟上限 60 天
从启用时间算起的 CA 有效期上限 60 天
设备上的 CA 数量上限 4000
CA 名称的大小上限 200 个字节
每日提取 URI 的大小上限 400 个字节
出价逻辑 URI 的大小上限 400 个字节
可信出价数据的大小上限 10 KB
用户出价信号的大小上限 10 KB
每个买方的 leaveCustomAudience 调用率上限 每秒 1 次
每个买方的 joinCustomAudience 调用率上限 每秒 1 次
CA 后台提取 连接超时 5 秒
HTTP 读取超时 30 秒
总下载大小上限 10 KB
提取迭代的时长上限 5 分钟
每个作业更新的 CA 数量上限 1000
广告选择 买方数量上限 待定
每个买方的 CA 数量上限 待定
参与竞价的广告数量上限 待定
初始连接超时 5 秒
连接读取超时 5 秒
整个 AdSelection 的执行时间上限 10 秒
AdSelection 期间每个 CA 的出价执行时间上限 5 秒
AdSelection 期间的评分执行时间上限 5 秒
AdSelection 期间每个买方的执行时间上限 待定
广告选择/卖方/每个买方信号的大小上限 待定
卖方/买方脚本的大小上限 待定
selectAds 的调用率上限 1 QPS
展示次数报告 从保留类型中移除广告选择前的最短时间 24 小时
存储空间广告选择的数量上限 待定
报告输出网址的大小上限 待定
展示次数报告的时间上限 待定
通知调用的重试次数上限 待定
连接超时 5 秒
reportImpression 的总执行时长上限 2 秒
reportImpressions 的调用率上限 1 QPS
广告 广告列表的大小上限 根据上下文,所有 AdData 在单个 CA 中的总大小上限为 10 KB
网址 作为输入接受的任何网址字符串的长度上限 待定
JavaScript 执行时间上限 展示次数报告的出价和评分执行时间上限为 1 秒
使用的内存上限 10 MB

报告 bug 和问题

您的反馈对 Privacy Sandbox on Android 至关重要!如果发现任何问题或有任何关于改进 Privacy Sandbox on Android 的想法,欢迎告诉我们。