Entwicklerhandbuch für die Protected Audience API

Wenn Sie die Dokumentation zu Privacy Sandbox für Android lesen, wählen Sie mit der Schaltfläche Entwicklervorschau oder Beta die Programmversion aus, mit der Sie arbeiten, da die Anleitungen variieren können.


Die Protected Audience API für Android (früher FLEDGE) umfasst die Custom Audience API und die Ad Selection API. Ad-Tech-Plattformen und Werbetreibende können diese APIs verwenden, um benutzerdefinierte Anzeigen basierend auf früheren App-Interaktionen auszuliefern. Dadurch wird das Teilen von Kennungen zwischen Apps und das Teilen von Informationen zu App-Interaktionen von Nutzern mit Drittanbietern 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 mit einer benutzerdefinierten Zielgruppe registrieren und relevante Anzeigen damit verknüpfen. Diese Informationen werden lokal gespeichert und können für Gebote von Werbetreibenden, das Filtern von Anzeigen und das Rendern von Anzeigen verwendet werden.

Die Ad Selection API bietet ein Framework, mit dem mehrere Entwickler eine Auktion lokal für eine benutzerdefinierte Zielgruppe durchführen können. Dazu werden relevante Anzeigen berücksichtigt, die der benutzerdefinierten Zielgruppe zugeordnet sind. Außerdem werden Anzeigen, die eine AdTech-Plattform an das Gerät zurückgibt, zusätzlich verarbeitet.

Anzeigentechnologie-Plattformen können diese APIs einbinden, um Remarketing zu implementieren, das den Datenschutz der Nutzer berücksichtigt. Die Unterstützung für weitere Anwendungsfälle, einschließlich Anzeigen zur App-Installation, ist für zukünftige Releases geplant. Weitere Informationen zur Protected Audience API für Android

In dieser Anleitung wird beschrieben, wie Sie mit der Protected Audience API auf Android Folgendes tun:

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

Hinweis

Führen Sie zuerst die folgenden Schritte aus:

  1. Richten Sie Ihre Entwicklungsumgebung für die Privacy Sandbox für Android ein.
  2. Installieren Sie ein Systemimage auf einem unterstützten Gerät oder richten Sie einen Emulator ein, der die Privacy Sandbox unter 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 im Manifest referenzierte XML-Ressource für Anzeigendienste an, 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 erzwingt die Ad Selection API Grenzwerte für die maximale Menge an Speicher, die einem Auktions- oder Impression-Reporting-Script zugewiesen werden kann. Für die Funktion zur Speicherbegrenzung ist WebView-Version 105.0.5195.58 oder höher erforderlich. Die Plattform erzwingt eine Versionsprüfung. Aufrufe der APIs selectAds und reportImpression schlagen fehl, wenn diese Bedingung nicht erfüllt ist. Dafür gibt es zwei Möglichkeiten:

    • Option 1: Führen Sie den folgenden ADB-Befehl aus, um diese Prüfung zu deaktivieren:

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

Einer benutzerdefinierten Zielgruppe beitreten

Eine benutzerdefinierte Zielgruppe stellt eine Gruppe von Nutzern mit gemeinsamen Absichten oder Interessen dar, die von einer Werbetreibenden-App festgelegt werden. Eine App oder ein SDK kann eine benutzerdefinierte Zielgruppe verwenden, um eine bestimmte Zielgruppe anzugeben, z. B. Nutzer, die Artikel in einem Einkaufswagen zurückgelassen haben. So erstellen Sie eine benutzerdefinierte Zielgruppe asynchron oder treten ihr bei:

  1. Initialisieren Sie das CustomAudienceManager-Objekt.
  2. Erstellen Sie ein CustomAudience-Objekt, indem Sie wichtige Parameter wie das Paket des Käufers und einen relevanten Namen angeben. Initialisieren Sie dann das JoinCustomAudienceRequest-Objekt mit dem CustomAudience-Objekt.
  3. Rufen Sie die asynchrone Funktion joinCustomAudience() mit dem JoinCustomAudienceRequest-Objekt und den relevanten 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);

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

  • owner: Paketname der Inhaber-App. Dieser wird implizit auf den Paketnamen der aufrufenden App festgelegt.
  • buyer: Kennung für das Anzeigennetzwerk des Käufers, das Anzeigen für diese benutzerdefinierte Zielgruppe verwaltet.
  • 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. Aus Datenschutzgründen wird bei 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 Aktualisierung: Eine HTTPS-URL, die täglich im Hintergrund aufgerufen wird, um die Gebotssignale, vertrauenswürdigen Gebotsdaten, Render-URLs und Metadaten für Anzeigen einer benutzerdefinierten Zielgruppe zu aktualisieren.
  • URL für 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.
  • IDs für die Anzeigendarstellung: Eine beliebige ID, die vom Ad-Tech-Unternehmen des Käufers festgelegt wird. Dies ist eine Optimierung für die Nutzlastgenerierung für B&A.

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

  • Aktivierungszeit: Eine benutzerdefinierte Zielgruppe kann erst nach der Aktivierungszeit an der Anzeigenauswahl und an täglichen Aktualisierungen teilnehmen. Das kann beispielsweise nützlich sein, um inaktive Nutzer einer App wieder zu aktivieren.
  • Ablaufzeit: Ein zukünftiger Zeitpunkt, nach dem die benutzerdefinierte Zielgruppe vom Gerät entfernt wird.
  • Gebotssignale für Nutzer: Ein JSON-String mit Nutzersignalen, z. B. dem bevorzugten Gebietsschema des Nutzers, der von der JavaScript-Gebotslogik eines Käufers verwendet wird, um während der Anzeigenauswahl Gebote zu generieren. Dieses Format hilft Ad-Tech-Plattformen, Code plattformübergreifend wiederzuverwenden, und erleichtert die Verwendung in JavaScript-Funktionen.
  • Vertrauenswürdige Gebotsdaten: Eine HTTPS-URL und eine Liste von Strings, die während der Anzeigenauswahl verwendet werden, um Gebotssignale von einem vertrauenswürdigen Schlüssel/Wert-Dienst abzurufen.
  • Anzeigen: Eine Liste von AdData-Objekten, die den Anzeigen entsprechen, die an der Anzeigenauswahl teilnehmen. Jedes AdData-Objekt besteht aus:
    • Render-URL: Eine HTTPS-URL, die abgefragt wird, um die endgültige Anzeige zu rendern.
    • Metadaten: Ein als String serialisiertes JSON-Objekt mit Informationen, die von der Gebotslogik des Käufers während der Anzeigenauswahl verwendet werden.
    • Anzeigenfilter: Eine Klasse, die alle erforderlichen Informationen zum Filtern von App-Install-Anzeigen und zum Festlegen der Häufigkeitsobergrenze bei der Anzeigenauswahl enthält.

Hier ein Beispiel für die Instanziierung eines CustomAudience-Objekts:

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

Ergebnisse von joinCustomAudience() verarbeiten

Die asynchrone Methode joinCustomAudience() verwendet das Objekt OutcomeReceiver, um das Ergebnis des API-Aufrufs zu signalisieren.

  • Der onResult()-Callback gibt an, dass die benutzerdefinierte Zielgruppe erfolgreich erstellt oder aktualisiert wurde.
  • Der onError()-Callback kann zwei mögliche Bedingungen signalisieren.

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 ein 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 ein CustomAudience anhand seiner eindeutigen Parameter:

  1. Initialisieren Sie das CustomAudienceManager-Objekt.
  2. Initialisieren Sie LeaveCustomAudienceRequest mit buyer und name der benutzerdefinierten Zielgruppe. Weitere Informationen zu diesen Eingabefeldern finden Sie unter Einer benutzerdefinierten Zielgruppe beitreten.
  3. Rufen Sie die asynchrone Methode leaveCustomAudience() 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 die Protected Audience API zum Auswählen von Anzeigen verwenden 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 Methode selectAds() 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 die Eingabe AdSelectionConfig erforderlich, wobei Sie die folgenden erforderlichen Parameter angeben müssen:

  • Verkäufer: Kennung für das Anzeigennetzwerk des Verkäufers, das die Anzeigenauswahl initiiert.
  • URL für Entscheidungslogik: Eine HTTPS-URL, die abgefragt wird, um die JavaScript-Logik des Werbenetzwerks des Verkäufers abzurufen.
    • HTTPS-URL: Wird abgefragt, um die JavaScript-Logik des Anzeigennetzwerks des Verkäufers abzurufen. Erforderliche Funktionssignaturen
    • Vorgefertigter URI: Dieser entspricht dem Format für die Anzeigenauswahl von FLEDGE. IllegalArgumentException wird ausgelöst, wenn eine nicht unterstützte oder fehlerhafte vordefinierte URI übergeben wird.
  • Käufer benutzerdefinierter Zielgruppen: Eine vollständige Liste der Kennungen für Werbenetzwerke von Käufern, die vom Verkäufer für die Teilnahme am Prozess zur Auswahl von Anzeigen zugelassen sind. Diese Käufer-IDs entsprechen CustomAudience.getBuyer() der teilnehmenden benutzerdefinierten Zielgruppen.

Die folgenden Parameter können optional angegeben werden, um die Anzeigenauswahl anzupassen:

  • Signale für die Anzeigenauswahl: Ein JSON-Objekt, das als String serialisiert ist und Signale enthält, die von der JavaScript-Bieterlogik des Käufers verwendet werden, die von CustomAudience.getBiddingLogicUrl() abgerufen wird.
  • Verkäufersignale: Ein JSON-Objekt, das als String serialisiert ist und Signale enthält, die von der abgerufenen JavaScript-Entscheidungslogik des Verkäufers 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 sollen, die von CustomAudience.getBiddingLogicUrl() abgerufen werden. Die Käufer werden anhand der Käuferfelder der teilnehmenden benutzerdefinierten Zielgruppen identifiziert.
  • Kontextbezogene Anzeigen:Eine Sammlung von Anzeigenkandidaten, die direkt von Käufern während einer Auktion erhoben werden, die außerhalb einer Protected Audience-Auktion stattfindet.

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 Render-URL für die erfolgreiche Anzeige, die von AdData.getRenderUrl() abgerufen wurde.
  • Eine für den Gerätenutzer eindeutige ID für die Anzeigenauswahl. Diese ID wird für Berichte zur Anzeigenimpression verwendet.

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

  • Wenn die Anzeigenauswahl mit ungültigen Argumenten initiiert wird, gibt AdServicesException als Ursache IllegalArgumentException an.
  • Alle anderen Fehler erhalten ein AdServicesException mit IllegalStateException als Ursache.

Kontextbasierte Anzeigen

Mit Protected Audience können kontextbezogene Anzeigen in eine Protected Audience-Auktion eingebunden werden. Kontextbezogene Anzeigen müssen auf dem Server des Anzeigentechnologieanbieters ausgewählt und an das Gerät zurückgegeben werden. Das erfolgt außerhalb der Protected Audience APIs. Kontextbezogene Anzeigen können dann über AdSelectionConfig in die Auktion aufgenommen werden. Sie funktionieren dann genauso wie On-Device-Anzeigen, einschließlich der Berechtigung für das Filtern von Anzeigen mit Ausschlusskriterien. Nach Abschluss der Protected Audience-Auktion müssen Sie reportImpression() aufrufen. Dadurch wird reportWin() in der gewonnenen kontextbezogenen Anzeige aufgerufen, um die gewonnene Anzeige auf einem Gerät zu erhalten. Das Muster ist dasselbe wie beim Impression-Reporting. Für jede kontextbezogene Anzeige sind ein Käufer, ein Gebot, ein Link zur Berichtslogik, eine Render-URL und Anzeigenmetadaten erforderlich.

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

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

Filterung von App-Installationsanzeigen

Mit der Filterung von App-Installationsanzeigen können Sie Installationsanzeigen für Apps herausfiltern, die bereits auf einem Gerät installiert sind.

Im ersten Schritt dieses Prozesses wird festgelegt, welche Werbetreibenden die Möglichkeit haben, nach dem installierten Paket zu filtern. Das muss in der App erfolgen, auf die Sie mit einer Anzeige ausgerichtet sein 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 angeben. Wenn Sie den Zugriff eines Werbetreibenden auf den Installationsstatus dieser App entfernen möchten, führen Sie diesen Code noch einmal aus, nachdem Sie die Informationen des Werbetreibenden entfernt haben.

Im nächsten Schritt müssen Sie die Anzeigenfilterung in der Publisher-App einrichten. Die Partei, die die Anzeige in der Publisher-App bereitstellt (wahrscheinlich ein Supply-Side-SDK), muss ihr AdFilters-Objekt mit Informationen dazu initialisieren, welche Anzeigen in Bezug auf 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();

Demand-Side-Publisher können auch ein 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();

Filterung nach Frequency Capping

Mit Frequency Capping können Ad-Tech-Unternehmen begrenzen, wie oft eine Anzeige ausgeliefert wird. Durch das Filtern nach Frequency Capping wird die Häufigkeit der Anzeigenauslieferung reduziert und die Auswahl alternativer Anzeigen für eine bestimmte Werbekampagne optimiert.

Ein Filter für die Häufigkeitsbegrenzung besteht aus zwei Hauptkomponenten: dem Anzeigenereignistyp und dem Anzeigenzähler-Schlü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. Gewinndaten sind nur für Anzeigen in einer bestimmten benutzerdefinierten Zielgruppe sichtbar.
  • Impression: Ein On-Device-Aufrufer (SSP oder MMP) verwendet updateAdCounterHistogram(), um Impressionsereignisse an der von ihm ausgewählten Stelle im Code aufzurufen. Dies ist unabhängig von reportImpression. Impressionsereignisse sind für alle Anzeigen einer bestimmten DSP sichtbar und nicht auf Anzeigen in derselben benutzerdefinierten Zielgruppe beschränkt.
  • View: Das Ereignis wird vom On-Device-Aufrufer (SSP oder MMP) an einer vom Entwickler ausgewählten Stelle im Code mit einem Aufruf von updateAdCounterHistogram() aufgerufen. View-Ereignisse sind für alle Anzeigen sichtbar, die zu einer bestimmten DSP gehören, und nicht auf Anzeigen in derselben benutzerdefinierten Zielgruppe beschränkt.
  • Klick: Das Ereignis wird vom Anrufer auf dem Gerät (SSP oder MMP) an einer Stelle im Code aufgerufen, die er mit einem Aufruf von updateAdCounterHistogram() auswählt. 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 ein MMP, die auf dem Gerät vorhanden sind, Werbeereignisse auf. Wenn updateAdCounterHistogram() aufgerufen wird, wird der Zähler eines Frequency-Capping-Filters inkrementiert, damit bei zukünftigen Auktionen aktuelle Informationen zur Häufigkeit der Auslieferung einer bestimmten Anzeige für einen Nutzer verfügbar sind. Die Anzeigenereignistypen sind nicht zwingend an die entsprechende Nutzeraktion gebunden. Sie sind Richtlinien, die Anrufern helfen sollen, ihr Ereignissystem zu strukturieren. Damit die Anzeigenzähler zum Zeitpunkt eines Ereignisses erhöht werden, stellt der On-Device-Akteur die ID der Anzeigenauswahl der gewonnenen Anzeigenauktion bereit.

Schlüssel für den Anzeigenzähler sind beliebige 32-Bit-Ganzzahlen mit Vorzeichen, die von einem AdTech-Unternehmen des Käufers zugewiesen werden und einer bestimmten Gruppe von Anzeigen entsprechen, die von der DSP definiert werden. Da Zählerschlüssel für Anzeigen nur auf Anzeigen beschränkt sind, die zu einer bestimmten DSP gehören, können diese Schlüssel ausgewählt werden, ohne sich mit Histogrammen einer anderen Ad-Tech zu überschneiden. Zählerschlüssel für Anzeigen werden verwendet, um DSP-spezifische IDs für die Anzeigen einer DSP oder innerhalb einer bestimmten benutzerdefinierten Zielgruppe zu erhöhen, um Anzeigen aus zukünftigen Auktionen herauszufiltern.

Mit Zählerschlüsseln können Anzeigen priorisiert werden, die für einen bestimmten Nutzer aufgrund seiner Interaktionen mit anderen Anzeigen einer bestimmten AdTech-Lösung eines Käufers wahrscheinlich interessanter sind. Eine Anzeige, die bei gewonnenen Anzeigenauktionen, Aufrufen und Klicks ein hohes Maß an Engagement erzielt hat, stellt beispielsweise einen abgeleiteten Datenpunkt dar. Ein Beispiel: Eine Anzeige für Golfschläger für Linkshänder deutet darauf hin, dass der Nutzer sich nicht für Golfschläger für Rechtshänder interessiert. Ein Filter für Frequency Capping, der für einen Zählerschlüssel festgelegt ist, der Anzeigen für Linkshänder zugewiesen ist, könnte Anzeigen für Rechtshänder herausfiltern.

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

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 übergeben 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äufigkeitsbegrenzung 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 das voreingestellte Frequency Capping-Filterlimit erreicht haben, werden aus der Auktion herausgefiltert. Die Filterung erfolgt vor der Ausführung der Gebotslogik für On-Device-Auktionen und während der Nutzlastgenerierung für Auktionen der Bidding & Auction-Dienste.Mit diesem Toolkit können Ad-Tech-Unternehmen die Interaktionen zwischen Nutzern und den Anzeigen in ihren benutzerdefinierten Zielgruppen nutzen, um das Anzeigentargeting zu optimieren und gleichzeitig eine übermäßige Anzeigenauslieferung zu minimieren.

Kontextbezogene Anzeigenfilterung 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 kann die Plattform das Abrufen von Gebotslogik, Gebotssignalen und Scoring-Signalen überspringen. Die Plattform verwendet einen vorkonfigurierten URI, um die kontextbezogene Anzeige mit dem höchsten Gebot auszuwählen.

Um die Latenz zu verbessern, können Ad-Tech-Unternehmen einen Anzeigenbereitstellungsprozess ausführen, der nur kontextbezogene Anzeigen mit Anzeigenfilterfunktionen ohne Netzwerkaufrufe umfasst. Dies wird durch die Verwendung von vordefinierten URIs für Scoring-Signale erreicht. Eine Liste der scoreAds-Implementierungen finden Sie im Abschnitt Unterstützte vordefinierte URI-Anwendungsfälle und ‑Namen.

So führen Sie die Anzeigenauswahl ohne Netzwerkaufrufe aus:

  1. Anzeigenfilterung einrichten
  2. Kontextbezogene Anzeigen erstellen
  3. Erstellen Sie ein AdSelectionConfig-Objekt mit folgenden Angaben:

    1. Eine leere Liste von Käufern
    2. Vorgefertigter URI zum Auswählen des höchsten Gebots
    3. Kontextbasierte Anzeigen
    4. Ein leerer URI für die Scoring-Signale. Der leere URI ist zulässig, um anzugeben, dass Sie das Abrufen vertrauenswürdiger Signale für die Bewertung nicht 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 Berichte mit vordefinierten URIs ausführen

Derzeit ist auf der Privacy Sandbox-Plattform nur eine einfache JavaScript-Implementierung für Berichte für vordefinierte URIs verfügbar. Wenn Sie Ihr eigenes Reporting-JavaScript ausführen und gleichzeitig vorgefertigte URIs für eine Anzeigenauswahl mit geringer Latenz verwenden möchten, können Sie DecisionLogicUri zwischen der Anzeigenauswahl und den Reporting-Ausführungen überschreiben.

  1. Führen Sie die Schritte zum Ausführen der Anzeigenauswahl für kontextbezogene Anzeigen mit vordefinierten URIs aus.
  2. Kopie von AdSelectionConfig erstellen, bevor Sie Berichte erstellen

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

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

Abfolgebasierte Vermittlung ausführen

Für die Wasserfallvermittlung sind mehrere Drittanbieter-SDKs (3P-Netzwerke) erforderlich, die von einem Erstanbieter-SDK-Vermittlungsnetzwerk koordiniert werden. Die Wasserfall-Vermittlung erfolgt auf dieselbe Weise, unabhängig davon, ob die Auktion auf dem Gerät oder über Bidding & Auction-Dienste (B&A) stattgefunden hat.

Netzwerke von Drittanbietern

3P-Netzwerke müssen einen Adapter bereitstellen, über den das Vermittlungsnetzwerk die erforderlichen Methoden zum Ausführen einer Auktion aufrufen kann:

  • Anzeigenauswahl ausführen
  • Bericht zu Impressionen

Hier ein Beispiel für einen Vermittlungsnetzwerkadapter:

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 ‑clients für die Anzeigenauswahl sowie eine eigene Implementierung von selectAds und reportImpressions. SDK-Anbieter können sich die Abschnitte zum Ausführen der Anzeigenauswahl für On-Device-Auktionen oder die B&A-Erklärung für B&A-Auktionen ansehen. Melden Sie Anzeigenimpressionen gemäß der Berichterstellung für einzelne SSP-Impressionen.

Vermittlungsnetzwerk

Ähnlich wie bei Drittanbieternetzwerken sind für Vermittlungsnetzwerke selectAds- und reportImpression-Implementierungen erforderlich. Weitere Informationen finden Sie in den Abschnitten zum Ausführen der Anzeigenauswahl und zum Melden von Anzeigeimpressionen.

Vermittlungsnetzwerke sind für die Ausführung der Vermittlungskette und die Platzierung in der Vermittlungskette verantwortlich. Im nächsten Abschnitt wird beschrieben, wie Sie diesen Prozess einrichten und ausführen.

Vermittlungskette und Mindestgebote abrufen

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

Platzierung des Netzwerks in der Vermittlungskette

Ein Vermittlungs-SDK kann sich selbst in die Vermittlungskette einfügen, basierend auf dem Live-eCPM von Geboten für eigene Anzeigen. In der Protected Audience API sind Gebote für Anzeigen nicht transparent. Ein Vermittlungs-SDK sollte AdSelectionFromOutcomesConfig verwenden, um das Gebot einer bestimmten 1P-Anzeige mit dem Mindestgebot des nächsten 3P-Netzwerks in der Kette vergleichen zu können. Wenn das Gebot des eigenen Produkts höher als der Mindestpreis ist, bedeutet das, dass das Vermittlungs-SDK vor diesem Drittanbieternetzwerk platziert wird.

Anzeigenauswahl ausführen

Um einen 1P-Anzeigenkandidaten abzurufen, kann das Vermittlungsnetzwerk eine On-Device-Auktion gemäß den Schritten im Abschnitt Anzeigenauswahl durchführen ausführen. Dadurch werden ein 1P-Anzeigenkandidat, ein Gebot und ein AdSelectionId generiert, das im Vermittlungsprozess verwendet wird.

AdSelectionFromOutcomesConfig erstellen

Mit einem AdSelectionFromOutcomesConfig kann das Vermittlungsnetzwerk eine Liste mit AdSelectionIds (Ergebnisse aus vorherigen Auktionen), Signalen zur Anzeigenauswahl und einem URI übergeben, um JavaScript abzurufen, mit dem eine Anzeige aus mehreren Kandidaten ausgewählt wird. Die Liste der AdSelectionIds wird zusammen mit den Geboten und Signalen an das JavaScript übergeben. Dieses kann einen der AdSelectionIds zurückgeben, wenn das Gebot den Mindestpreis übersteigt, oder keinen, wenn die Vermittlungskette fortgesetzt werden soll.

Mediation Networks erstellen ein AdSelectionFromOutcomesConfig mit dem 1P-AdSelectionId aus dem vorherigen Abschnitt und dem Mindestgebot für das infrage kommende 3P-Netzwerk. Für jeden Schritt in der Vermittlungskette sollte ein neues 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 die Überschreibung der Methode selectAds() für die Wasserfall-Vermittlung ist eine AdSelectionFromOutcomesConfig-Eingabe erforderlich, in der Sie die folgenden erforderlichen Parameter angeben müssen:

  • Verkäufer: Kennung für das Anzeigennetzwerk des Verkäufers, das die Anzeigenauswahl initiiert.
  • AdSelectionIds: Eine Singleton-Liste eines vorherigen selectAds()-Laufs für eine 1P-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 sollen. Geben Sie in diesem Fall den für das angegebene Drittanbieternetzwerk abgerufenen Mindestgebotspreis an.
  • URI für Auswahllogik: Eine HTTPS-URL, die während der Anzeigenauswahl aufgerufen wird, um das JavaScript des Vermittlungsnetzwerks zum Auswählen einer Gewinneranzeige abzurufen. Die erforderlichen Funktionssignaturen finden Sie in diesem JavaScript. Das JavaScript sollte die Drittanbieteranzeige zurückgeben, wenn das Gebot höher als der Mindestpreis ist, andernfalls null. Dadurch kann das Vermittlungs-SDK die Vermittlungskette kürzen, wenn ein Gewinner gefunden wird.

Rufen Sie nach der Erstellung von AdSelectionOutcomesConfig die Methode selectAds() des 3P-Netzwerks auf, das als Erstes 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);

Abfolgebasierte Vermittlung orchestrieren

Im Folgenden wird die Reihenfolge der Vorgänge für die Durchführung des Vermittlungsprozesses beschrieben.

  1. Führen Sie die Auswahl von Anzeigen mit eigenen Daten durch.
  2. Vermittlungskette durchlaufen Gehen Sie für jedes Drittanbieternetzwerk so vor:
    1. Erstellen Sie AdSelectionFromOutcomeConfig, einschließlich des 1P-outcomeId und des Mindestgebots des 3P-SDK.
    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 1P-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

Es gibt zwei Abläufe zum Melden einer Anzeigenimpression, je nachdem, wie die Auktion durchgeführt wird. Wenn Sie eine einzelne SSP sind, die eine Auktion durchführt, folgen Sie diesem Abschnitt. Wenn Sie die Vermittlung mit Wasserfall implementieren möchten, folgen Sie der Anleitung im Abschnitt zu Berichten zu Impressionen bei der Vermittlung mit Wasserfall.

Berichte zu Impressionen von einzelnen SSPs

Nachdem im Anzeigenauswahl-Workflow eine erfolgreiche Anzeige ausgewählt wurde, können Sie die Impression mit der AdSelectionManager.reportImpression()-Methode an teilnehmende Buy-Side- und Sell-Side-Plattformen zurückmelden. So melden Sie eine Anzeigenimpression:

  1. Initialisieren Sie ein AdSelectionManager-Objekt.
  2. Erstellen Sie ein ReportImpressionRequest-Objekt mit der ID für die Anzeigenauswahl.
  3. Rufen Sie die asynchrone Methode reportImpression() mit dem ReportImpressionRequest-Objekt und den relevanten 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:

  • ID für die Anzeigenauswahl: Eine ID, die nur für einen Gerätebenutzer eindeutig ist und eine erfolgreiche Anzeigenauswahl identifiziert.
  • Konfiguration für die Anzeigenauswahl: Die gleiche Konfiguration, die im selectAds()-Aufruf verwendet wird, der durch die angegebene ID für die Anzeigenauswahl identifiziert wird.

Die asynchrone Methode reportImpression() verwendet das Objekt OutcomeReceiver, um das Ergebnis des API-Aufrufs zu signalisieren.

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

Berichte zu Impressionen bei der abfolgebasierten Vermittlung

Ein Vermittlungs-SDK muss das Gewinner-SDK im Blick behalten, um die entsprechenden Berichtsabläufe auszulösen. Die SDKs, die an einer Vermittlungskette beteiligt sind, sollten eine Methode für den Vermittler bereitstellen, mit der der eigene Berichterstellungsablauf ausgelöst werden kann. Ein SDK, das an einer vermittelten Auktion teilnimmt, kann die oben beschriebenen Schritte ausführen, um eigene Berichte zu implementieren.

SSPs können dieses 3P-SDK-Codebeispiel als Prototyp dafür verwenden, wie sie an Vermittlungsabläufen teilnehmen können:

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 sendet HTTPS-GET-Anfragen an Endpunkte, die von der verkäuferseitigen Plattform und der erfolgreichen käuferseitigen Plattform bereitgestellt werden:

Endpunkt der Plattform auf Käuferseite:

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

Endpunkt der Sell-Side-Plattform:

  • Verwenden Sie die im AdSelectionConfig-Objekt angegebene URL für Entscheidungslogik, um das JavaScript für die Entscheidungslogik des Verkäufers abzurufen.
  • Rufen Sie die JavaScript-Funktion reportResult() auf, die die URL für die Impression-Berichterstellung des Verkäufers zurückgeben soll.

Berichterstellung für Gebots- und Auktionsdienste

Bei einer Auktion, die über Bidding & Auction Services ausgeführt wird, sind alle erforderlichen Berichtsinformationen, einschließlich der generierten 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. Das Melden von Anzeigen und Impressionen erfolgt also nach denselben Schritten.

Best-Effort-Berichterstellung für Impressionen

Die Methode reportImpression() wurde entwickelt, um Berichte bestmöglich zu vervollständigen.

Anzeigeninteraktionen melden

Protected Audience bietet Unterstützung für Berichte zu detaillierteren Interaktionen für eine gerenderte Anzeige. Dazu können Interaktionen wie Wiedergabezeit, Klicks, Mouseovers oder andere nützliche Messwerte gehören, die erfasst werden können. Der Prozess zum Erhalten dieser Berichte umfasst zwei Schritte. Zuerst müssen sich Käufer und Verkäufer registrieren, um diese Berichte in ihrem JavaScript für Berichte zu erhalten. Anschließend muss der Client diese Ereignisse melden.

Registrieren, um Interaktionsereignisse zu erhalten

Die Registrierung für Interaktionsereignisse erfolgt in den JavaScript-Funktionen reportWin() des Käufers und reportResult() des Verkäufers mit einer von der Plattform bereitgestellten JavaScript-Funktion: registerAdBeacon. Wenn Sie sich für den Empfang eines Ereignisberichts registrieren möchten, rufen Sie die Plattform-JavaScript-Funktion aus Ihrem Reporting-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 melden

Nachdem eine Impression gemeldet wurde, können Clients die Interaktionen mit der Methode AdSelectionManager.reportInteraction() an zuvor registrierte Gewinnerplattformen auf Käufer- und Verkäuferseite zurückmelden. So melden Sie ein Anzeigenereignis:

  1. Initialisieren Sie ein AdSelectionManager-Objekt.
  2. Erstellen Sie ein ReportInteractionRequest-Objekt mit der ID für die Anzeigenauswahl, dem Interaktionsschlüssel, den Interaktionsdaten und dem Berichtsziel.
  3. Rufen Sie die asynchrone Methode reportInteraction() 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:

  • ID für die Anzeigenauswahl: Eine ID für die Anzeigenauswahl, die aus einem zuvor zurückgegebenen AdSelectionOutcome abgerufen wurde.
  • Interaction Key (Interaktionsschlüssel): Ein vom Client definierter String-Schlüssel, der die gemeldete Aktion beschreibt. Dieser muss mit dem Schlüssel übereinstimmen, der vom Verkäufer oder Käufer in den JavaScript-Funktionen für Berichte registriert wurde.
  • Interaktionsdaten: Ein String mit Daten, die in den Ereignisbericht aufgenommen und an die Berichtsserver zurückgesendet werden sollen.
  • Berichtsziel: Eine Bitmaske, die angibt, ob die Ereignisse an den Käufer, den Verkäufer oder beide gemeldet werden sollen. Diese Flags werden von der Plattform bereitgestellt und die Maske für das endgültige Ziel kann mit bitweisen Operationen erstellt werden. Wenn Sie Daten an ein Ziel senden möchten, können Sie das Flag verwenden, das direkt von der Plattform bereitgestellt wird. Wenn Sie Daten an mehrere Ziele senden möchten, können Sie die bitweise OR-Operation (|) verwenden, um Flag-Werte zu kombinieren.

Die asynchrone Methode reportInteraction() verwendet das Objekt OutcomeReceiver, um das Ergebnis des API-Aufrufs zu signalisieren.

  • Der onResult()-Callback gibt an, dass der Aufruf für die Berichtsinteraktion 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 ein IllegalStateException mit einer Beschreibung des Fehlers zurückgegeben.
    • Wenn der Client gedrosselt wird, sodass er reportInteraction() nicht aufrufen kann, wird LimitExceededException zurückgegeben.
    • Wenn das Paket nicht für den Aufruf der Privacy Preserving APIs registriert ist, wird ein SecurityException() zurückgegeben.
    • Wenn die App, die Interaktionen meldet, sich von der App unterscheidet, die selectAds() aufgerufen hat, wird IllegalStateException zurückgegeben.
  • Wenn der Nutzer nicht in die Aktivierung der Privacy Sandbox-APIs eingewilligt hat, schlägt der Aufruf ohne Fehlermeldung fehl.

Endpunkte für Interaktionsberichte

Die Report Interaction API sendet HTTPS-POST-Anfragen an Endpunkte, die von der Sell-Side-Plattform und der Buy-Side-Plattform mit dem höchsten Gebot bereitgestellt werden. Protected Audience gleicht die Interaktionsschlüssel mit den in Reporting-JavaScript deklarierten URIs ab und sendet für jede gemeldete Interaktion eine POST-Anfrage an jeden Endpunkt. Der Content-Type der Anfrage ist Nur-Text, wobei der Hauptteil die Interaktionsdaten enthält.

Best-Effort-Berichte zu Interaktionen

Der reportInteraction() ist so konzipiert, dass er Berichte nach dem HTTP-POST-Verfahren nach bestem Wissen und Gewissen erstellt.

Tägliches Hintergrund-Update

Beim Erstellen einer benutzerdefinierten Zielgruppe können in Ihrer App oder Ihrem SDK Metadaten für benutzerdefinierte Zielgruppen initialisiert werden. Außerdem kann die Plattform die folgenden benutzerdefinierten Zielgruppenmetadaten täglich im Hintergrund aktualisieren.

  • Nutzersignale für die Gebotseinstellung
  • Vertrauenswürdige Gebotsdaten
  • AdData Liste

Bei diesem Vorgang werden Abfragen für die in der benutzerdefinierten Zielgruppe definierte URL für tägliche Updates ausgeführt. 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 validiert. Der Client ignoriert alle fehlerhaften Felder, was dazu führt, dass das entsprechende 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.
  • Für alle URIs muss HTTPS verwendet werden.
  • trusted_bidding_uri muss dieselbe ETLD+1 wie der Käufer haben.

Beispiel: JSON-Antwort für die tägliche Aktualisierung im Hintergrund

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

Im Workflow zur Anzeigenauswahl wird die Ausführung von JavaScript-Code koordiniert, der vom Käufer und vom Verkäufer bereitgestellt wird.

Das vom Käufer bereitgestellte JavaScript wird von der URL für die Gebotslogik abgerufen, die in der benutzerdefinierten Zielgruppe angegeben ist. Das zurückgegebene JavaScript sollte die folgenden Funktionen enthalten:

Vom Verkäufer bereitgestelltes JavaScript wird von der URL für die Entscheidungslogik abgerufen, die im Parameter AdSelectionConfig für die API zur Anzeigenauswahl 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: JSON-Objekt, das von der Plattform generiert wird. 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, die aus den Eigenschaften mit demselben Namen der benutzerdefinierten Zielgruppe stammen, die an der Anzeigenauswahl beteiligt ist.
    • activation_time und expiration_time sind die Aktivierungs- und Ablaufzeit der benutzerdefinierten Zielgruppe in Sekunden seit der Unix-Epoche.
    • ca_user_bidding_signals ist ein JSON-String, der bei der Erstellung im Feld userBiddingSignals von CustomAudience angegeben wird.
    • trusted_bidding_signals, contextual_signals und user_signals sind JSON-Objekte. Sie werden als leere Objekte übergeben und in zukünftigen Versionen ausgefüllt. Das Format wird nicht von der Plattform erzwungen, sondern von der Ad-Tech-Lösung verwaltet.

Ergebnis:

  • ad: Die Anzeige, auf die sich das Gebot bezieht. Das Skript darf eine Kopie der empfangenen Anzeige mit anderen Metadaten zurückgeben. Das Attribut 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), wenn eines der Eingabesignale ungültig ist. Wenn von „generate-bid“ ein Wert ungleich null zurückgegeben wird, wird das Gebotsverfahren für alle CA-Anzeigen 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: generateBid-Dokumentation ansehen
  • 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 als leere Objekte übergeben und in zukünftigen Versionen ausgefüllt. Das Format wird nicht von der Plattform erzwungen, sondern von der Anzeigentechnologie verwaltet.

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

Ausgabe:

  • score: Ein Gleitkommawert, der den Punktwert für diese Anzeige darstellt.
  • status: Ein ganzzahliger Wert, der Folgendes sein kann:
    • 0: für eine erfolgreiche Ausführung
    • 1: Falls die customAudienceSignals ungültig sind
    • 2: wenn die AdSelectionConfig ungültig ist
    • 3: Wenn eines der anderen Signale ungültig ist
    • Jeder Wert ungleich null führt zum Fehlschlagen des Prozesses. Der Wert bestimmt den Typ der ausgelösten 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 Objekt „auction configuration“ (Auktionskonfiguration) angegeben sind

Ausgabe:

  • status: 0 für Erfolg, ungleich 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: Dokumentation zu scoreAds ansehen
  • render_url: die Render-URL der Gewinneranzeige
  • bid: das Gebot für die erfolgreiche Anzeige
  • contextual_signals: Dokumentation zu generateBid ansehen

Ausgabe:

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

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: Weitere Informationen finden Sie in der Dokumentation für scoreAd.
  • signals_for_buyer: Ein JSON-Objekt, das von reportResult zurückgegeben wird.
  • contextual_signals, custom_audience_signals: Weitere Informationen finden Sie in der Dokumentation zu generateBid.

Ausgabe:

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

registerAdBeacon()

function registerAdBeacon(
  beacons
)

Eingabeparameter:

  • beacons: Ein Objekt mit Schlüssel/Wert-Paaren aus Interaktionsschlüsseln und Reporting-URIs. Das Format dafür ist:

    let beacons = {
      'interaction_key': 'reporting_uri',
      'interaction_key': 'reporting_uri',
      ...
    }
    
    • interaction_key: Ein String, der das Ereignis darstellt. Die Plattform verwendet diese später, um beim Melden von Ereignisinteraktionen die reporting_uri zu ermitteln, die benachrichtigt werden soll. Dieser Schlüssel muss mit dem übereinstimmen, was der Käufer oder Verkäufer registriert und was der Verkäufer meldet.
    • reporting_uri: Ein URI zum Empfangen von Ereignisberichten. Die Beschreibung sollte sich auf den gemeldeten Ereignistyp beziehen. Es muss eine POST-Anfrage akzeptieren, um alle mit dem Ereignis gemeldeten Daten zu verarbeiten.

    Beispiel:

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

Vorgefertigte URIs für die Anzeigenauswahl

Mit vordefinierten URIs können AdTech-Unternehmen JavaScript-Funktionen für die Entscheidungslogik zur Anzeigenauswahl in den Klassen AdSelectionConfig und AdSelectionFromOutcomesConfig festlegen. Für vorgefertigte URIs sind keine Netzwerkaufrufe zum Herunterladen des entsprechenden JavaScript-Codes erforderlich. Ad-Tech-Unternehmen können vorgefertigte URIs verwenden, ohne eine registrierte Domain zum Hosten des JavaScript 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 zur Laufzeit bereit.

Eine IllegalArgumentException wird ausgelöst, wenn:

  • Einer der erforderlichen Parameter ist nicht im URI vorhanden.
  • Die URI enthält nicht erkannte Parameter.

Unterstützte vordefinierte URI-Anwendungsfälle und ‑Namen

Anwendungsfall 1: Auswahl von Anzeigen

Vorgefertigte URIs für den Anwendungsfall ad-selection werden im selectAds(AdSelectionConfig)-Ablauf unterstützt.

Name des vordefinierten URI: highest-bid-wins

Dieser vordefinierte URI enthält JavaScript-Code, mit dem nach dem Bidding die Anzeige mit dem höchsten Gebot ausgewählt wird. Außerdem bietet es eine grundlegende Berichtsfunktion, mit der die render_uri und bid des Gewinners gemeldet werden können.

Erforderliche Parameter

reportingUrl: Die Basis-URL für Berichte, die mit der render_uri und der bid der Gewinneranzeige parametrisiert wird:

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

Nutzung

Wenn Ihre Basis-Berichts-URL https://www.ssp.com/reporting ist, lautet der vordefinierte URI:

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

Anwendungsfall 2: Auswahl von Anzeigen anhand von 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 enthält JavaScript, das die Logik für das Kürzen der Vermittlungsabfolge implementiert. Das JavaScript gibt eine Erstanbieteranzeige zurück, wenn der bid größer oder gleich dem bid floor ist. Andernfalls wird null zurückgegeben.

Erforderliche Parameter

bidFloor: Der Schlüssel des Mindestgebotswerts, der im getSelectionSignals() übergeben wird und mit der Anzeige des Vermittlungs-SDK verglichen wird.

Nutzung

Wenn Ihre Signale für die Anzeigenauswahl so aussehen: {"bid_floor": 10}, 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, die Sie auf GitHub finden.

Vorbereitung

Für die Protected Audience API ist während der Anzeigenauswahl und des Impression-Reportings JavaScript erforderlich. Es gibt zwei Möglichkeiten, 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 bereitstellen

Für beide Ansätze ist die Einrichtung eines HTTPS-Endpunkts für das Impression-Reporting erforderlich.

HTTPS-Endpunkte

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

  1. Käuferendpunkt, über den das JavaScript für die Gebotslogik bereitgestellt wird.
  2. Ein Endpunkt, über den die Gebotssignale bereitgestellt werden.
  3. Verkäuferendpunkt, über den das JavaScript für die Entscheidungslogik bereitgestellt wird.
  4. Ein Endpunkt, der Scoring-Signale 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 zum Bereitstellen der täglichen Aktualisierungen für eine benutzerdefinierte Zielgruppe.

Das GitHub-Repository enthält 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 des Projekts.

Remote-Abruf von JavaScript überschreiben

Diese Funktion ist für End-to-End-Tests vorgesehen. Wenn Sie das Abrufen von Remote-Konfigurationen ü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 die folgende Zeile dem Attribut „application“ in Ihrer Datei „AndroidManifest.xml“ hinzu:

<application
  android:debuggable="true">

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

Sie müssen Ihren eigenen benutzerdefinierten JavaScript-Code hinzufügen, um Routinen für die Anzeigenauswahl wie Gebote, Scoring-Entscheidungen und Berichte zu verarbeiten. Im GitHub-Repository finden Sie grundlegende JavaScript-Codebeispiele, die alle erforderlichen Anfragen verarbeiten. Die Protected Audience API-Beispielanwendung zeigt, wie Code aus dieser Datei gelesen und für die Verwendung als Überschreibung vorbereitet wird.

Das Abrufen von JavaScript auf Verkäufer- und Käuferseite kann unabhängig voneinander überschrieben werden. Sie benötigen jedoch einen HTTPS-Endpunkt, um JavaScript bereitzustellen, für das Sie keine Überschreibungen angeben. In der README finden Sie Informationen zum Einrichten eines Servers, der diese Fälle verarbeitet.

Das Abrufen von JavaScript kann nur für benutzerdefinierte Zielgruppen überschrieben werden, die zu Ihrem Paket gehören.

Sell-side-JavaScript überschreiben

So richten Sie das Überschreiben von sell-side JavaScript ein (siehe folgendes Codebeispiel):

  1. Initialisieren Sie ein AdSelectionManager-Objekt.
  2. Rufen Sie eine Referenz zu TestAdSelectionManager aus dem AdSelectionManager-Objekt ab.
  3. Erstellen Sie ein AdSelectionConfig-Objekt.
  4. Erstellen Sie ein AddAdSelectionOverrideRequest mit dem AdSelectionConfig-Objekt und einem String, das das JavaScript darstellt, das Sie als Überschreibung verwenden möchten.
  5. Rufen Sie die asynchrone Methode overrideAdSelectionConfigRemoteInfo() 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 dazu, wofür die einzelnen Felder in AdSelectionConfig stehen, finden Sie im Abschnitt Anzeigenauswahl ausführen. Der Hauptunterschied besteht darin, dass decisionLogicUrl auf einen Platzhalterwert festgelegt werden kann, da er ignoriert wird.

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

Die asynchrone Methode overrideAdSelectionConfigRemoteInfo() verwendet das OutcomeReceiver-Objekt, um das Ergebnis des API-Aufrufs zu signalisieren.

Der onResult()-Callback gibt an, dass die Überschreibung erfolgreich angewendet wurde. Bei zukünftigen Aufrufen von selectAds() wird die Entscheidungs- und Berichtslogik verwendet, die Sie als Überschreibung übergeben haben.

Der onError()-Callback kann zwei mögliche Bedingungen signalisieren:

  • Wenn der Override mit ungültigen Argumenten versucht wird, gibt AdServiceException als Ursache IllegalArgumentException an.
  • Wenn der Override mit einer App versucht wird, die nicht im Debug-Modus mit aktivierten Entwickleroptionen ausgeführt wird, gibt AdServiceException IllegalStateException als Ursache an.

Sell-Side-Überschreibungen zurücksetzen

In diesem Abschnitt wird davon ausgegangen, dass Sie das sell-side JavaScript ü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 Methode resetAllAdSelectionConfigRemoteOverrides() 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 sell-side-Überschreibungen zurückgesetzt haben, wird bei Aufrufen von selectAds() die in AdSelectionConfig gespeicherte decisionLogicUrl verwendet, um das erforderliche JavaScript abzurufen.

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

Buy-Side-JavaScript überschreiben

  1. Anleitung zum Beitreten einer benutzerdefinierten Zielgruppe
  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. Rufen Sie die asynchrone Methode overrideCustomAudienceRemoteInfo() mit dem AddCustomAudienceOverrideRequest-Objekt und den relevanten Executor- und OutcomeReceiver-Objekten auf.

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 zum Erstellen der benutzerdefinierten Zielgruppe verwendet wurden. Weitere Informationen zu diesen Feldern

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

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

Die asynchrone Methode overrideCustomAudienceRemoteInfo() verwendet das Objekt OutcomeReceiver, um das Ergebnis des API-Aufrufs zu signalisieren.

Der onResult()-Callback gibt an, dass die Überschreibung erfolgreich angewendet wurde. Bei nachfolgenden Aufrufen von selectAds() wird die Gebots- und Berichtslogik verwendet, die Sie als Überschreibung übergeben haben.

Der onError()-Callback kann zwei mögliche Bedingungen signalisieren.

  • Wenn der Override mit ungültigen Argumenten versucht wird, gibt AdServiceException als Ursache IllegalArgumentException an.
  • Wenn der Override mit einer App versucht wird, die nicht im Debug-Modus mit aktivierten Entwickleroptionen ausgeführt wird, gibt AdServiceException IllegalStateException als Ursache an.

Buy-Side-Überschreibungen zurücksetzen

In diesem Abschnitt wird davon ausgegangen, dass Sie das buy-side JavaScript überschrieben haben und dass Sie einen Verweis auf das TestCustomAudienceManager aus dem vorherigen Abschnitt haben.

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

  1. Rufen Sie die asynchrone Methode resetAllCustomAudienceOverrides() mit 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 Sie die Überschreibungen auf der Käuferseite zurückgesetzt haben, werden bei nachfolgenden Aufrufen von selectAds() die in CustomAudience gespeicherten biddingLogicUrl und trustedBiddingData verwendet, um das erforderliche JavaScript abzurufen.

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

Berichtsserver einrichten

Wenn Sie die Überschreibungen für das Remote-Abrufen verwenden, müssen Sie weiterhin einen Server einrichten, den Ihr Gerät oder Emulator erreichen kann, um auf Berichterstattungsereignisse zu reagieren. Für Tests reicht ein Endpunkt, der 200 zurückgibt. Das GitHub-Repository enthält OpenAPI-Dienstdefinitionen, die auf einer unterstützten Mock- oder Microservices-Plattform bereitgestellt werden können. Weitere Informationen finden Sie in der README des Projekts.

Suchen Sie nach den OpenAPI-Definitionen in der Datei „reporting-server.json“. Diese Datei enthält einen 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 Impression-Berichterstellung erfolgreich abgeschlossen wurde.

Zu testende Funktionen

  • Sie können einer Übung beitreten oder sie verlassen und eine benutzerdefinierte Zielgruppe basierend auf früheren Nutzeraktionen einrichten.
  • Die Initiierung der Geräteauswahl von Anzeigen über remote gehostete JavaScripts testen.
  • Beobachten Sie, wie sich die Zuordnung einer App zu benutzerdefinierten Zielgruppeneinstellungen auf die Auswahl von Anzeigen auswirken kann.
  • Berichterstellung zu Trainingseindrücken nach der Auswahl von Anzeigen.

Beschränkungen

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

Komponente Beschreibung des Limits Grenzwert
Benutzerdefinierte Zielgruppe (CA) Maximale Anzahl von Anzeigen pro Kampagnengruppe 100
Maximale Anzahl von CAs pro Anwendung 1000
Maximale Anzahl von Apps, die eine CA erstellen können 1000
Maximale Verzögerung bei der Aktivierungszeit einer CA ab dem Zeitpunkt ihrer Erstellung 60 Tage
Maximale Ablaufzeit einer CA ab dem Aktivierungszeitpunkt 60 Tage
Maximale Anzahl von Zertifizierungsstellen auf dem Gerät 4000
Maximale Größe des CA-Namens 200 Byte
Maximale Größe der URI für den täglichen Abruf 400 Byte
Maximale Größe der URI für die Gebotslogik 400 Byte
Maximale Größe vertrauenswürdiger Gebotsdaten 10 KB
Maximale Größe von Gebotssignalen für Nutzer 10 KB
Maximale Aufrufrate für leaveCustomAudience pro Käufer 1 pro Sekunde
Maximale Aufrufrate für joinCustomAudience pro Käufer 1 pro Sekunde
CA Background Fetch Zeitüberschreitung beim Verbindungsaufbau 5 Sekunden
HTTP-Lesezeitüberschreitung 30 Sekunden
Maximale Gesamtgröße des Downloads 10 KB
Maximale Dauer einer Abruf-Iteration 5 Minuten
Maximale Anzahl von CAs, die pro Job aktualisiert werden 1000
Anzeigenauswahl Maximale Anzahl von Käufern Noch offen
Maximale Anzahl von CAs pro Käufer Noch offen
Maximale Anzahl von Anzeigen in einer Auktion Noch offen
Zeitlimit für die erste Verbindung 5 Sekunden
Zeitüberschreitung beim Lesen der Verbindung 5 Sekunden
Maximale Ausführungszeit von insgesamt AdSelection 10 Sekunden
Maximale Ausführungszeit für Gebote pro CA in AdSelection 5 Sekunden
Maximale Ausführungszeit für die Bewertung in AdSelection 5 Sekunden
Maximale Ausführungszeit pro Käufer in AdSelection Noch offen
Maximale Größe von Signalen für die Anzeigenauswahl/Verkäufer/pro Käufer Noch offen
Maximale Größe von Verkäufer-/Käuferskripts Noch offen
Maximale Aufrufrate für selectAds 1 QPS
Berichte zu Impressionen Mindestzeit, bevor die Anzeigenauswahl aus dem persistenten Speicher entfernt wird 24 Stunden
Maximale Anzahl von Auswahlmöglichkeiten für Speicheranzeigen Noch offen
Maximale Größe der URL für die Berichtsausgabe Noch offen
Maximaler Zeitraum für das Melden von Impressionen Noch offen
Maximale Anzahl von Wiederholungsversuchen für Benachrichtigungsaufrufe Noch offen
Zeitüberschreitung der Verbindung 5 Sekunden
Maximale Gesamtausführungszeit für reportImpression 2 Sekunden
Maximale Aufrufrate für reportImpressions 1 QPS
Ereignisberichte Maximale Anzahl von Beacons pro Käufer und Auktion 10

Maximale Anzahl von Beacons pro Verkäufer und 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 beliebigen URL-Strings, der als Eingabe verwendet wird Noch offen
JavaScript Maximale Ausführungszeit 1 Sekunde für Gebote und Scoring für Impressionsberichte
Maximal verwendeter Arbeitsspeicher 10 MB

Fehler und Probleme melden

Ihr Feedback ist ein wichtiger Bestandteil der Privacy Sandbox für Android. Teilen Sie uns alle Probleme mit, die Sie finden, oder Ideen zur Verbesserung der Privacy Sandbox für Android.