自定义受众群体代表一组由广告主应用确定出的具有共同意向或兴趣的用户。应用或 SDK 可使用自定义受众群体来指示特定受众群体,例如在购物车中添加商品却未结账的用户。
Android Protected Audience API 可用于加入和退出用户设备上的自定义受众群体。创建和加入自定义受众群体时,您可以委托给服务器,从中提取部分或全部自定义受众群体属性,也可以直接调用 API 时指定此信息。
自定义受众群体
以下参数的组合可以让设备上的每个 CustomAudience
对象具有唯一标识:
owner
:所有者应用的软件包名称。该参数会隐式设置为调用方应用的软件包名称。buyer
:买方广告网络的标识符(此广告网络负责管理面向此自定义受众群体的广告)。name
:自定义受众群体的任意名称或标识符。
此外,必须使用以下必需参数创建 CustomAudience
:
- 每日更新网址:每天在后台查询的 HTTPS 网址,用于更新自定义受众群体的用户出价信号、可信出价数据以及广告的呈现网址和元数据。
- 出价逻辑网址:在广告选择过程中查询的 HTTPS 网址,用于提取买方的 JavaScript 出价逻辑。查看此 JavaScript 中必需的函数签名。
- 广告呈现 ID:买方广告技术平台设置的任意 ID。这是针对 B&A 生成载荷的优化。
CustomAudience
对象的可选参数可以包括:
- 启用时间:自定义受众群体只能在其启用时间之后参与广告选择和每日更新。设置此参数有助于吸引已流失的应用用户。
- 到期时间:未来的某个时间,超过此时间后,自定义受众群体会从设备中移除。
- 用户出价信号:一个 JSON 字符串,包含买方的出价逻辑 JavaScript 会使用的用户信号(例如用户的首选语言区域),用于在广告选择流程中生成出价。此格式有助于广告技术平台跨平台重复使用代码并简化 JavaScript 函数的使用。
- 可信出价数据:广告选择流程中使用的 HTTPS 网址和字符串列表,用于从可信的键值对服务中提取出价信号。
- 广告:与要参与广告选择的广告对应的
AdData
对象列表。每个AdData
对象都包含:- 呈现网址:为呈现最终广告而查询的 HTTPS 网址。
- 元数据:已序列化为字符串的 JSON 对象,包含买方出价逻辑在广告选择流程中要使用的信息。
- AdFilters:是一个类,其中包含用于在广告选择过程中过滤应用安装广告以及控制广告展示频次不超过频次上限的所有必要信息。
提取和加入自定义受众群体
借助 fetchAndJoinCustomAudience
API,买家可以利用其设备端存在的合作伙伴 MMP 或 SSP 来委托加入自定义受众群体。
为此,设备端调用方(无论是 MMP SDK 还是 SSP SDK)会创建一个如下所示的 fetchAndJoinCustomAudienceRequest
:
/**
* @param fetchUri The URL to retrieve the CA from.
* (optional)@param name The name of the CA to join.
* (optional)@param activationTime The time when the CA will activate.
* (optional)@param expirationTime The time when the CA will expire,
must be a time in the future otherwise this will fail
* (optional)@param userBiddingSignals The user bidding signals used at auction.
*/
val request = FetchAndJoinCustomAudienceRequest.Builder(fetchUri)
.setName(name)
.setActivationTime(activationTime)
.setExpirationTime(expirationTime)
.setUserBiddingSignals(userBiddingSignals)
.build()
/**
* @param fetchUri The URL to retrieve the CA from.
* (optional)@param name The name of the CA to join.
* (optional)@param activationTime The time when the CA will activate.
* (optional)@param expirationTime The time when the CA will expire,
must be a time in the future otherwise this will fail
* (optional)@param userBiddingSignals The user bidding signals used at auction.
*/
FetchAndJoinCustomAudienceRequest request =
new FetchAndJoinCustomAudienceRequest.Builder(fetchUri)
.setName(name) //Optional
.setActivationTime(activationTime) //Optional
.setExpirationTime(expirationTime) //Optional
.setUserBiddingSignals(userBiddingSignals) //Optional
.build();
关于所有可选参数的重要说明:如果这些参数在提取请求内设置,它们的数据就无法被从买家返回的内容替换,从而让设备端调用方可以更好地控制哪些自定义受众群体将保持不变。
fetchUri
应指向由买家运营的服务器端点,该端点将返回与此处所示格式匹配的自定义受众群体 JSON 对象:
//Return a 200 response with data matching the format of the following in the body
{
"daily_update_uri": "https://js.example.com/bidding/daily",
"bidding_logic_uri": "https://js.example.com/bidding",
"user_bidding_signals": {
"valid": true,
"arbitrary": "yes"
},
"trusted_bidding_data": {
"trusted_bidding_uri": "https://js.example.com/bidding/trusted",
"trusted_bidding_keys": [
"key1",
"key2"
]
},
"ads": [
{
"render_uri": "https://js.example.com/render/fetch_and_join_ad1",
"metadata": {
"valid": 1
}
},
{
"render_uri": "https://js.example.com/render/fetch_and_join_ad2",
"metadata": {
"valid": 2
}
}
]
}
如需详细了解如何在 API 端解析,请参阅设计提案以加入自定义受众群体委托。
测试
在客户端代码中实现了 Fetch 调用并在 DSP 端设置了端点以返回自定义受众群体数据后,您就可以测试加入自定义受众群体的委托。在运行应用之前,您需要在测试设置页面上运行命令。运行这些命令后,您应该就能够开始使用 Fetch API 成功进行调用了。
我们已将提取调用添加到 GitHub 上 Privacy Sandbox 示例仓库中,您可以将其作为此流程的示例进行参阅。
直接加入自定义受众群体
如果您已经拥有创建和加入自定义受众群体所需的所有信息,则可以直接使用异步 Protected Audience API 调用来创建和加入自定义受众群体。如需直接创建或加入自定义受众群体,请执行以下操作:
- 初始化
CustomAudienceManager
对象。 - 通过指定买方软件包和相关名称等关键参数来创建
CustomAudience
对象。然后,使用CustomAudience
对象初始化JoinCustomAudienceRequest
对象。 - 使用
JoinCustomAudienceRequest
对象及相关的Executor
和OutcomeReceiver
对象调用异步joinCustomAudience()
。
val customAudienceManager: CustomAudienceManager =
context.getSystemService(CustomAudienceManager::class.java)
// Minimal initialization of a CustomAudience object
val audience: 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()
// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()
// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
executor,
outcomeReceiver)
CustomAudienceManager customAudienceManager =
context.getSystemService(CustomAudienceManager.class);
// Minimal initialization of a CustomAudience object
CustomAudience audience = 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();
// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();
// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
executor,
outcomeReceiver);
处理 joinCustomAudience() 结果
异步 joinCustomAudience()
方法使用 OutcomeReceiver
对象来指示 API 调用的结果。
onResult()
回调表示已成功创建或更新自定义受众群体。onError()
回调表示两种可能的情况。- 如果使用无效参数初始化
JoinCustomAudienceRequest
,则会收到AdServicesException
,表明IllegalArgumentException
是错误原因。 - 所有其他错误会收到
AdServicesException
,以IllegalStateException
为错误原因。
- 如果使用无效参数初始化
下面是一个关于处理 joinCustomAudience()
结果的示例:
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)
}
};
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
,请执行以下操作:
- 初始化
CustomAudienceManager
对象。 - 使用自定义受众群体的
buyer
和name
初始化LeaveCustomAudienceRequest
。如需详细了解这些输入字段,请参阅直接加入自定义受众群体。 - 使用
LeaveCustomAudienceRequest
对象及相关的Executor
和OutcomeReceiver
对象调用异步leaveCustomAudience()
方法。
val customAudienceManager: CustomAudienceManager =
context.getSystemService(CustomAudienceManager::class.java)
// Initialize a LeaveCustomAudienceRequest
val leaveCustomAudienceRequest: LeaveCustomAudienceRequest =
LeaveCustomAudienceRequest.Builder()
.setBuyer(buyer)
.setName(name)
.build()
// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
leaveCustomAudienceRequest,
executor,
outcomeReceiver)
CustomAudienceManager customAudienceManager =
context.getSystemService(CustomAudienceManager.class);
// Initialize a LeaveCustomAudienceRequest
LeaveCustomAudienceRequest leaveCustomAudienceRequest =
new LeaveCustomAudienceRequest.Builder()
.setBuyer(buyer)
.setName(name)
.build();
// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
leaveCustomAudienceRequest,
executor,
outcomeReceiver);
与调用 joinCustomAudience()
类似,OutcomeReceiver
会发出信号来表明 API 调用已结束。为了帮助保护隐私,错误结果不区分内部错误和无效参数。当 API 调用完成后,无论是否已成功移除匹配的自定义受众群体,系统都会调用 onResult()
回调。