Entwicklung von Gebotsadaptern

Dieser Leitfaden richtet sich an Werbenetzwerke, die einen Gebotsadapter erstellen möchten, um an Echtzeitgeboten (Real-Time Bidding, RTB) in der Google-Vermittlung teilzunehmen. Wenn Sie Publisher sind, lesen Sie die Anleitung zur Publisher-Vermittlung.

Ein Gebotsadapter ist der clientseitige Teil der Integration. Über den Adapter kann das SDK Ihres Anzeigennetzwerks mit dem Google Mobile Ads SDK kommunizieren, um Anzeigen zu laden, die von Ihrem Bieter ausgeliefert werden.

Damit Gebote richtig funktionieren, muss Ihr Adapter die Initialisierung, das Erfassen von Signalen, das Laden von Anzeigen und die Weiterleitung von Ereignissen des Anzeigenlebenszyklus verarbeiten. In diesem Leitfaden zeigen wir Ihnen, wie Ihr Adapter für die Verarbeitung dieser Vorgänge implementiert werden sollte.

Workflow eines Gebotsadapters

Initialisierung

Unten ist ein detaillierter Ablauf des gesamten Lebenszyklus von Anfrage, Antwort und Rendering eines Adapters dargestellt:

Der Adapter ist für die folgenden Teile des Workflows verantwortlich:

  • Schritte 4–7: Initialisieren Sie den Adapter und rufen Sie das Google Mobile Ads SDK zurück, sobald die Initialisierung abgeschlossen ist.

  • Schritte 10–13: Signale aus dem SDK Ihres Werbenetzwerks erfassen, an Ihren Bieter senden, damit er an einer RTB-Anfrage teilnehmen kann, und an das Google Mobile Ads SDK weiterleiten.

  • Schritte 18–21: Wenn Ihre Gebotsfunktion das erfolgreiche Gebot zurückgibt, laden Sie die Anzeige gemäß der Antwort Ihrer Gebotsfunktion. Benachrichtigen Sie das Google Mobile Ads SDK, sobald die Anzeige geladen wurde.

  • Schritt 23 und höher: Während die Anzeige ausgeliefert wird, benachrichtigen Sie das Google Mobile Ads SDK über Impressions- und Klickereignisse sowie andere Anzeigenereignisse, die während des Präsentationszyklus Ihrer Anzeige auftreten.

Gebotsadapter implementieren

Wenn Sie einen Gebotsadapter für das Google Mobile Ads SDK erstellen möchten, müssen Sie die abstrakte Klasse RtbAdapter erweitern. In den folgenden Abschnitten werden die einzelnen abstrakten Methoden in RtbAdapter erläutert.

getSDKVersionInfo()

Hier sollten Sie die Version Ihres SDKs zurückgeben. Diese Version wird als Teil der OpenRTB-Anfrage an Ihren Bieter übergeben.

Bei dieser Methode müssen Sie eine VersionInfo zurückgeben. Im folgenden Beispiel wird gezeigt, wie Sie die Stringversion Ihres SDKs in einen VersionInfo. konvertieren können.

@Override
public VersionInfo getSDKVersionInfo() {
  // Get your SDK's version as a string. E.g. "1.2.3"
  // String versionString = YourSdk.getVersion();
  String splits[] = versionString.split("\\.");
  if (splits.length >= 3) {
      int major = Integer.parseInt(splits[0]);
      int minor = Integer.parseInt(splits[1]);
      int micro = Integer.parseInt(splits[2]);
      return new VersionInfo(major, minor, micro);
   }

   String logMessage = String.format("Unexpected SDK version format: %s." +
           "Returning 0.0.0 for SDK version.", sdkVersion);
   Log.w(TAG, logMessage);
   return new VersionInfo(0, 0, 0);
}

getVersionInfo()

Geben Sie hier die Version Ihres Adapters an. Diese Version wird als Teil der OpenRTB-Anfrage an Ihren Bieter übergeben.

Die Open-Source- und versionierten Adapter von Google verwenden ein vierstelliges Adapterversionierungsschema, die VersionInfo erlaubt jedoch nur drei Ziffern. Um dieses Problem zu umgehen, wird empfohlen, die letzten beiden Ziffern in die Patchversion aufzunehmen, wie unten dargestellt.

@Override
public VersionInfo getVersionInfo() {
  // Get your adapters's version as a string. E.g. "1.2.3.0"
  String versionString = BuildConfig.VERSION_NAME;
  String splits[] = versionString.split("\\.");
  if (splits.length >= 4) {
      int major = Integer.parseInt(splits[0]);
      int minor = Integer.parseInt(splits[1]);
      int micro = Integer.parseInt(splits[2]) * 100 + Integer.parseInt(splits[3]);
      return new VersionInfo(major, minor, micro);
    }

    String logMessage = String.format("Unexpected adapter version format: %s." +
                "Returning 0.0.0 for adapter version.", versionString);
    Log.w(TAG, logMessage);
    return new VersionInfo(0, 0, 0);
}

initialize()

Zeitlimit: 30 Sekunden

Die Methode initialize() ist die erste Methode, die in Ihrem Adapter aufgerufen wird. Es wird nur einmal pro Sitzung aufgerufen. Mit dieser Methode erhalten Sie eine Liste von MediationConfiguration-Objekten, die die vollständige Liste der Placements in dieser App darstellen, die für Ihr Werbenetzwerk konfiguriert sind. Sie können diese Liste durchgehen, um die Anmeldedaten für jedes Placement zu parsen und relevante Daten zur Initialisierung an Ihr SDK weiterzugeben.

Sobald Ihr SDK initialisiert ist und Anzeigenanfragen empfangen kann, rufen Sie die Methode onInitializationSucceeded() des InitializationCompleteCallback auf. Dieser Rückruf wird an die App-Publisher weitergeleitet, damit sie wissen, dass sie mit dem Laden von Anzeigen beginnen können.

@Override
public void initialize(Context context,
    InitializationCompleteCallback initializationCompleteCallback,
    List<MediationConfiguration> mediationConfigurations) {
  // Initialize your ad network's SDK.
  ...

  // Invoke the InitializationCompleteCallback once initialization completes.
  initializationCompleteCallback.onInitializationSucceeded();
}

collectSignals()

Zeitlimit: 1 Sekunde

Jedes Mal, wenn der Publisher eine Anzeige anfordert, wird eine neue Instanz Ihrer RtbAdapter erstellt und die Methode collectSignals() aufgerufen. Diese Instanz von RtbAdapter wird für die Dauer des Lebenszyklus der Anzeigenanfrage, -antwort und -rendering für diese Anzeige verwendet. Mit der Methode collectSignals() kann Ihr Adapter Signale vom Gerät bereitstellen, die in einer OpenRTB-Anfrage an Ihren Bieter gesendet werden.

collectSignals() wird in einem Hintergrund-Thread aufgerufen. Das Google Mobile Ads SDK fordert gleichzeitig Signale von allen Adaptern an, die an Geboten teilnehmen. Bitte seien Sie während dieser Zeit verständnisvoll und beschränken Sie Anfragen an den UI-Thread. Alle aufwendigen Aufgaben, die Ihr Adapter oder SDK zum Erfassen von Signalen ausführen muss, sollten in der initialize()-Methode ausgeführt und im Cache gespeichert werden.

Rufe den onSuccess()-Callback mit deinen codierten Signalen auf, sobald du sie hast.

Hier ein Beispiel für eine Implementierung:

@Override
public void collectSignals(RtbSignalData rtbSignalData,
                           SignalCallbacks signalCallbacks) {
  String signals = YourSdk.getSignals();
  signalCallbacks.onSuccess(signals);
}

Wenn Ihr Adapter keine Signale erfasst, rufen Sie signalCallbacks.onFailure() mit einem String auf, in dem der aufgetretene Fehler beschrieben wird.

Methoden zum Laden von Anzeigen implementieren

Zeitlimit: 10 Sekunden

Wenn Ihr Bieter den Gewinnerpreis zurückgibt, ruft das Google Mobile Ads SDK Ihren Adapter auf, um die Gewinneranzeige zu laden. Dabei werden alle Daten übergeben, die Ihr Bieter zurückgegeben hat und die Ihr SDK zum Laden der Anzeige benötigt.

Welche Lademethode genau aufgerufen wird, hängt vom Anzeigenformat ab, für das diese Anfrage bestimmt ist:

Anzeigenformat Lademethode
Banner loadBannerAd()
Interstitial loadInterstitialAd()
Verfügbar loadRewardedAd()

Implementieren Sie diese Methoden für die Anzeigenformate, die Ihr Adapter unterstützt.

Die Methode „load“ wird im UI-Thread auf derselben Instanz des Adapters aufgerufen, von dem Sie Signale bereitgestellt haben. Diese Methode bietet die folgenden Parameter:

  • Eine MediationAdConfiguration, die Parameter enthält, die Ihr SDK zum Laden der Anzeige für das Gewinnergebot benötigt, z. B. die Gebotsantwort und alle Anmeldedaten, die der Publisher in der AdMob-Benutzeroberfläche konfiguriert hat.

  • Ein MediationAdLoadCallback-Objekt, mit dem das Google Mobile Ads SDK darüber informiert wird, ob das Laden erfolgreich war oder fehlgeschlagen ist.

Rufen Sie mediationAdLoadCallback.onSuccess() auf, sobald das SDK die Anzeige geladen hat. Wenn das Laden der Anzeige fehlschlägt, rufe mediationAdLoadCallback.onFailure() mit einem String auf, der den aufgetretenen Fehler beschreibt.

Für die Methode mediationAdLoadCallback.onSuccess() müssen Sie ein Objekt übergeben, das einer der vom Google Mobile Ads SDK definierten „Anzeigen“-Schnittstellen entspricht. Auf diesen Anzeigenoberflächen werden Sie gebeten, einige Informationen zur Anzeige anzugeben.

MediationAdConfiguration bietet auch die Methode getWatermark(), um einen Base64-codierten String zurückzugeben, der ein PNG-Bild darstellt. Dieses Bild sollte in einem transparenten Overlay in Ihren Anzeigen gekachtelt werden. Weitere Informationen zum Rendern des Wasserzeichens erhalten Sie von Google. Es enthält Metadaten zur ausgelieferten Anzeige, anhand derer Publisher die Quelle der ausgelieferten Anzeigen ermitteln können.

Bei Bannern müssen Sie die Banneransicht angeben. Bei Interstitial- und Anzeigen mit Prämie müssen Sie eine show()-Methode implementieren, um die Anzeige zu einem späteren Zeitpunkt zu präsentieren. Als Best Practice empfehlen wir, dass die Klasse, die das Anzeigenladen übernimmt, auch für die Implementierung dieser Anzeigenmethoden verantwortlich ist.

Im Folgenden finden Sie eine Beispielimplementierung von loadBannerAd(). Die Implementierung deines Adapters sieht anders aus, da er in ein anderes SDK eingebunden ist.

public final class SampleRtbAdapter extends RtbAdapter {
  ...

  @Override
  public void loadBannerAd(
      MediationBannerAdConfiguration adConfiguration,
      MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> callback) {

      SampleBannerRenderer bannerRenderer =
          new SampleBannerRenderer(adConfiguration, callback);
      bannerRenderer.render();
    }
}

// Renders a banner ad, and forwards callbacks to the Google Mobile Ads SDK.
public class SampleBannerRenderer implements MediationBannerAd {
  private MediationBannerAdConfiguration adConfiguration;
  private final MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> adLoadCallback;
  private AdView adView;
  private MediationBannerAdCallback callback;

  public SampleRtbBannerRenderer(
      MediationBannerAdConfiguration adConfiguration,
      MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> adLoadCallback) {
    this.adConfiguration = adConfiguration;
    this.adLoadCallback = adLoadCallback;
  }

  public void render() {
    adView = new AdView(adConfiguration.getContext());
    adView.setAdSize(adConfiguration.getAdSize());
    // serverParameters are the parameters entered in the AdMob UI for your network.
    adView.setAdUnitId(adConfiguration.getServerParameters().getString("adUnitId"));

    // Map the callbacks from your SDK to Google's SDK.
    adView.setAdListener(new AdListener() {
      // See the next step for more information on callback mapping.
      // ...
    });

    // Get the bid response and watermark from the ad configuration and
    // pass the relevant information to your SDK.
    String ad = adConfiguration.getBidResponse();
    String watermark = adConfiguration.getWatermark();
    Bundle extras = new Bundle();
    extras.putString("bid", ad);
    extras.putString("watermark", watermark);
    AdRequest request = new AdRequest.Builder()
        .addNetworkExtrasBundle(AdMobAdapter.class, extras)
        .build();
    adView.loadAd(request);
  }

  // MediationBannerAd implementation

  @NonNull
  @Override
  public View getView() {
    return adView;
  }
}

Lebenszyklusereignisse für die Anzeigenpräsentation weitergeben

Der Adapter muss das Google Mobile Ads SDK über alle Ereignisse des Präsentationszyklus informieren, damit sie an den Publisher weitergeleitet werden können. Der Publisher erwartet diese Rückrufe zu bestimmten Zeiten, unabhängig davon, über welches Werbenetzwerk die Anzeige ausgeliefert wird. Daher ist es wichtig, dass so viele dieser Rückrufe wie möglich und zur richtigen Zeit aufgerufen werden, damit das Google Mobile Ads SDK sie an den Publisher weiterleiten kann.

Adapter sollten gegebenenfalls die folgenden Ereignisse auslösen:

Für alle Formate gleich
Methode Wann anrufen
reportAdClicked() Es wurde auf die Anzeige geklickt.
reportAdImpression() Die Anzeige hat eine Impression generiert.
onAdOpened() Die Anzeige wurde im Vollbildmodus präsentiert.
onAdClosed() Die Vollbildansicht der Anzeige wurde geschlossen.
onAdLeftApplication() Die Anzeige hat dazu geführt, dass der Nutzer die App verlassen hat.
Anzeigen mit Prämie
onRewarded() Der Nutzer erhält eine Prämie.
Video-Callbacks (Videoanzeigen mit Prämie und native Videoanzeigen)
onVideoStarted() Das Video der Anzeige wurde gestartet.
onVideoCompleted() Das Video der Anzeige ist zu Ende.

Der Adapter erhält beim Aufrufen von mediationAdLoadCallback.onSuccess() ein MediationAdLoadCallback<MediationAdT, MediationAdCallbackT>-Objekt zurück. Adapter sollten dieses Objekt beibehalten und damit Präsentationsereignisse auslösen, die in Ihrer Anzeige auftreten.

In der Regel werden die meisten dieser Ereignisse vom SDK Ihres Werbenetzwerks ausgelöst. Die Aufgabe des Adapters besteht lediglich darin, die Rückrufe aus dem SDK Ihres Werbenetzwerks dem Google Mobile Ads SDK zuzuordnen.

Im folgenden Beispiel wird gezeigt, wie Sie Callbacks vom Anzeigen-Listener Ihres SDK an das Google Mobile Ads SDK weiterleiten:

adView.setAdListener(new AdListener() {
    public void onAdLoaded() {
        callback = adLoadCallback.onSuccess(SampleBannerRenderer.this);
    }

    public void onAdImpression() {
        if (callback != null) {
            callback.reportAdImpression();
        }
    }

    public void onAdFailedToLoad(LoadAdError adError) {
        adLoadCallback.onFailure("Error: " + adError.toString());
    }

    public void onAdClosed() {
        if (callback != null) {
            callback.onAdClosed();
        }
    }

    public void onAdOpened() {
        if (callback != null) {
            callback.onAdOpened();
            callback.reportAdClicked();
        }
    }

    public void onAdLeftApplication() {
        if (callback != null) {
            callback.onAdLeftApplication();
        }
    }
});

Erforderliche Assets für das Impressions-Tracking bei nativen Anzeigen

Das Google Mobile Ads SDK erfasst eine Impression für eine native Anzeige, wenn ein Pixel der Anzeige sichtbar ist. Wenn für Ihr Werbenetzwerk-SDK bestimmte Assets ausgeliefert werden müssen, um eine gültige Impression zu erzielen, kann Ihr Bieter diese erforderlichen nativen Assets in der Gebotsantwort angeben. Das Google Mobile Ads SDK prüft dann, ob die erforderlichen nativen Assets ausgeliefert werden, bevor eine Impression erfasst wird.

Weitere Informationen dazu, wie Sie zusätzliche erforderliche Assets in der Gebotsantwort angeben, finden Sie in der Dokumentation zu erforderlichen nativen Assets.

Anzeigenfehler anzeigen

Bei Vollbildformaten wie Interstitial- und Anzeigen mit Prämie müssen Sie im Erfolgs-Lade-Callback eine Implementierung von MediationInterstitialAd oder MediationRewardedAd bereitstellen, damit das Google Mobile Ads SDK Ihren Adapter auffordern kann, die Anzeige zu präsentieren.

Das Google Mobile Ads SDK geht davon aus, dass eine Anzeige, die von einem Adapter geladen wurde, bereit ist, wenn der Publisher sie anzeigt. Das bedeutet, dass jeder Aufruf zum Anzeigen sollte zu einer Impression führen.

Es kann jedoch Fälle geben, in denen keine Anzeige ausgeliefert werden kann. Wenn die Anzeige nicht ausgeliefert werden kann, rufen Sie den Callback onAdFailedToShow() auf, um die Impression abzubrechen.

In der folgenden Tabelle sehen Sie, wie sich Präsentations-Callbacks auf die Erfassung von Impressionen für Vollbildanzeigen auswirken:

Rückruf Ergebnis
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
Keine der oben genannten Optionen für mehrere Sekunden Impression recorded

1 Bei fehlgeschlagenen Impressionen wird Ihrem Werbenetzwerk die Impression nicht in Rechnung gestellt. Sie wirkt sich jedoch auf die abrechenbare Anpassung der Ereignisrate aus. Weitere Informationen finden Sie unter Signale in Gebotsanfragen.

Das folgende Beispiel zeigt einen Lade-/Auslieferungszyklus, bei dem ein Aufruf zum Anzeigen einer Anzeige zu einem Fehler führen kann.

final class SampleRtbAdapter extends RtbAdapter implements MediationRewardedAd {

 private MediationRewardedAdCallback callback;
 private RewardedAd rewardedAd;

 ...

  @Override
  public void loadRewardedAd(
      MediationRewardedAdConfiguration adConfiguration,
      final MediationAdLoadCallback<MediationRewardedAd, MediationRewardedAdCallback> loadCallback) {

    // Load an ad. This mock example uses Google's SDK, but in practice
    // your adapter will load the ad using your ad network's SDK.
    RewardedAd.load(adConfiguration.getContext(),
        "ca-app-pub-3940256099942544/5224354917",
        new AdRequest.Builder().build(),
        new RewardedAdLoadCallback() {
          @Override
          public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
            // When the ad loads, invoke the load success callback.
            callback = loadCallback.onSuccess(SampleRtbAdapter.this);
          }
        });
  }

  @Override
  public void showAd(Context context) {
    // In this mock example, your ad network requires an activity context, but
    // didn't receive one, making you unable to show the ad.
    if (!(context instanceof Activity)) {
      AdError error = new AdError(1, "Context must be an activity",
          "com.google.ads.mediation.sample");
      callback.onAdFailedToShow(error);
    }

    // This example shows Google SDK's callbacks, but it's likely your SDK
    // has similar presentation callbacks.
    rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
      @Override
      public void onAdShowedFullScreenContent() {
        // Your ad network SDK successfully showed the ad. Call onAdOpened().
        callback.onAdOpened();
      }

      @Override
      public void onAdFailedToShowFullScreenContent(AdError adError) {
        // Your ad network SDK failed to show the ad, invoke onAdFailedToShow.
        // In practice, you will map your SDK's error to an AdError.
        AdError error = new AdError(adError.getCode(), adError.getMessage(),
            adError.getDomain());
        callback.onAdFailedToShow(adError);
      }
    });


    rewardedAd.show((Activity) context, ...);
  }
}