Entwicklerleitfaden für die Protected Audience API

Verwenden Sie beim Lesen der Dokumentation zur Privacy Sandbox für Android die Schaltfläche Entwicklervorschau oder Beta, um die Programmversion auszuwählen, mit der Sie arbeiten. Die Anleitung kann variieren.


Die Protected Audience API auf Android (früher FLEDGE) umfasst die Custom Audience API und die Ad Selection API. AdTech-Plattformen und Werbetreibende können diese APIs verwenden, um interessenspezifische Anzeigen basierend auf vorherigen App-Interaktionen auszuliefern. Dadurch wird die Freigabe von Kennungen zwischen Apps eingeschränkt und die Weitergabe von App-Interaktionsinformationen eines Nutzers an Dritte wird eingeschränkt.

Die Custom Audience API dreht sich um die Abstraktion „benutzerdefinierte Zielgruppe“, die eine Gruppe von Nutzern mit gemeinsamen Absichten darstellt. Ein Werbetreibender kann einen Nutzer bei einer benutzerdefinierten Zielgruppe registrieren und dieser relevante Anzeigen zuordnen. Diese Informationen werden lokal gespeichert und können für Gebote von Werbetreibenden, für die Anzeigenfilterung und das Anzeigen-Rendering verwendet werden.

Die Ad Selection API bietet ein Framework, mit dem mehrere Entwickler lokal eine Auktion für eine benutzerdefinierte Zielgruppe durchführen können. Dazu berücksichtigt das System relevante Anzeigen, die mit der benutzerdefinierten Zielgruppe verknüpft sind, und führt eine zusätzliche Verarbeitung der Anzeigen durch, die eine Anzeigentechnologieplattform an das Gerät zurückgibt.

Anzeigentechnologie-Plattformen können diese APIs einbinden, um Remarketing zu implementieren, das die Privatsphäre der Nutzer schützt. Für zukünftige Releases ist die Unterstützung weiterer Anwendungsfälle, einschließlich Anzeigen für App-Installationen, geplant. Weitere Informationen zur Protected Audience API für Android finden Sie im Designvorschlag.

In dieser Anleitung wird beschrieben, wie Sie die Protected Audience API auf Android-Geräten verwenden, um Folgendes zu tun:

  1. Benutzerdefinierte Zielgruppen verwalten
  2. Anzeigenauswahl auf einem Gerät einrichten und ausführen
  3. Berichte zu Anzeigenimpressionen erstellen

Hinweis

Führen Sie die folgenden Schritte aus, bevor Sie beginnen:

  1. Richten Sie Ihre Entwicklungsumgebung für die Privacy Sandbox für Android ein.
  2. Sie können entweder ein System-Image auf einem unterstützten Gerät installieren oder einen Emulator einrichten, der die Privacy Sandbox auf Android unterstützt.
  3. Aktivieren Sie in einem Terminal den Zugriff auf die Protected Audience API (standardmäßig deaktiviert) mit dem folgenden ADB-Befehl.

      adb shell device_config put adservices ppapi_app_allow_list \"*\"
    
  4. Aktivieren Sie in einem Terminal die Beacon-Berichterstellung mit den folgenden ADB-Befehlen.

     adb shell device_config put adservices fledge_beacon_reporting_metrics_enabled true
     adb shell device_config put adservices fledge_register_ad_beacon_enabled true
    
  5. Fügen Sie Ihrem App-Manifest die Berechtigung ACCESS_ADSERVICES_CUSTOM_AUDIENCE hinzu:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE" />
    
  6. Verweisen Sie im <application>-Element Ihres Manifests auf eine Konfiguration für Anzeigendienste:

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
                android:resource="@xml/ad_services_config" />
    
  7. Geben Sie die XML-Ressource für Anzeigendienste an, auf die in Ihrem Manifest verwiesen wird, z. B. res/xml/ad_services_config.xml. Weitere Informationen zu Berechtigungen für Anzeigendienste und zur SDK-Zugriffssteuerung

      <ad-services-config>
        <custom-audiences allowAllToAccess="true" />
      </ad-services-config>
    
  8. Standardmäßig schränkt die Ad Selection API den maximalen Arbeitsspeicher ein, der einem Script für Auktions- oder Impressionsberichte zugewiesen werden kann. Für die Speicherbeschränkung ist die WebView-Version 105.0.5195.58 oder höher erforderlich. Die Plattform erzwingt eine Versionsprüfung und Aufrufe der selectAds- und reportImpression-APIs schlagen fehl, wenn diese nicht erfüllt ist. Es gibt zwei Möglichkeiten, dies einzurichten:

    • Option 1: Deaktivieren Sie diese Prüfung mit dem folgenden adb-Befehl:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • Option 2: WebView Beta aus dem Google Play Store installieren Dieser Wert muss gleich oder höher als die zuvor angegebene Version sein.

Einer benutzerdefinierten Zielgruppe beitreten

Eine benutzerdefinierte Zielgruppe ist eine Gruppe von Nutzern mit gemeinsamen Absichten oder Interessen, die von der App eines Werbetreibenden festgelegt werden. Eine App oder ein SDK kann eine benutzerdefinierte Zielgruppe verwenden, um eine bestimmte Zielgruppe anzugeben, z. B. eine Person, die Artikel in einem Einkaufswagen gelassen hat. So erstellen oder verknüpfen Sie eine benutzerdefinierte Zielgruppe asynchron:

  1. Initialisieren Sie das Objekt CustomAudienceManager.
  2. Erstelle ein CustomAudience-Objekt, indem du Schlüsselparameter wie das Paket des Käufers und einen relevanten Namen angibst. Initialisieren Sie dann das JoinCustomAudienceRequest-Objekt mit dem CustomAudience-Objekt.
  3. Rufe die asynchrone joinCustomAudience() mit dem JoinCustomAudienceRequest-Objekt und den entsprechenden Executor- und OutcomeReceiver-Objekten auf.

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);

Durch die Kombination der folgenden Parameter wird jedes CustomAudience-Objekt auf einem Gerät eindeutig identifiziert:

  • owner: Paketname der Eigentümer-App. Dieser wird implizit auf den Paketnamen der aufrufenden App festgelegt.
  • buyer: Kennung für das Werbenetzwerk des Käufers, über das Anzeigen für diese benutzerdefinierte Zielgruppe verwaltet werden.
  • name: Ein beliebiger Name oder eine beliebige Kennung für die benutzerdefinierte Zielgruppe.

Wenn Sie joinCustomAudience() wiederholt mit einer anderen Instanz von CustomAudience aufrufen, werden alle vorhandenen CustomAudience mit übereinstimmenden owner, buyer- und name-Parametern aktualisiert. Zum Schutz der Privatsphäre wird im Ergebnis der API nicht zwischen „Erstellung“ und „Aktualisierung“ unterschieden.

Außerdem muss die CustomAudience mit den folgenden erforderlichen Parametern erstellt werden:

  • URL für tägliche Updates: Eine HTTPS-URL, die täglich im Hintergrund abgefragt wird, um die Signale für Nutzergebote und vertrauenswürdige Gebotsdaten einer benutzerdefinierten Zielgruppe zu aktualisieren sowie URLs und Metadaten für Anzeigen zu rendern.
  • URL für die Gebotslogik: Eine HTTPS-URL, die während der Anzeigenauswahl abgefragt wird, um die JavaScript-Gebotslogik eines Käufers abzurufen. Die erforderlichen Funktionssignaturen finden Sie in diesem JavaScript.
  • Anzeigen-Render-IDs: Eine beliebige ID, die von der Anzeigentechnologie des Käufers festgelegt wird. Dies ist eine Optimierung für die Generierung der Nutzlast für B&A.

Optionale Parameter für ein CustomAudience-Objekt können Folgendes umfassen:

  • Aktivierungszeit: Eine benutzerdefinierte Zielgruppe kann erst nach der Aktivierung an der Anzeigenauswahl und täglichen Aktualisierungen teilnehmen. Das kann beispielsweise nützlich sein, um inaktive Nutzer einer App zu erreichen.
  • Ablaufzeit: Eine Zeit, nach der die benutzerdefinierte Zielgruppe vom Gerät entfernt wird.
  • Gebotssignale für Nutzer: Ein JSON-String mit Nutzersignalen, z. B. der bevorzugten Sprache des Nutzers, die vom JavaScript-Code für die Gebotslogik eines Käufers verwendet wird, um bei der Anzeigenauswahl Gebote zu generieren. Dieses Format ermöglicht es AdTech-Plattformen, Code plattformübergreifend wiederzuverwenden und die Verwendung in JavaScript-Funktionen zu vereinfachen.
  • Vertrauenswürdige Gebotsdaten: Eine HTTPS-URL und eine Liste von Strings, die bei der Anzeigenauswahl verwendet werden, um Gebotssignale von einem vertrauenswürdigen Schlüssel/Wert-Paardienst abzurufen.
  • Anzeigen: Eine Liste von AdData-Objekten, die den Anzeigen entsprechen, die zur Anzeigenauswahl gehören. Jedes AdData-Objekt besteht aus:
    • Render-URL: Eine HTTPS-URL, die zum Rendern der finalen Anzeige abgefragt wird.
    • Metadaten: Ein JSON-Objekt, das als String serialisiert ist und Informationen enthält, die von der Gebotslogik des Käufers während der Anzeigenauswahl abgerufen werden.
    • Anzeigenfilter: Eine Klasse, die alle erforderlichen Informationen für die Installation von Anzeigenfiltern und die Häufigkeitsbeschränkung bei der Anzeigenauswahl enthält.

Hier ein Beispiel für die Objektinstanziierung von 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()-Ergebnisse verarbeiten

Bei der asynchronen Methode joinCustomAudience() wird das Objekt OutcomeReceiver verwendet, um das Ergebnis des API-Aufrufs zu signalisieren.

  • Der Callback onResult() zeigt an, dass die benutzerdefinierte Zielgruppe erstellt oder aktualisiert wurde.
  • Der onError()-Callback steht für zwei mögliche Bedingungen.

Hier ein Beispiel für die Verarbeitung des Ergebnisses von 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);
    }
};

Benutzerdefinierte Zielgruppe verlassen

Wenn der Nutzer die Geschäftskriterien für eine bestimmte benutzerdefinierte Zielgruppe nicht mehr erfüllt, kann eine App oder ein SDK leaveCustomAudience() aufrufen, um die benutzerdefinierte Zielgruppe vom Gerät zu entfernen. So entfernen Sie eine CustomAudience anhand ihrer eindeutigen Parameter:

  1. Initialisieren Sie das Objekt CustomAudienceManager.
  2. Initialisieren Sie LeaveCustomAudienceRequest mit buyer und name der benutzerdefinierten Zielgruppe. Weitere Informationen zu diesen Eingabefeldern finden Sie unter Benutzerdefinierte Zielgruppen zusammenführen.
  3. Rufen Sie die asynchrone leaveCustomAudience()-Methode mit dem LeaveCustomAudienceRequest-Objekt und den relevanten Executor- und OutcomeReceiver-Objekten auf.

Kotlin

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)

Java

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);

Ähnlich wie beim Aufrufen von joinCustomAudience() signalisiert OutcomeReceiver das Ende eines API-Aufrufs. Aus Datenschutzgründen wird bei einem Fehlerergebnis nicht zwischen internen Fehlern und ungültigen Argumenten unterschieden. Der onResult()-Callback wird aufgerufen, wenn der API-Aufruf abgeschlossen ist, unabhängig davon, ob eine übereinstimmende benutzerdefinierte Zielgruppe erfolgreich entfernt wurde.

Anzeigenauswahl ausführen

Wenn Sie Anzeigen mit der Protected Audience API auswählen möchten, rufen Sie die Methode selectAds() auf:

  1. Initialisieren Sie ein AdSelectionManager-Objekt.
  2. Erstellen Sie ein AdSelectionConfig-Objekt.
  3. Rufen Sie die asynchrone selectAds()-Methode mit dem AdSelectionConfig-Objekt und den relevanten Executor- und OutcomeReceiver-Objekten auf.

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)
    .setBuyerContextualAds(
      Collections.singletonMap(
        contextualAds.getBuyer(), contextualAds
      )
    ).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)
    .setBuyerContextualAds(
      Collections.singletonMap(contextualAds.getBuyer(), contextualAds)
    )
    .build();

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

Für die Methode selectAds() ist eine AdSelectionConfig-Eingabe erforderlich, in der Sie die folgenden erforderlichen Parameter angeben müssen:

  • Verkäufer: ID des Verkäufer-Werbenetzwerks, mit dem die Anzeigenauswahl initiiert wird.
  • URL der Entscheidungslogik: Eine HTTPS-URL, über die die JavaScript-Logik des Werbenetzwerks des Verkäufers abgerufen wird.
    • HTTPS-URL: Wird abgefragt, um die JavaScript-Logik des Verkäufer-Werbenetzwerks zu erhalten. Erforderliche Funktionssignaturen
    • Vordefinierter URI: entspricht dem Format für die Anzeigenauswahl von FLEDGE. IllegalArgumentException wird geworfen, wenn ein nicht unterstützter oder fehlerhafter vordefinierter URI übergeben wird.
  • Käufer mit benutzerdefinierten Zielgruppen: Eine vollständige Liste der IDs für Käufer-Werbenetzwerke, die vom Verkäufer zur Teilnahme am Anzeigenauswahlprozess zugelassen sind. Diese Käufer-IDs entsprechen CustomAudience.getBuyer() der teilnehmenden benutzerdefinierten Zielgruppen.

Für eine individuellere Anzeigenauswahl können Sie optional die folgenden Parameter angeben:

  • Signale für die Anzeigenauswahl: Ein JSON-Objekt, das als String serialisiert ist und Signale enthält, die von der JavaScript-Gebotslogik des Käufers verarbeitet werden, die von CustomAudience.getBiddingLogicUrl() abgerufen wird.
  • Verkäufersignale: Ein JSON-Objekt, das als String serialisiert ist und Signale enthält, die von der vom Verkäufer abgerufenen JavaScript-Entscheidungslogik aus AdSelectionConfig.getDecisionLogicUrl() verwendet werden.
  • Signale pro Käufer: Eine Zuordnung von JSON-Objekten, die als Strings serialisiert sind und Signale enthalten, die von der JavaScript-Gebotslogik bestimmter Käufer verwendet werden. Sie werden aus CustomAudience.getBiddingLogicUrl() abgerufen und anhand der Käuferfelder der teilnehmenden benutzerdefinierten Zielgruppen identifiziert.
  • Kontextbezogene Anzeigen: Eine Sammlung von Anzeigenkandidaten, die während einer Auktion direkt von Käufern erfasst werden, die nicht für eine Auktion mit geschützten Zielgruppen gilt.

Sobald eine Anzeige ausgewählt wurde, werden die Ergebnisse, Gebote und Signale intern für die Berichterstellung gespeichert. Der OutcomeReceiver.onResult()-Callback gibt ein AdSelectionOutcome zurück, das Folgendes enthält:

  • Eine Rendering-URL für die erfolgreiche Anzeige, die von AdData.getRenderUrl() abgerufen wurde.
  • Eine eindeutige Anzeigenauswahl-ID für den Gerätenutzer. Diese ID wird für die Berichterstellung zur Anzeigenimpression verwendet.

Wenn die Anzeigenauswahl aus Gründen wie ungültigen Argumenten, Zeitüberschreitungen oder übermäßigem Ressourcenverbrauch nicht abgeschlossen werden kann, enthält der OutcomeReceiver.onError()-Callback eine AdServicesException mit den folgenden Verhaltensweisen:

  • Wenn die Anzeigenauswahl mit ungültigen Argumenten gestartet wird, gibt AdServicesException IllegalArgumentException als Ursache an.
  • Bei allen anderen Fehlern wird AdServicesException mit IllegalStateException als Ursache zurückgegeben.

Kontextbasierte Anzeigen

Mit Protected Audience können kontextbezogene Anzeigen in eine Protected Audience-Auktion einbezogen werden. Kontextbezogene Anzeigen müssen auf dem AdTech-Server ausgewählt und außerhalb der Protected Audience APIs an das Gerät zurückgegeben werden. Kontextbezogene Anzeigen können dann über das AdSelectionConfig in die Auktion einbezogen werden. Dann funktionieren sie genauso wie Anzeigen auf Geräten, einschließlich der Berechtigung für die ausschließende Anzeigenfilterung. Sobald die Auktion für geschützte Zielgruppen abgeschlossen ist, müssen Sie reportImpression() aufrufen. Dadurch wird reportWin() in der ausgelieferten kontextbezogenen Anzeige aufgerufen, und zwar nach demselben Muster wie bei Impressionsberichten, um die ausgelieferte Anzeige auf einem Gerät zu empfangen. Für jede kontextbezogene Anzeige sind ein Käufer, ein Gebot, ein Link zur Berichtslogik, eine Rendering-URL und Anzeigenmetadaten erforderlich.

Damit kontextbezogene Anzeigen in der App bereitgestellt werden können, muss die Ziel-App ein ContextualAds-Objekt erstellen:

Kotlin

val contextualAds: ContextualAds =
  Builder().setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
    //Pass in your valid app install ads
    .setDecisionLogicUri(mContextualLogicUri)
    .setAdsWithBid(appInstallAd)
    .build()

Java

ContextualAds contextualAds = new ContextualAds.Builder()
  .setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
  .setDecisionLogicUri(mContextualLogicUri)
  //Pass in your valid app install ads
  .setAdsWithBid(appInstallAd)
  .build();

Das resultierende ContextualAds-Objekt kann dann beim Erstellen des AdSelectionConfig übergeben werden:

Kotlin

// Create a new ad
val noFilterAd: AdData = Builder()
  .setMetadata(JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build()
val noFilterAdWithBid = AdWithBid(noFilterAd, NO_FILTER_BID)
contextualAds.getAdsWithBid().add(noFilterAdWithBid)

Java

// Create a new ad
AdData noFilterAd = new AdData.Builder()
  .setMetadata(new JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build();
AdWithBid noFilterAdWithBid = new AdWithBid(noFilterAd, NO_FILTER_BID);
contextualAds.getAdsWithBid().add(noFilterAdWithBid);

App-Installationsanzeigen filtern

Mit dem Filter für App-Installationsanzeigen können Sie Installationsanzeigen für Apps filtern, die bereits auf einem Gerät installiert sind.

Als Erstes legen Sie fest, welche Werbetreibenden das installierte Paket filtern können. Dies muss in der App geschehen, auf die Sie eine Anzeige ausrichten möchten.

Kotlin

//Create a request for setting the app install advertisers
val adtech = AdTechIdentifier.fromString("your.enrolled.uri")
val adtechSet = setOf(adtech)
val request = SetAppInstallAdvertisersRequest(adtechSet)

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  object : OutcomeReceiver<Any?, Exception?>() {
    fun onResult(@NonNull ignoredResult: Any?) {
      Log.v("[your tag]", "Updated app install advertisers")
    }

    fun onError(@NonNull error: Exception?) {
      Log.e("[your tag]", "Failed to update app install advertisers", error)
    }
  })

Java

//Create a request for setting the app install advertisers
AdTechIdentifier adtech = AdTechIdentifier.fromString("your.enrolled.uri");
Set<AdTechIdentifier> adtechSet = Collections.singleton(adtech);
SetAppInstallAdvertisersRequest request = new SetAppInstallAdvertisersRequest(adtechSet);

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  new OutcomeReceiver<Object, Exception>() {
    @Override
    public void onResult(@NonNull Object ignoredResult) {
      Log.v("[your tag]", "Updated app install advertisers");
    }

    @Override
    public void onError(@NonNull Exception error) {
      Log.e("[your tag]", "Failed to update app install advertisers", error);
    }
  });

Wenn der vorherige Code ausgeführt wird, können die übergebenen Werbetreibenden die installierten Apps herausfiltern, die Sie bei der Gebotsgenerierung angegeben haben. Wenn Sie einem Werbetreibenden den Zugriff auf den Installationsstatus dieser App entziehen möchten, führen Sie diesen Code noch einmal aus, wobei die Informationen des Werbetreibenden entfernt werden.

Der nächste Schritt besteht darin, die Anzeigenfilterung in der Publisher-App einzurichten. Der Anbieter, der die Anzeige in der Publisher-App bereitstellt (wahrscheinlich ein lieferseitiges SDK), muss sein AdFilters-Objekt mit Informationen darüber initialisieren, welche Anzeigen mit Bezug zu Apps herausgefiltert werden sollen:

Kotlin

// Instantiate AdFilters object with package names.
val filters: AdFilters = Builder().setAppInstallFilters(
    Builder().setPackageNames(setOf("example.target.app")).build()
  ).build()

Java

// Instantiate AdFilters object with package names.
AdFilters filters = new AdFilters.Builder()
.setAppInstallFilters(
  new AppInstallFilters.Builder()
  .setPackageNames(Collections.singleton("example.target.app"))
  .build())
.build();

Publisher auf der Nachfrageseite können auch eine AdFilter für Anzeigen festlegen, die in ihren benutzerdefinierten Zielgruppen enthalten sind.

AdFilters kann auch beim Instanziieren eines neuen AdData-Objekts übergeben werden:

Kotlin

// Instantiate an AdData object with the AdFilters created in the
// previous example.
val appInstallAd: AdData =
  Builder().setMetadata("{ ... }") // Valid JSON string
    .setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters).build()

Java

// Instantiate an AdData object with the AdFilters created in the
// previous example.
AdData appInstallAd = new AdData.Builder()
.setMetadata("{ ... }") // Valid JSON string
.setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters)
    .build();

Filtern nach Frequency Capping

Mit dem Frequency Capping-Filter können Anzeigentechnologien die Häufigkeit begrenzen, mit der eine Anzeige ausgeliefert wird. Durch Frequency Capping wird die übermäßige Auslieferung von Anzeigen reduziert und die Auswahl alternativer Anzeigen für eine bestimmte Werbekampagne optimiert.

Ein Filter für die Häufigkeitsobergrenze besteht aus zwei Hauptkomponenten: dem Anzeigenereignistyp und dem Anzeigenzählerschlüssel. Folgende Anzeigenereignistypen können verwendet werden:

  • Gewinn: Ein Gewinnereignis gibt an, dass die Anzeige eine Auktion gewonnen hat. Gewinnereignisse werden automatisch von der Protected Audience API aktualisiert und können nicht direkt vom Entwickler aufgerufen werden. Daten zu erfolgreichen Anzeigen sind nur für Anzeigen innerhalb einer bestimmten benutzerdefinierten Zielgruppe sichtbar.
  • Impression: Unabhängig von reportImpression verwendet ein On-Device-Aufrufer (SSP oder MMP) updateAdCounterHistogram(), um Impressionsereignisse an der von ihm ausgewählten Codestelle aufzurufen. Impressionsereignisse sind für alle Anzeigen einer bestimmten DSP sichtbar und sind nicht auf Anzeigen in derselben benutzerdefinierten Zielgruppe beschränkt.
  • Ansicht: Das Ereignis wird vom Aufrufer auf dem Gerät (SSP oder MMP) an einer Codestelle aufgerufen, die er über einen updateAdCounterHistogram()-Aufruf auswählt. Aufrufereignisse sind für alle Anzeigen einer bestimmten DSP sichtbar und nicht auf Anzeigen in derselben benutzerdefinierten Zielgruppe beschränkt.
  • Klick: Das Ereignis wird vom On-Device-Caller (SSP oder MMP) an einem beliebigen Punkt im Code durch einen Aufruf von updateAdCounterHistogram() aufgerufen. Klickereignisse sind für alle Anzeigen einer bestimmten DSP sichtbar und nicht auf Anzeigen in derselben benutzerdefinierten Zielgruppe beschränkt.

In der Publisher-App ruft eine SSP oder MMP mit einer Präsenz auf dem Gerät Anzeigenereignisse auf. Wenn updateAdCounterHistogram() aufgerufen wird, wird der Zähler eines Frequency Capping-Filters erhöht, damit für zukünftige Auktionen aktuelle Informationen zur Auslieferung einer bestimmten Anzeige an einen Nutzer vorliegen. Die Anzeigenereignistypen sind nicht zwangsläufig mit der entsprechenden Nutzeraktion verknüpft. Sie dienen als Richtlinien, die Aufrufern helfen sollen, ihr Ereignissystem zu strukturieren. Um die Anzeigenzähler zum Zeitpunkt eines Ereignisses zu erhöhen, gibt der On-Device-Akteur die Anzeigenauswahl-ID der Gewinnerwerbungs-Auktion an.

Anzeigenzählerschlüssel sind beliebige vorzeichenbehaftete 32-Bit-Ganzzahlen, die von der Anzeigentechnologie eines Käufers zugewiesen werden. Sie entsprechen einer bestimmten Gruppe von Anzeigen, die von der DSP definiert wird. Da Anzeigenzählerschlüssel nur auf Anzeigen beschränkt sind, die zu einer bestimmten DSP gehören, können diese Schlüssel ausgewählt werden, ohne dass sich die Histogramme einer anderen Anzeigentechnologie überschneiden. Anzeigen-Zählerschlüssel werden verwendet, um DSP-spezifische Kennungen für die Anzeigen einer DSP oder innerhalb einer bestimmten benutzerdefinierten Zielgruppe zu erhöhen, um Anzeigen aus zukünftigen Auktionen herauszufiltern.

Zählerschlüssel können verwendet werden, um Anzeigen zu priorisieren, die basierend auf den Interaktionen mit anderen Anzeigen einer bestimmten Anzeigentechnologie eines Käufers für einen bestimmten Nutzer mit größerer Wahrscheinlichkeit interessant sind. Ein abgeleiteter Datenpunkt ist beispielsweise eine Anzeige, die durch gewonnene Anzeigenauktionen, Aufrufe und Klicks ein hohes Engagement erzielt hat. Zur Veranschaulichung: Eine Anzeige für Golfschläger für Linkshänder könnte darauf hinweisen, dass der Nutzer nicht an Schlägern für Rechtshänder interessiert ist. Mit einem Frequency Capping-Filter für eine Zählertaste, die linkshändigen Anzeigen zugewiesen ist, können Anzeigen für rechtshänderische Schläger herausgefiltert werden.

Wenn Sie Frequency Capping in Ihrer Auktion verwenden möchten, müssen Sie zuerst KeyedFrequencyCap-Objekte erstellen, wie unten gezeigt:

Kotlin

// Value used when incrementing frequency counter
val adCounterKey = 123

// Frequency cap exceeded after 2 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 2, Duration.ofSeconds(10)
).build()

// Frequency cap exceeded after 1 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 1, Duration.ofSeconds(10)
).build()

Java

// Value used when incrementing frequency counter
int adCounterKey = 123;

// Frequency cap exceeded after 2 counts
KeyedFrequencyCap keyedFrequencyCapForImpression =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 2, Duration.ofSeconds(10)
  ).build();

// Frequency Cap exceeded after 1 counts
KeyedFrequencyCap keyedFrequencyCapForClick =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 1, Duration.ofSeconds(10)
  ).build();

Nachdem die KeyedFrequencyCap-Objekte erstellt wurden, können Sie sie an ein AdFilters-Objekt übergeben.

Kotlin

val filters: AdFilters = Builder()
  .setFrequencyCapFilters(
    Builder()
      .setKeyedFrequencyCapsForImpressionEvents(
        ImmutableObject.of(keyedFrequencyCapForImpression)
      )
      .setKeyedFrequencyCapsForClickEvents(
        ImmutableObject.of(keyedFrequencyCapForClick)
      )
  ).build()

Java

AdFilters filters = new AdFilters.Builder()
    .setFrequencyCapFilters(new FrequencyCapFilters.Builder()
        .setKeyedFrequencyCapsForImpressionEvents(
            ImmutableObject.of(keyedFrequencyCapForImpression)
        )
        .setKeyedFrequencyCapsForClickEvents(
            ImmutableObject.of(keyedFrequencyCapForClick)
        )
    ).build();

Wenn das AdFilters-Objekt mit Filtern für das Frequency Capping gefüllt ist, kann es beim Erstellen der benutzerdefinierten Zielgruppe weitergegeben werden:

Kotlin

// Initialize a custom audience.
val audience: CustomAudience = Builder()
  .setBuyer(buyer)
  .setName(name)
  .setAds(
    listOf(
      Builder()
        .setRenderUri(renderUri)
        .setMetadata(JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()
    )
  ).build()

Java

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setAds(Collections.singletonList(new AdData.Builder()
        .setRenderUri(renderUri)
        .setMetadata(new JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()))
    .build();

Wenn Filter für die Häufigkeitsobergrenze in eine benutzerdefinierte Zielgruppe implementiert werden, kann die SSP die erforderlichen Klick-, Aufruf- oder Impressionsereignisse aufrufen.

Kotlin

val callerAdTech: AdTechIdentifier = mAdSelectionConfig.getSeller()

val request: UpdateAdCounterHistogramRequest = Builder(
  adSelectionId,
  FrequencyCapFilters.AD_EVENT_TYPE_CLICK,  //CLICK, VIEW, or IMPRESSION
  callerAdTech
).build()

Java

AdTechIdentifier callerAdTech = mAdSelectionConfig.getSeller();

UpdateAdCounterHistogramRequest request =
  new UpdateAdCounterHistogramRequest.Builder(
      adSelectionId,
      FrequencyCapFilters.AD_EVENT_TYPE_CLICK, //CLICK, VIEW, or IMPRESSION
      callerAdTech
).build();

Anzeigen, die die voreingestellten Filterlimits für das Frequency Capping erreicht haben, werden aus der Auktion herausgefiltert. Das Filtern erfolgt, bevor die Gebotslogik für On-Device-Auktionen ausgeführt wird und während die Nutzlast für Auktionen von Gebots- und Auktionsdiensten generiert wird.Dieses Toolkit gibt Anzeigentechnologie-Experten die Flexibilität, die Interaktionen zwischen Nutzern und den Anzeigen innerhalb ihrer benutzerdefinierten Zielgruppen zu nutzen, um das Anzeigen-Targeting zu optimieren und gleichzeitig die übermäßige Anzeigenauslieferung zu minimieren.

Kontextbezogenes Anzeigen-Filtern ohne Netzwerkaufrufe

Wenn auf dem Gerät keine Remarketing-Nachfrage besteht, können Sie die Anzeigenauswahl für kontextbezogene Anzeigen ohne Netzwerkaufrufe ausführen. Mit vordefinierten URIs und einer Liste von kontextbezogenen Anzeigen mit Geboten muss die Plattform das Abrufen von Gebotslogik, Gebotssignalen und Bewertungssignalen überspringen. Die Plattform verwendet einen vordefinierten URI, um die kontextbezogene Anzeige mit dem höchsten Gebot auszuwählen.

Um die Latenz zu verbessern, können Anzeigentechnologien einen Ablauf für die Anzeigenauswahl verwenden, der nur kontextbezogene Anzeigen mit Anzeigenfilterfunktion ohne Netzwerkaufrufe enthält. Dazu werden vordefinierte URIs für die Signalbewertung verwendet. Eine Liste der Implementierungen von scoreAds finden Sie im Abschnitt Unterstützte vordefinierte URI-Anwendungsfälle und -Namen.

So führen Sie die Anzeigenauswahl ohne Netzwerkaufrufe aus:

  1. Anzeigenfilter einrichten
  2. Kontextbezogene Anzeigen erstellen
  3. Erstellen Sie ein AdSelectionConfig-Objekt mit Folgendem:

    1. Eine leere Käuferliste
    2. Ein vordefinierter URI, um das höchste Gebot auszuwählen
    3. Kontextbasierte Anzeigen
    4. Ein leerer URI für die Bewertungssignale. Mit einem leeren URI können Sie angeben, dass Sie das Abrufen vertrauenswürdiger Signale nicht für die Bewertung verwenden möchten:
    Uri prebuiltURIScoringUri = Uri.parse("ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=your.registered.uri/reporting");
    // Initialize AdSelectionConfig
    AdSelectionConfig adSelectionConfig =
      new AdSelectionConfig.Builder()
        .setSeller(seller)
        .setDecisionLogicUri(prebuiltURIScoringUri)
        .setCustomAudienceBuyers(Collections.emptyList())
        .setAdSelectionSignals(adSelectionSignals)
        .setSellerSignals(sellerSignals)
        .setPerBuyerSignals(perBuyerSignals)
        .setBuyerContextualAds(buyerContextualAds)
        .setTrustedScoringSignalsUri(Uri.EMPTY)
        .build();
    
  4. Anzeigenauswahl ausführen:

    adSelectionManager.selectAds(
        adSelectionConfig,
        executor,
        outcomeReceiver);
    

Eigenes JavaScript für die Berichterstellung mit vordefinierten URIs ausführen

Derzeit ist auf der Privacy Sandbox-Plattform nur eine grundlegende JavaScript-Implementierung für Berichte für vordefinierte URIs verfügbar. Wenn Sie Ihr eigenes JavaScript für die Berichterstellung ausführen und dabei vordefinierte URIs für eine Anzeigenauswahl mit niedriger Latenz nutzen möchten, können Sie die DecisionLogicUri zwischen der Anzeigenauswahl und Berichterstellungsausführungen überschreiben.

  1. Schritte zur Anzeigenauswahl für kontextbezogene Anzeigen mithilfe vordefinierter URIs ausführen
  2. Kopie der AdSelectionConfig erstellen, bevor Berichte erstellt werden

    adSelectionConfigWithYourReportingJS = adSelectionConfig.cloneToBuilder()
      // Replace <urlToFetchYourReportingJS> with your own URL:
      .setDecisionLogicUri(Uri.parse(<urlToFetchYourReportingJS>))
      .build();
    
  3. Impressionsberichte erstellen

    // adSelectionId is from the result of the previous selectAds run
    ReportImpressionRequest request = new ReportImpressionRequest(
      adSelectionId,
      adSelectionConfigWithYourReportingJS);
    adSelectionManager.reportImpression(
      request,
      executor,
      outcomeReceiver);
    

Vermittlungsabfolge ausführen

Bei der Wasserfall-Vermittlung müssen mehrere Drittanbieter-SDKs (Drittanbieter-Werbenetzwerke) von einem Erstanbieter-SDK-Vermittlungsnetzwerk orchestriert werden. Die abfolgebasierte Vermittlung erfolgt auf die gleiche Weise, unabhängig davon, ob die Auktion auf dem Gerät oder über Bidding & Auction Services (B&A) stattgefunden hat.

Drittanbieternetzwerke

Drittanbieternetzwerke müssen einen Adapter bereitstellen, mit dem das Vermittlungsnetzwerk die erforderlichen Methoden zum Ausführen einer Auktion aufrufen kann:

  • Anzeigenauswahl ausführen
  • Impressionen erfassen

Hier ein Beispiel für einen Adapter für ein Vermittlungsnetzwerk:

Kotlin

class NetworkAdaptor {
    private val adSelectionManager : AdSelectionManager

    init {
        adSelectionManager = context.getSystemService(AdSelectionManager::class.java)
    }

    fun selectAds() {...}

    fun reportImpressions() {...}
}

Java

class NetworkAdaptor {
    AdSelectionManager adSelectionManager;

    public NetworkAdaptor() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void selectAds() {...}

    public void reportImpressions() {...}
}

Jedes SDK hat eigene Dienstmanager und ‑kunden für die Anzeigenauswahl sowie eigene selectAds- und reportImpressions-Implementierungen. SDK-Anbieter finden weitere Informationen in den Abschnitten zur Anzeigenauswahl für On-Device-Auktionen oder in der Erläuterung zu B&A für B&A-Auktionen. So legen Sie Berichte zu Anzeigenimpressionen fest (anhand der Berichterstellung zu Impressionen für einzelne SSPs).

Vermittlungsnetzwerk

Ähnlich wie bei Drittanbieter-Netzwerken müssen Vermittlungsnetzwerke selectAds und reportImpression implementiert werden. Weitere Informationen finden Sie in den Abschnitten Anzeigenauswahl durchführen und Berichte zu Anzeigenimpressionen erstellen.

Vermittlungsnetzwerke sind dafür verantwortlich, die Vermittlungskette auszuführen und in diese zu platzieren. Im nächsten Abschnitt erfahren Sie, wie Sie diesen Prozess einrichten und ausführen.

Vermittlungskette und Gebotsuntergrenzen abrufen

Das Vermittlungsnetzwerk ist für das Abrufen der selbst erhobenen (1P) kontextbezogenen Anzeigen, der Vermittlungskette und der Gebotsuntergrenzen (3P) von Drittanbieternetzwerken verantwortlich. Das kann bei einer Anfrage zum Abrufen kontextbezogener Anzeigen passieren, die vom Vermittlungsnetzwerk ausgeführt wurden. Die Vermittlungskette bestimmt, wie die Drittanbieternetzwerke durchlaufen werden, und die Mindestpreise können als adSelectionSignals an den Auktionsprozess übergeben werden.

Werbenetzwerk-Placement in der Vermittlungskette

Ein Vermittlungs-SDK kann sich basierend auf dem Live-eCPM der eigenen Anzeigengebote in die Vermittlungskette einfügen. In der Protected Audience API sind Anzeigengebote nicht transparent. Ein Mediation-SDK sollte AdSelectionFromOutcomesConfig verwenden, um das Gebot einer bestimmten Anzeigenanzeige vom Typ „Eigenwerbung“ mit dem Mindestgebot des nächsten Drittanbieternetzwerks in der Vermittlungskette zu vergleichen. Wenn das eigene Gebot über dem Mindestpreis liegt, wird das Mediation SDK vor diesem Drittanbieternetzwerk platziert.

Anzeigenauswahl ausführen

Um einen Anzeigenkandidaten aus selbst erhobenen Daten abzurufen, kann das Vermittlungsnetzwerk eine On-Device-Auktion ausführen. Folgen Sie dazu der Anleitung im Abschnitt Anzeigenauswahl ausführen. Dadurch werden ein Anzeigenkandidat aus selbst erhobenen Daten, ein Gebot und ein AdSelectionId generiert, die im Vermittlungsprozess verwendet werden.

AdSelectionFromOutcomesConfig erstellen

Mit einem AdSelectionFromOutcomesConfig kann das Vermittlungsnetzwerk eine Liste von AdSelectionIds (Ergebnisse aus vorherigen Auktionen), Signale zur Anzeigenauswahl und einen URI zum Abrufen von JavaScript übergeben, mit dem eine Anzeige aus mehreren Kandidaten ausgewählt wird. Die Liste der AdSelectionIds zusammen mit ihren Geboten und Signalen wird an das JavaScript übergeben. Dieses kann AdSelectionIds zurückgeben, wenn es den Mindestpreis übertrifft, oder keine, wenn die Vermittlungskette fortgesetzt werden soll.

Vermittlungsnetzwerke erstellen eine AdSelectionFromOutcomesConfig mithilfe der AdSelectionId aus dem vorherigen Abschnitt und des Mindestgebots für das Drittanbieternetzwerk, das berücksichtigt werden soll. Für jeden Schritt in der Vermittlungskette sollte eine neue AdSelectionFromOutcomesConfig erstellt werden.

Kotlin

fun  runSelectOutcome(
    adSelectionClient : AdSelectionClient,
    outcome1p : AdSelectionOutcome,
    network3p : NetworkAdapter) : ListenableFuture<AdSelectionOutcome?> {
    val config = AdSelectionFromOutcomesConfig.Builder()
        .setSeller(seller)
        .setAdSelectionIds(listOf(outcome1p))
        .setSelectionSignals({"bid_floor": bid_floor})
        .setSelectionLogicUri(selectionLogicUri)
        .build()
    return adSelectionClient.selectAds(config)
}

Java

public ListenableFuture<AdSelectionOutcome> runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) {
    AdSelectionFromOutcomesConfig config = new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .build();

    return adSelectionClient.selectAds(config){}
}

Für das Überschreiben der selectAds()-Methode für die abfolgebasierte Vermittlung ist eine AdSelectionFromOutcomesConfig-Eingabe erforderlich, in der Sie die folgenden erforderlichen Parameter angeben müssen:

  • Verkäufer: ID des Verkäufer-Werbenetzwerks, mit dem die Anzeigenauswahl initiiert wird.
  • Anzeigenauswahl-IDs: Eine einzelne Liste einer vorherigen selectAds()-Ausführung für eine selbst erhobenen Anzeige.
  • Signale für die Anzeigenauswahl: Ein JSON-Objekt, das als String serialisiert ist und Signale enthält, die von der Gebotslogik des Käufers verwendet werden. Geben Sie in diesem Fall den Mindestgebotentwert an, der für das jeweilige Drittanbieternetzwerk abgerufen wurde.
  • URI der Auswahllogik: Eine HTTPS-URL, die während der Anzeigenauswahl abgefragt wird, um das JavaScript des Vermittlungsnetzwerks zur Auswahl einer Anzeigenauslieferung abzurufen. Die erforderlichen Funktionssignaturen finden Sie in diesem JavaScript. Das JavaScript sollte die Drittanbieteranzeige zurückgeben, wenn das Gebot über dem Mindestpreis liegt. Andernfalls wird null zurückgegeben. So kann das Mediation SDK die Vermittlungskette kürzen, wenn ein Gewinner gefunden wird.

Rufe nach dem Erstellen von AdSelectionOutcomesConfig die selectAds()-Methode des Drittanbieternetzwerks auf, das zuerst in der Kette steht.

Kotlin

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

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
  AdSelectionFromOutcomesConfig.Builder()
    .setSeller(seller)
    .setAdSelectionIds(listof(outcome1p))
    .setSelectionSignals({"bid_floor": bid_floor})
    .setSelectionLogicUri(selectionLogicUri)
    .setAdSelectionIds(outcomeIds)
    .build()

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

Java

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

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
        new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .setAdSelectionIds(outcomeIds)
            .build();

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

Vermittlungsabfolge orchestrieren

Im Folgenden wird die Reihenfolge der Vorgänge für die Vermittlung beschrieben.

  1. Anzeigenauswahl für selbst erhobene Daten ausführen
  2. Für die Vermittlungskette iterieren. Gehen Sie für jedes Drittanbieternetzwerk so vor:
    1. Erstellen Sie AdSelectionFromOutcomeConfig unter Berücksichtigung des outcomeId für selbst erhobene Daten und des Gebotsgrenzwerts des Drittanbieter-SDKs.
    2. Rufen Sie selectAds() mit der Konfiguration aus dem vorherigen Schritt auf.
    3. Wenn das Ergebnis nicht leer ist, geben Sie die Anzeige zurück.
    4. Rufen Sie die Methode selectAds() des aktuellen SDK-Netzwerkadapters auf. Wenn das Ergebnis nicht leer ist, geben Sie die Anzeige zurück.
  3. Wenn in der Kette kein Gewinner gefunden wird, geben Sie die selbstverwaltete Anzeige zurück.

Kotlin

fun runWaterfallMediation(mediationChain : List<NetworkAdapter>)
  : Pair<AdSelectionOutcome, NetworkAdapter> {
    val outcome1p = runAdSelection()

    var outcome : AdSelectionOutcome
    for(network3p in mediationChain) {
      outcome = runSelectOutcome(outcome1p, network3p)
      if (outcome1p.hasOutcome() && outcome.hasOutcome()) {
          return Pair(outcome, this)
      }

      outcome = network3p.runAdSelection()
      if(outcome.hasOutcome()) {
          return Pair(outcome, network3p)
      }
    }
  return Pair(outcome1p, this)
}

Java

class MediationNetwork {
    AdSelectionManager adSelectionManager;

    public MediationNetwork() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void runAdSelection() {...}

    public void reportImpressions() {...}

    public Pair<AdSelectionOutcome, NetworkAdapter> runWaterfallMediation(
            List<NetworkAdapter> mediationChain) {
        AdSelectionOutcome outcome1p = runAdSelection();

        AdSelectionOutcome outcome;
        for(NetworkAdapter network3p: mediationChain) {
            if (outcome1p.hasOutcome() &&
              (outcome = runSelectOutcome(outcome1p, network3p)).hasOutcome()) {
                return new Pair<>(outcome, this);
            }

            if((outcome = network3p.runAdSelection()).hasOutcome()) {
                return new Pair<>(outcome, network3p);
            }
        }
        return new Pair<>(outcome1p, this);
    }

    /* Runs comparison by creating an AdSelectionFromOutcomesConfig */
    public AdSelectionOutcome runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) { ... }
}

Anzeigenimpressionen melden

Je nachdem, wie die Auktion durchgeführt wird, gibt es zwei Abläufe für die Erfassung einer Anzeigenimpression. Wenn Sie eine einzelne SSP haben, die eine Auktion durchführt, folgen Sie der Anleitung in diesem Abschnitt. Wenn Sie die abfolgebasierte Vermittlung implementieren möchten, folgen Sie der Anleitung im Abschnitt zu Berichten zu Impressionen bei der abfolgebasierten Vermittlung.

Berichte zu Impressionen bei einer einzelnen SSP

Nachdem im Workflow zur Anzeigenauswahl eine erfolgreiche Anzeige ausgewählt wurde, können Sie die Impression mit der Methode AdSelectionManager.reportImpression() an die teilnehmenden Plattformen auf Käufer- und Verkäuferseite zurückmelden. So melden Sie eine Anzeigenimpression:

  1. Initialisieren Sie ein AdSelectionManager-Objekt.
  2. Erstellen Sie ein ReportImpressionRequest-Objekt mit der Anzeigenauswahl-ID.
  3. Rufen Sie die asynchrone reportImpression()-Methode mit dem Objekt ReportImpressionRequest und den entsprechenden Executor- und OutcomeReceiver-Objekten auf.

Java

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

// Initialize a ReportImpressionRequest
ReportImpressionRequest reportImpressionRequest =
        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)

Initialisieren Sie ReportImpressionRequest mit den folgenden erforderlichen Parametern:

  • Anzeigenauswahl-ID: Diese ID ist nur für einen Gerätenutzer eindeutig und dient zur Identifizierung einer erfolgreichen Anzeigenauswahl.
  • Konfiguration der Anzeigenauswahl: Dies ist die im selectAds()-Aufruf verwendete Konfiguration, die durch die angegebene Anzeigenauswahl-ID identifiziert wird.

Bei der asynchronen Methode reportImpression() wird das Objekt OutcomeReceiver verwendet, um das Ergebnis des API-Aufrufs zu signalisieren.

  • Der onResult()-Callback zeigt an, ob URLs für Impressionsberichte erstellt und die Anfrage geplant wurde.
  • Der onError()-Callback zeigt die folgenden möglichen Bedingungen an:
    • Wenn der Aufruf mit einem ungültigen Eingabeargument initialisiert wird, gibt AdServicesException IllegalArgumentException als Ursache an.
    • Für alle anderen Fehler wird ein AdServicesException mit IllegalStateException als Ursache angezeigt.

Impressionsberichte zur abfolgebasierten Vermittlung

Ein Mediation SDK muss das erfolgreiche SDK im Blick behalten, um die Berichterstellung auszulösen. Die SDKs, die an einer Vermittlungskette teilnehmen, sollten eine Methode für den Vermittler bereitstellen, mit der er seinen eigenen Berichtsablauf auslösen kann. Wenn Sie ein SDK verwenden, das an einer vermittelten Auktion teilnimmt, können Sie die oben genannten Schritte ausführen, um eigene Berichte zu implementieren.

SSPs können dieses Beispiel für Drittanbieter-SDK-Code als Prototyp verwenden, um Mediationsabläufe zu verknüpfen:

Pair<AdSelectionOutcome, NetworkAdapter> winnerOutcomeAndNetwork =
         mediationSdk.orchestrateMediation(mediationChain);

if (winner.first.hasOutcome()) {
      winner.second.reportImpressions(winner.first.getAdSelectionId());

Endpunkte für Berichte zu Impressionen

Die Report Impression API gibt HTTPS-GET-Anfragen an Endpunkte aus, die von der Sell-Side-Plattform und der erfolgreichen Buy-Side-Plattform bereitgestellt werden:

Endpunkt der Buy-Side-Plattform:

  • Die API verwendet die in der benutzerdefinierten Zielgruppe angegebene URL der Gebotslogik, um das vom Käufer bereitgestellte JavaScript abzurufen, das eine Logik zum Zurückgeben einer URL für Impressionsberichte enthält.
  • Rufen Sie die JavaScript-Funktion reportWin() auf, die voraussichtlich die URL der Impressionsberichte des Käufers zurückgibt.

Endpunkt der Sell-Side-Plattform:

  • Verwenden Sie die im AdSelectionConfig-Objekt angegebene URL der Entscheidungslogik, um das JavaScript der Entscheidungslogik des Verkäufers abzurufen.
  • Rufen Sie die JavaScript-Funktion reportResult() auf, die voraussichtlich die URL der Impressionsberichte des Verkäufers zurückgibt.

Berichte zu Geboten und Auktionsdiensten

Bei einer Auktion, die über Bidding & Auction Services ausgeführt wird, sind alle erforderlichen Berichtsinformationen, einschließlich generierter URLs für Berichte zu Anzeigeninteraktionen, in der verschlüsselten Antwort der serverseitigen Auktion enthalten. Wenn die Antwort entschlüsselt wird, werden die entsprechenden URLs bei der Plattform registriert. Für Anzeigen- und Impressionsberichte gelten daher die oben aufgeführten Schritte.

Best-Effort-Impressionsberichte

Die Methode reportImpression() ist so konzipiert, dass Berichte nach dem Best-Effort-Prinzip erstellt werden.

Anzeigeninteraktionen melden

Mit Protected Audience können Sie detailliertere Berichte zu Interaktionen für eine gerenderte Anzeige erstellen. Dazu gehören Interaktionen wie Aufrufzeit, Klicks, Mouseovers und andere nützliche Messwerte, die erfasst werden können. Um diese Berichte zu erhalten, sind zwei Schritte erforderlich. Käufer und Verkäufer müssen sich zuerst registrieren, um diese Berichte in ihrem JavaScript-Code für Berichte zu erhalten. Dann muss der Kunde diese Ereignisse melden.

Registrierung für Interaktionsereignisse

Die Registrierung für Interaktionsereignisse erfolgt in den JavaScript-Funktionen reportWin() und reportResult() des Käufers über eine von der Plattform bereitgestellte JavaScript-Funktion: registerAdBeacon. Wenn Sie sich für den Empfang eines Ereignisberichts registrieren möchten, rufen Sie einfach die JavaScript-Funktion der Plattform aus Ihrem Berichts-JavaScript auf. Im folgenden Snippet wird die reportWin() eines Käufers verwendet, derselbe Ansatz gilt jedoch auch für reportResult().

reportWin(
  adSelectionSignals,
  perBuyerSignals,
  signalsForBuyer,
  contextualSignals,
  customAudienceSignals) {
    ...
    // Calculate reportingUri, clickUri, viewUri, and hoverUri

    registerAdBeacon({"click": clickUri, "view": viewUri, "hover": hoverUri});

    return reportingUri;
}

Interaktionsereignisse erfassen

Nachdem eine Impression erfasst wurde, können Kunden die Interaktionen mit der Methode AdSelectionManager.reportInteraction() an zuvor registrierte erfolgreiche Buy-Side- und Sell-Side-Plattformen zurückmelden. So melden Sie ein Anzeigenereignis:

  1. Initialisieren Sie ein AdSelectionManager-Objekt.
  2. Erstellen Sie ein ReportInteractionRequest-Objekt mit der Anzeigenauswahl-ID, dem Interaktionsschlüssel, Interaktionsdaten und dem Berichtsziel.
  3. Rufen Sie die asynchrone reportInteraction()-Methode mit dem request-Objekt und den relevanten Executor- und OutcomeReceiver-Objekten auf.
AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportInteractionRequest
ReportInteractionRequest request =
  new ReportInteractionRequest.Builder()
    .setAdSelectionId(adSelectionId)
    .setInteractionKey("view")
    .setInteractionData("{ viewTimeInSeconds : 1 }") // Can be any string
    .setReportingDestinations(
      FLAG_REPORTING_DESTINATION_BUYER | FLAG_REPORTING_DESTINATION_SELLER
    )
    .build();

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

Initialisieren Sie ReportInteractionRequest mit den folgenden erforderlichen Parametern:

  • Anzeigenauswahl-ID: Eine Anzeigenauswahl-ID, die aus einer zuvor zurückgegebenen AdSelectionOutcome abgerufen wurde.
  • Interaktionsschlüssel: Ein vom Client definierter Stringschlüssel, der die gemeldete Aktion beschreibt. Er muss mit dem Schlüssel übereinstimmen, der vom Verkäufer oder Käufer in den JavaScript-Funktionen für die Berichterstellung registriert wurde.
  • Interaktionsdaten: Ein String mit Daten, die in den Ereignisbericht aufgenommen und per POST an die Berichtsserver gesendet werden sollen.
  • Berichtsziele: Eine Bitmaske, die angibt, ob die Ereignisse für den Käufer, den Verkäufer oder beides gemeldet werden sollen. Diese Flags werden von der Plattform bereitgestellt und die endgültige Zielmaske kann mit Bitweisen Operationen erstellt werden. Wenn Sie eine Meldung an ein Ziel senden möchten, können Sie das Flag verwenden, das von der Plattform bereitgestellt wird. Wenn Sie Berichte an mehrere Ziele senden möchten, können Sie die bitweise OR-Verknüpfung (|) verwenden, um Flag-Werte zu kombinieren.

Bei der asynchronen Methode reportInteraction() wird das Ergebnis des API-Aufrufs mithilfe des Objekts OutcomeReceiver signalisiert.

  • Der onResult()-Callback gibt an, dass der Berichtsaufruf gültig ist.
  • Der onError()-Callback gibt die folgenden möglichen Bedingungen an:
    • Wenn der Aufruf erfolgt, während die App im Hintergrund ausgeführt wird, wird IllegalStateException mit einer Beschreibung des Fehlers zurückgegeben.
    • Wenn der Client beim Aufrufen von reportInteraction() gedrosselt wird, wird LimitExceededException zurückgegeben.
    • Wenn das Paket nicht für den Aufruf der APIs zum Schutz der Privatsphäre registriert ist, wird SecurityException() zurückgegeben.
    • Wenn sich die Interaktionen der App-Berichte von der App mit dem Namen selectAds() unterscheiden, wird ein IllegalStateException zurückgegeben.
  • Wenn der Nutzer nicht zugestimmt hat, die Privacy Sandbox APIs zu aktivieren, schlägt der Aufruf stillschweigend fehl.

Endpunkte für Berichte zu Interaktionen

Die Report Interaction API sendet HTTPS-POST-Anfragen an Endpunkte, die von der Sell-Side-Plattform und der erfolgreichen Buy-Side-Plattform bereitgestellt werden. Protected Audience gleicht die Interaktionsschlüssel mit den URIs ab, die in der Berichterstellung für JavaScript deklariert sind, und sendet für jede gemeldete Interaktion eine POST-Anfrage an jeden Endpunkt. Der Inhaltstyp der Anfrage ist Nur-Text, wobei der Text die Interaktionsdaten darstellt.

Best-Effort-Interaktionsberichte

Der reportInteraction() ist so konzipiert, dass Berichte nach dem Best-Effort-Prinzip über HTTP POST eingereicht werden.

Tägliches Hintergrundupdate

Beim Erstellen einer benutzerdefinierten Zielgruppe können Ihre App oder Ihr SDK benutzerdefinierte Zielgruppenmetadaten initialisieren. Außerdem können die folgenden Metadaten für benutzerdefinierte Zielgruppen über einen täglichen Aktualisierungsprozess im Hintergrund aktualisiert werden.

  • Gebotssignale von Nutzern
  • Daten für die vertrauenswürdige Gebotseinstellung
  • AdData Liste

Dabei wird die in der benutzerdefinierten Zielgruppe definierte URL für die tägliche Aktualisierung abgefragt. Die URL kann eine JSON-Antwort zurückgeben.

  • Die JSON-Antwort kann alle unterstützten Metadatenfelder enthalten, die aktualisiert werden müssen.
  • Jedes JSON-Feld wird unabhängig geprüft. Fehlerhafte Felder werden vom Client ignoriert, sodass das jeweilige Feld in der Antwort nicht aktualisiert wird.
  • Eine leere HTTP-Antwort oder ein leeres JSON-Objekt „{}“ führt zu keinen Metadatenaktualisierungen.
  • Die Größe der Antwortnachricht muss auf 10 KB begrenzt sein.
  • Alle URIs müssen HTTPS verwenden.
  • trusted_bidding_uri muss dieselbe ETLD+1 wie der Käufer haben.

Beispiel: JSON-Antwort für ein tägliches Hintergrundupdate

{
    "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 für die Anzeigenauswahl

Der Anzeigenauswahl-Workflow koordiniert die Ausführung von vom Käufer und vom Verkäufer bereitgestelltem JavaScript.

Vom Käufer bereitgestelltes JavaScript wird von der URL für die Gebotslogik abgerufen, die in der benutzerdefinierten Zielgruppe angegeben ist. Der zurückgegebene JavaScript-Code sollte die folgenden Funktionen enthalten:

Vom Verkäufer bereitgestelltes JavaScript wird von der Entscheidungslogik-URL abgerufen, die im Parameter AdSelectionConfig für die Anzeigenauswahl-API angegeben ist. Das zurückgegebene JavaScript sollte die folgenden Funktionen enthalten:

generateBid()

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

Eingabeparameter:

  • ad: ein JSON-Objekt im Format var ad = { 'render_url': url, 'metadata': json_metadata };
  • auction_signals, per_buyer_signals: JSON-Objekte, die im Auktionskonfigurationsobjekt angegeben sind
  • custom_audience_bidding_signals: Von der Plattform generiertes JSON-Objekt. Das Format für dieses JSON-Objekt ist:

    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"
    }
    

    Dabei gilt:

    • owner, buyer und name sind Strings aus den Properties mit demselben Namen wie die benutzerdefinierte Zielgruppe, die an der Anzeigenauswahl teilnimmt.
    • activation_time und expiration_time sind die Aktivierungs- und Ablaufzeit der benutzerdefinierten Zielgruppe, ausgedrückt in Sekunden seit der Unix-Epoche.
    • ca_user_bidding_signals ist ein JSON-String, der bei der Erstellung im Feld userBiddingSignals der CustomAudience angegeben wurde.
    • trusted_bidding_signals, contextual_signals und user_signals sind JSON-Objekte. Sie werden als leere Objekte übergeben und in zukünftigen Releases ausgefüllt. Das Format wird nicht von der Plattform erzwungen und wird von der Anzeigentechnologie verwaltet.

Ergebnis:

  • ad: Die Anzeige, auf die sich das Gebot bezieht. Das Skript kann eine Kopie der empfangenen Anzeige mit unterschiedlichen Metadaten zurückgeben. Die Eigenschaft render_url der Anzeige sollte unverändert bleiben.
  • bid: ein Gleitkommawert, der den Gebotswert für diese Anzeige darstellt
  • status: ein ganzzahliger Wert, der Folgendes sein kann:
    • 0: für eine erfolgreiche Ausführung
    • 1: (oder ein beliebiger Wert ungleich Null), falls eines der Eingabesignale ungültig ist. Wenn von „generate-bid“ ein Wert ungleich Null zurückgegeben wird, wird der Gebotsvorgang für alle Kampagnenanzeigen ungültig.

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 };
}

Eingabeparameter:

  • ad: siehe generateBid-Dokumentation
  • bid: der Gebotswert für die Anzeige
  • ad_selection_config: Ein JSON-Objekt, das den Parameter AdSelectionConfig der selectAds API darstellt. Das Format dafür ist:

    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: JSON-Objekte, die aus dem API-Parameter sellerSignals AdSelectionConfig gelesen werden

  • trusted_scoring_signal: wird aus dem Feld adSelectionSignals im API-Parameter AdSelectionConfig gelesen

  • contextual_signals, user_signals: JSON-Objekte. Sie werden derzeit als leere Objekte übergeben und in zukünftigen Versionen aufgefüllt. Ihr Format wird nicht von der Plattform durchgesetzt und von der Anzeigentechnologie verwaltet.

  • per_buyer_signals: JSON-Objekt, das aus der perBuyerSignal-Zuordnung im API-Parameter AdSelectionConfig gelesen wird. Dabei wird der aktuelle Käufer der benutzerdefinierten Zielgruppe als Schlüssel verwendet. Das Feld ist leer, wenn die Karte keinen Eintrag für den angegebenen Käufer enthält.

Ausgabe:

  • score: ein Gleitkommawert, der den Punktzahlwert für diese Anzeige darstellt
  • status: Ganzzahlwert, der einen der folgenden Werte haben kann:
    • 0: für eine erfolgreiche Ausführung
    • 1: falls customAudienceSignals ungültig sind
    • 2: Wenn AdSelectionConfig ungültig ist
    • 3: Wenn eines der anderen Signale ungültig ist
    • Jeder Wert ungleich Null führt zum Abbruch des Prozesses. Der Wert bestimmt die Art der geworfenen Ausnahme.

selectOutcome()

function selectOutcome(
  outcomes,
  selection_signals) {
    return {'status': 0, 'result': null};
}

Eingabeparameter:

  • outcomes: ein JSON-Objekt {"id": id_string, "bid": bid_double}
  • selection_signals: JSON-Objekte, die im Auktionskonfigurationsobjekt angegeben sind

Ausgabe:

  • status: 0 für Erfolg, Nicht-Null für Fehler
  • result: eines der übergebenen Ergebnisse oder „null“

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 }
   };
}

Eingabeparameter:

  • ad_selection_config: siehe Dokumentation von scoreAds
  • render_url: die Rendering-URL der erfolgreichen Anzeige
  • bid: das Gebot für die Anzeige, die den Zuschlag erhalten hat
  • contextual_signals: siehe Dokumentation zu generateBid

Ausgabe:

  • status: 0 für Erfolg und ein anderer Wert für Fehler
  • results: Ein JSON-Objekt mit den folgenden Elementen:
    • signals_for_buyer: Ein JSON-Objekt, das an die Funktion reportWin übergeben wird.
    • reporting_url: Eine URL, über die die Plattform den Käufer über die Impression informiert.

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 } };
}

Eingabeparameter:

  • ad_selection_signals, per_buyer_signals: siehe Dokumentation für scoreAd
  • signals_for_buyer: Ein JSON-Objekt, das von reportResult zurückgegeben wird
  • contextual_signals, custom_audience_signals: siehe Dokumentation zu generateBid

Ausgabe:

  • status: 0 für Erfolg und nicht null für Fehler
  • results: Ein JSON-Objekt mit den folgenden Elementen:
    • reporting_url: Eine URL, die von der Plattform verwendet wird, um dem Verkäufer die Impression mitzuteilen.

registerAdBeacon()

function registerAdBeacon(
  beacons
)

Eingabeparameter:

  • beacons: Ein Objekt, das Schlüssel/Wert-Paare aus Interaktionsschlüsseln und Berichts-URIs enthält. Das Format dafür ist:

    let beacons = {
      'interaction_key': 'reporting_uri',
      'interaction_key': 'reporting_uri',
      ...
    }
    
    • interaction_key: Ein String, der das Ereignis darstellt. Er wird später von der Plattform verwendet, wenn Ereignisinteraktionen gemeldet werden, um die reporting_uri zu suchen, die benachrichtigt werden sollen. Dieser Schlüssel muss mit den Informationen, die der Käufer oder Verkäufer registriert, und den Angaben des Verkäufers übereinstimmen.
    • reporting_uri: Ein URI zum Empfangen von Ereignisberichten. Dies sollte spezifisch für den zu meldenden Ereignistyp sein. Sie muss eine POST-Anfrage akzeptieren, um alle Daten zu verarbeiten, die mit dem Ereignis gemeldet werden.

    Beispiel:

      let beacons = {
        'click': 'https://reporting.example.com/click_event',
        'view': 'https://reporting.example.com/view_event'
      }
    

Vordefinierte URIs für die Anzeigenauswahl

Mit vordefinierten URIs können Anzeigentechnologien JavaScript-Funktionen für die Entscheidungslogik für die Anzeigenauswahl in den Klassen AdSelectionConfig und AdSelectionFromOutcomesConfig einsetzen. Für vordefinierte URIs sind keine Netzwerkaufrufe zum Herunterladen des entsprechenden JavaScript-Codes erforderlich. Anbieter von Anzeigentechnologien können vordefinierte URIs verwenden, ohne eine registrierte Domain zum Hosten des JavaScripts einrichten zu müssen.

Ein vordefinierter URI wird im folgenden Format erstellt:

ad-selection-prebuilt:<use-case>/<name>?<required-script-generation-parameters>

Die Privacy Sandbox-Plattform stellt JavaScript mit den Informationen aus diesem URI in der Laufzeit bereit.

Eine IllegalArgumentException wird ausgelöst, wenn:

  • Einer der erforderlichen Parameter ist nicht im URI vorhanden
  • im URI unbekannte Parameter vorhanden sind

Unterstützte Anwendungsfälle und Namen für vordefinierte URIs

Anwendungsfall 1: Anzeigenauswahl

Vordefinierte URIs im Anwendungsfall ad-selection werden im Ablauf selectAds(AdSelectionConfig) unterstützt.

Name des vordefinierten URI: highest-bid-wins

Dieser vordefinierte URI stellt einen JavaScript-Code bereit, mit dem die Anzeige mit dem höchsten Gebot nach dem Gebot ausgewählt wird. Außerdem bietet es eine einfache Berichtsfunktion, um den render_uri und den bid des Gewinners zu melden.

Erforderliche Parameter

reportingUrl: Die grundlegende Berichts-URL, die mit render_uri und bid der erfolgreichen Anzeige parametrisiert ist:

<reportingUrl>?render_uri=<renderUriOfWinnigAd>&bid=<bidOfWinningAd>

Nutzung

Wenn Ihre grundlegende Berichts-URL https://www.ssp.com/reporting ist, wäre der vordefinierte URI:

`ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=https://www.ssp.com/reporting`

Anwendungsfall 2: „Anzeigenauswahl aus Ergebnissen“

Vordefinierte URIs für den Anwendungsfall ad-selection-from-outcomes unterstützen den Workflow selectAds(AdSelectionFromOutcomesConfig).

Name des vordefinierten URI: waterfall-mediation-truncation

Der vordefinierte URI waterfall-mediation-truncation stellt JavaScript-Code bereit, der eine Kürzungslogik der abfolgebasierten Vermittlung implementiert, bei der das JavaScript eine eigene Anzeige zurückgibt, wenn bid höher als oder gleich bid floor ist. Andernfalls wird null zurückgegeben.

Erforderliche Parameter

bidFloor: Der Schlüssel des Mindestgebotswerts, der in getSelectionSignals() übergeben wird und mit der Anzeige des Mediation-SDKs verglichen wird.

Nutzung

Wenn die Signale für die Anzeigenauswahl {"bid_floor": 10} lauten, wäre der resultierende vordefinierte URI:

`ad-selection-prebuilt://ad-selection-from-outcomes/waterfall-mediation-truncation/?bidFloor=bid_floor`

Test

Um Ihnen den Einstieg in die Protected Audience API zu erleichtern, haben wir Beispiel-Apps in Kotlin und Java erstellt. Sie finden diese auf GitHub.

Vorbereitung

Für die Protected Audience API ist JavaScript bei der Anzeigenauswahl und bei der Erstellung von Impressionsberichten erforderlich. Es gibt zwei Methoden, dieses JavaScript in einer Testumgebung bereitzustellen:

  • Einen Server mit den erforderlichen HTTPS-Endpunkten ausführen, der das JavaScript zurückgibt
  • Remote-Abruf überschreiben, indem Sie den erforderlichen Code aus einer lokalen Quelle angeben

Für beide Ansätze muss ein HTTPS-Endpunkt eingerichtet werden, um Impressionsberichte zu verarbeiten.

HTTPS-Endpunkte

Um die Anzeigenauswahl und Berichte zu Impressionen zu testen, müssen Sie sieben HTTPS-Endpunkte einrichten, auf die Ihr Testgerät oder Emulator zugreifen kann:

  1. Käuferendpunkt, der das JavaScript für die Gebotslogik bereitstellt.
  2. Ein Endpunkt, der die Gebotssignale bereitstellt.
  3. Verkäuferendpunkt, der die JavaScript-Entscheidungslogik bereitstellt.
  4. Ein Endpunkt, der Bewertungssignale bereitstellt.
  5. Endpunkt für Berichte zu Impressionen des Käufers, der die Auktion gewonnen hat.
  6. Endpunkt für Berichte zu Verkäuferimpressionen.
  7. Ein Endpunkt, um die täglichen Updates für eine benutzerdefinierte Zielgruppe bereitzustellen.

Der Einfachheit halber enthält das GitHub-Repository grundlegenden JavaScript-Code für Testzwecke. Sie enthält auch OpenAPI-Dienstdefinitionen, die auf einer unterstützten Mock- oder Mikrodienstplattform bereitgestellt werden können. Weitere Informationen finden Sie in der README für das Projekt.

Remote-Abruf von JavaScript überschreiben

Diese Funktion ist für End-to-End-Tests vorgesehen. Wenn Sie das Remote-Abrufen überschreiben möchten, muss Ihre App im Debug-Modus mit aktivierten Entwickleroptionen ausgeführt werden.

Wenn Sie den Debug-Modus für Ihre Anwendung aktivieren möchten, fügen Sie dem Attribut „application“ in AndroidManifest.xml die folgende Zeile hinzu:

<application
  android:debuggable="true">

Ein Beispiel für die Verwendung dieser Überschreibungen finden Sie in der Beispiel-App Protected Audience API auf GitHub.

Sie müssen eigenes benutzerdefiniertes JavaScript hinzufügen, um Abläufe für die Anzeigenauswahl wie Gebote, Bewertungsentscheidungen und Berichte zu verarbeiten. Im GitHub-Repository finden Sie Beispiele für einfachen JavaScript-Code, der alle erforderlichen Anfragen verarbeitet. Die Beispielanwendung der Protected Audience API zeigt, wie Code aus dieser Datei gelesen und für die Verwendung als Überschreibung vorbereitet wird.

Es ist möglich, JavaScript-Abrufe auf Verkäuferseite und auf Käuferseite unabhängig voneinander zu überschreiben. Sie benötigen jedoch einen HTTPS-Endpunkt, um JavaScript bereitzustellen, für das Sie keine Überschreibungen bereitstellen. In der README-Datei finden Sie Informationen zum Einrichten eines Servers, der diese Fälle verarbeitet.

Das Abrufen von JavaScript kann nur für benutzerdefinierte Zielgruppen überschrieben werden, deren Inhaber Ihr Paket ist.

JavaScript auf Verkäuferseite überschreiben

So richten Sie eine Überschreibung von JavaScript auf Verkäuferseite ein:

  1. Initialisieren Sie ein AdSelectionManager-Objekt.
  2. Rufe einen Verweis auf TestAdSelectionManager aus dem AdSelectionManager-Objekt ab.
  3. Erstellen Sie ein AdSelectionConfig-Objekt.
  4. Erstelle einen AddAdSelectionOverrideRequest mit dem AdSelectionConfig-Objekt und einem String, der den JavaScript-Code darstellt, den du als Überschreibung verwenden möchtest.
  5. Rufen Sie die asynchrone overrideAdSelectionConfigRemoteInfo()-Methode mit dem AddAdSelectionOverrideRequest-Objekt und den relevanten Executor- und OutcomeReceiver-Objekten auf.

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);

Weitere Informationen zu den einzelnen Feldern in AdSelectionConfig finden Sie im Abschnitt Anzeigenauswahl ausführen. Der Hauptunterschied besteht darin, dass decisionLogicUrl auf einen Platzhalterwert gesetzt werden kann, da dieser ignoriert wird.

Damit das bei der Anzeigenauswahl verwendete JavaScript überschrieben werden kann, muss decisionLogicJs die richtigen Funktionssignaturen der Verkäuferseite enthalten. Ein Beispiel für das Lesen einer JavaScript-Datei als String finden Sie in der Beispiel-App „Protected Audience API“ auf GitHub.

Bei der asynchronen Methode overrideAdSelectionConfigRemoteInfo() wird das Ergebnis des API-Aufrufs mithilfe des Objekts OutcomeReceiver signalisiert.

Der onResult()-Callback bedeutet, dass die Überschreibung erfolgreich angewendet wurde. Zukünftige Aufrufe von selectAds() verwenden die Entscheidungs- und Berichtslogik, die Sie als Überschreibung übergeben haben.

Der onError()-Callback deutet auf zwei mögliche Bedingungen hin:

  • Wenn versucht wird, mit ungültigen Argumenten zu überschreiben, gibt AdServiceException einen IllegalArgumentException als Ursache an.
  • Wird versucht, die Anwendung mit einer App zu überschreiben, die nicht im Debug-Modus mit aktivierten Entwickleroptionen ausgeführt wird, wird durch AdServiceException IllegalStateException als Ursache angegeben.

Überschreibungen auf Verkäuferseite zurücksetzen

In diesem Abschnitt wird davon ausgegangen, dass Sie das JavaScript für die Sell-Side überschrieben haben und dass Sie einen Verweis auf TestAdSelectionManager und AdSelectionConfig haben, die im vorherigen Abschnitt verwendet wurden.

So setzen Sie die Überschreibungen für alle AdSelectionConfigs zurück:

  1. Rufen Sie die asynchrone resetAllAdSelectionConfigRemoteOverrides()-Methode mit dem entsprechenden OutcomeReceiver-Objekt auf.

Kotlin

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

Java

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

Nachdem Sie die kundenseitigen Überschreibungen zurückgesetzt haben, wird für Aufrufe von selectAds() die decisionLogicUrl verwendet, die in AdSelectionConfig gespeichert ist, um das erforderliche JavaScript abzurufen.

Wenn der Aufruf von resetAllAdSelectionConfigRemoteOverrides() fehlschlägt, gibt der Callback OutComeReceiver.onError() ein AdServiceException aus. Wird versucht, die Überschreibungen mit einer App zu entfernen, die nicht im Debug-Modus mit aktivierten Entwickleroptionen ausgeführt wird, wird in AdServiceException IllegalStateException als Ursache angegeben.

Buy-Side-JavaScript überschreiben

  1. Folgen Sie dieser Anleitung, um einer benutzerdefinierten Zielgruppe beizutreten.
  2. Erstellen Sie eine AddCustomAudienceOverrideRequest mit dem Käufer und dem Namen der benutzerdefinierten Zielgruppe, die Sie überschreiben möchten, sowie der Gebotslogik und den Daten, die Sie als Überschreibung verwenden möchten.
  3. Die asynchrone overrideCustomAudienceRemoteInfo()-Methode mit dem AddCustomAudienceOverrideRequest-Objekt und den relevanten Executor- und OutcomeReceiver-Objekten aufrufen

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);

Die Werte für buyer und name sind dieselben, die beim Erstellen der benutzerdefinierten Zielgruppe verwendet wurden. Weitere Informationen zu diesen Feldern

Außerdem können Sie zwei zusätzliche Parameter angeben:

  • biddingLogicJs: JavaScript-Code mit der Käuferlogik, die bei der Anzeigenauswahl verwendet wird Die erforderlichen Funktionssignaturen finden Sie in diesem JavaScript-Code.
  • trustedBiddingSignals: Gebotssignale, die bei der Anzeigenauswahl verwendet werden sollen. Zu Testzwecken kann dies ein leerer String sein.

Bei der asynchronen Methode overrideCustomAudienceRemoteInfo() wird über das Objekt OutcomeReceiver das Ergebnis des API-Aufrufs signalisiert.

Der onResult()-Callback zeigt an, dass die Überschreibung erfolgreich angewendet wurde. Nachfolgende Aufrufe von selectAds() verwenden die Gebots- und Berichtslogik, die Sie als Überschreibung übergeben haben.

Der onError()-Callback steht für zwei mögliche Bedingungen.

  • Wenn der Überschreibung mit ungültigen Argumenten versucht wird, gibt die AdServiceException einen IllegalArgumentException als Ursache an.
  • Wenn der Überschreibungsversuch mit einer App erfolgt, die nicht im Debug-Modus mit aktivierten Entwickleroptionen ausgeführt wird, wird in AdServiceException IllegalStateException als Ursache angegeben.

Überschreibungen auf Käuferseite zurücksetzen

In diesem Abschnitt wird davon ausgegangen, dass Sie das Buy-Side-JavaScript überschrieben haben und dass Sie einen Verweis auf den im vorherigen Abschnitt verwendeten TestCustomAudienceManager haben.

So setzen Sie Überschreibungen für alle benutzerdefinierten Zielgruppen zurück:

  1. Rufen Sie die asynchrone resetAllCustomAudienceOverrides()-Methode mit den relevanten Executor- und OutcomeReceiver-Objekten auf.

Kotlin

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

Java

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

Nachdem du Überschreibungen auf Käuferseite zurückgesetzt hast, verwenden nachfolgende Aufrufe von selectAds() den in CustomAudience gespeicherten biddingLogicUrl und trustedBiddingData, um das erforderliche JavaScript abzurufen.

Wenn der Aufruf von resetCustomAudienceRemoteInfoOverride() fehlschlägt, gibt der Callback OutComeReceiver.onError() ein AdServiceException aus. Wird versucht, die Überschreibungen mit einer App zu entfernen, die nicht im Debug-Modus mit aktivierten Entwickleroptionen ausgeführt wird, wird durch AdServiceException IllegalStateException als Ursache angegeben.

Berichtsserver einrichten

Wenn Sie Überschreibungen für Remote-Abrufe verwenden, müssen Sie trotzdem einen Server einrichten, den Ihr Gerät oder Emulator erreichen kann, um auf Berichtsereignisse zu reagieren. Ein einfacher Endpunkt, der 200 zurückgibt, ist zum Testen ausreichend. Das GitHub-Repository enthält OpenAPI-Dienstdefinitionen, die auf einer unterstützten Mock- oder Mikrodienstplattform bereitgestellt werden können. Weitere Informationen finden Sie in der README für das Projekt.

Suchen Sie nach der Datei „reporting-server.json“, um die OpenAPI-Definitionen zu finden. Diese Datei enthält einen einfachen Endpunkt, der 200 zurückgibt, was einem HTTP-Antwortcode entspricht. Dieser Endpunkt wird während selectAds() verwendet und signalisiert der Protected Audience API, dass die Impressionsberichte erfolgreich abgeschlossen wurden.

Zu testende Funktionalität

  • Sie üben das Teilnehmen oder Verlassen von Aktivitäten und das Einrichten einer benutzerdefinierten Zielgruppe basierend auf früheren Nutzeraktionen.
  • Testen Sie die Auslösung der Anzeigenauswahl auf dem Gerät über remote gehostete JavaScripts.
  • Beobachten Sie, wie sich die Verknüpfung einer App mit benutzerdefinierten Zielgruppeneinstellungen auf die Ergebnisse der Anzeigenauswahl auswirken kann.
  • Führen Sie nach der Anzeigenauswahl die Impressionsberichte durch.

Beschränkungen

In der folgenden Tabelle sind Einschränkungen für die Verarbeitung durch die Protected Audience API aufgeführt. Die Limits können sich je nach Feedback ändern. Informationen zu in der Entwicklung befindlichen Funktionen finden Sie in den Versionshinweisen.

Komponente Beschreibung des Limits Grenzwert
Benutzerdefinierte Zielgruppe (Kanada) Maximale Anzahl von Anzeigen pro Creative-Anzeigenblock 100
Maximale Anzahl von Zertifizierungsstellen pro Anwendung 1000
Maximale Anzahl von Apps, mit denen eine CA erstellt werden kann 1000
Maximale Verzögerung der Aktivierungszeit einer Zertifizierungsstelle ab ihrer Erstellung 60 Tage
Maximale Ablaufzeit einer Zertifizierungsstelle ab ihrer Aktivierungszeit 60 Tage
Maximale Anzahl von Zertifizierungsstellen auf dem Gerät 4000
Maximale Größe des CA-Namens 200 Byte
Maximale Größe des täglichen Abruf-URI 400 Byte
Maximale Größe der URI für die Gebotslogik 400 Byte
Maximale Größe von vertrauenswürdigen Gebotsdaten 10 KB
Maximale Größe von Gebotssignalen von Nutzern 10 KB
Maximale Anrufrate für leaveCustomAudience pro Käufer 1 pro Sekunde
Maximale Anrufrate für joinCustomAudience pro Käufer 1 pro Sekunde
CA-Hintergrundabruf Zeitüberschreitung beim Verbindungsaufbau 5 Sekunden
HTTP-Lesezeitlimit 30 Sekunden
Maximale Downloadgröße insgesamt 10 KB
Maximale Dauer einer Abrufiteration 5 Minuten
Maximale Anzahl von Zertifizierungsstellen pro Job aktualisiert 1000
Anzeigenauswahl Maximale Anzahl von Käufern Noch offen
Maximale Anzahl von Kundencentern pro Käufer Noch offen
Maximale Anzahl von Anzeigen in einer Auktion Noch offen
Zeitüberschreitung bei der ersten Verbindung 5 Sekunden
Zeitlimit für das Lesen von Verbindungen 5 Sekunden
Maximale Ausführungszeit insgesamt AdSelection 10 Sekunden
Maximale Ausführungszeit von Bidding pro Zertifizierungsstelle in AdSelection 5 Sekunden
Maximale Ausführungszeit der Bewertung in AdSelection 5 Sekunden
Maximale Ausführungszeit für pro Käufer in AdSelection Noch offen
Maximale Größe von Signalen für Anzeigenauswahl, Verkäufer und Käufer Noch offen
Maximale Größe von Verkäufer-/Käuferskripts Noch offen
Maximale Aufrufrate für selectAds 1 Abfrage pro Sekunde
Berichte zu Impressionen Mindestdauer, bevor die Anzeigenauswahl aus der Persistenz entfernt wird 24 Stunden
Maximale Anzahl der für Speicheranzeigen ausgewählten Anzeigen Noch offen
Maximale Größe der URL für die Berichtsausgabe Noch offen
Maximale Zeit für Impressionsberichte Noch offen
Maximale Anzahl von Wiederholungen für Benachrichtigungsaufrufe Noch offen
Zeitüberschreitung der Verbindung 5 Sekunden
Maximale Gesamtausführungszeit für reportImpression 2 Sekunden
Maximale Anrufrate für reportImpressions 1 Abfrage pro Sekunde
Ereignisberichte Maximale Anzahl von Beacons pro Käufer und Auktion 10

Maximale Anzahl von Beacons pro Verkäufer pro Auktion

10

Maximale Größe des Ereignisschlüssels

40 Byte

Maximale Größe von Ereignisdaten

64 KB

Anzeigen Maximale Größe der Anzeigenliste 10 KB, die von allen AdData in einer einzelnen CA für kontextbezogene
URLs Maximale Länge eines als Eingabe verwendeten URL-Strings Noch offen
JavaScript Maximale Ausführungszeit 1 Sekunde für Gebote und Bewertungen für Impressionsberichte
Maximaler Arbeitsspeicherverbrauch 10 MB

Fehler und Probleme melden

Ihr Feedback ist ein wichtiger Bestandteil der Privacy Sandbox für Android. Teilen Sie uns mit, wenn Sie Probleme finden oder wenn Sie Vorschläge zur Verbesserung der Privacy Sandbox für Android haben.