Benutzerdefinierte native Anzeigenformate

Benutzerdefinierte native Anzeigenformate

Neben den systemdefinierten nativen Formaten haben Ad Manager-Publisher die Möglichkeit, eigene native Anzeigenformate zu erstellen, indem sie benutzerdefinierte Listen mit Assets definieren. Diese werden als benutzerdefinierte native Anzeigenformate bezeichnet und können mit reservierten Anzeigen verwendet werden. So können Publisher beliebige strukturierte Daten an ihre Apps übergeben. Diese Anzeigen werden durch das Objekt NativeCustomFormatAd dargestellt.

Benutzerdefinierte native Anzeigenformate laden

In dieser Anleitung wird erläutert, wie Sie benutzerdefinierte native Anzeigenformate laden und anzeigen.

AdLoader erstellen

Wie native Anzeigen werden auch benutzerdefinierte native Anzeigenformate mit der Klasse AdLoader geladen:

Java

AdLoader adLoader = new AdLoader.Builder(context, "/21775744923/example/native")
    .forCustomFormatAd("10063170",
      new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
          @Override
          public void onCustomFormatAdLoaded(NativeCustomFormatAd ad) {
              // Show the custom format and record an impression.
          }
      },
      new NativeCustomFormatAd.OnCustomClickListener() {
          @Override
          public void onCustomClick(NativeCustomFormatAd ad, String s) {
              // Handle the click action
          }
      })
    .withAdListener( ... )
    .withNativeAdOptions( ... )
    .build();

Kotlin

val adLoader = AdLoader.Builder(this, "/21775744923/example/native")
        .forCustomFormatAd("10063170",
            { ad ->
                // Show the custom format and record an impression.
            },
            { ad, s ->
            // Handle the click action
            })
        .withAdListener( ... )
        .withNativeAdOptions( ... )
        .build()

Mit der forCustomFormatAd-Methode wird die AdLoader so konfiguriert, dass benutzerdefinierte native Anzeigenformate angefordert werden. Es werden drei Parameter an die Methode übergeben:

  • Die ID des benutzerdefinierten nativen Anzeigenformats, das von AdLoader angefordert werden soll. Jedem benutzerdefinierten nativen Anzeigenformat ist eine ID zugewiesen. Dieser Parameter gibt an, in welchem Format die AdLoader von Ihrer App angefordert werden soll.
  • Ein OnCustomFormatAdLoadedListener, das aufgerufen wird, wenn eine Anzeige erfolgreich geladen wurde.
  • Optionale OnCustomClickListener, die aufgerufen werden soll, wenn der Nutzer auf die Anzeige tippt oder klickt. Weitere Informationen zu diesem Listener finden Sie unten im Abschnitt „Umgang mit Klicks und Impressionen“.

Da ein einzelner Anzeigenblock so eingerichtet werden kann, dass mehr als ein Creative-Format ausgeliefert wird, kann forCustomFormatAd mehrmals mit eindeutigen Format-IDs aufgerufen werden, um den Anzeigen-Lademechanismus auf mehrere mögliche benutzerdefinierte native Anzeigenformate vorzubereiten.

ID des benutzerdefinierten nativen Anzeigenformats

Die Format-ID, mit der ein benutzerdefiniertes natives Anzeigenformat identifiziert wird, finden Sie auf der Ad Manager-Benutzeroberfläche im Drop-down-Menü Auslieferung im Bereich Native:

Die ID jedes benutzerdefinierten nativen Anzeigenformats wird neben dem Namen angezeigt. Wenn Sie auf einen der Namen klicken, wird ein Detailbildschirm mit Informationen zu den Feldern des Formats angezeigt:

Hier können einzelne Felder hinzugefügt, bearbeitet und entfernt werden. Notiere dir den Namen jedes Assets. Der Name ist der Schlüssel, mit dem die Daten für jedes Asset abgerufen werden, wenn Ihr benutzerdefiniertes natives Anzeigenformat ausgeliefert wird.

Benutzerdefinierte native Anzeigenformate ausliefern

Benutzerdefinierte native Anzeigenformate unterscheiden sich von systemdefinierten Formaten dadurch, dass Publisher ihre eigene Liste der Assets definieren können, aus denen eine Anzeige besteht. Daher unterscheidet sich die Anzeige von benutzerdefinierten Formaten in einigen Punkten von systemdefinierten Formaten:

  1. Da die NativeCustomFormatAd-Klasse alle benutzerdefinierten nativen Anzeigenformate verarbeiten soll, die Sie in Ad Manager definieren, gibt es keine benannten „Getter“ für Assets. Stattdessen bietet es Methoden wie getText und getImage, die den Namen des Felds als Parameter annehmen.
  2. Es gibt keine spezielle Anzeigenansichtsklasse wie NativeAdView, die mit NativeCustomFormatAd verwendet werden kann. Sie können jedes Layout verwenden, das für Ihre Nutzererfahrung sinnvoll ist.
  3. Da es keine spezielle ViewGroup-Klasse gibt, müssen Sie keine der Ansichten registrieren, die Sie zum Darstellen der Assets der Anzeige verwenden. Dadurch sparen Sie beim Ausliefern der Anzeige einige Codezeilen. Sie müssen aber auch etwas mehr Aufwand betreiben, um Klicks später zu verarbeiten.

Hier ein Beispiel für eine Funktion, die ein NativeCustomFormatAd anzeigt:

Java

public void displayCustomFormatAd (ViewGroup parent,
                                     NativeCustomFormatAd customFormatAd) {
    // Inflate a layout and add it to the parent ViewGroup.
    LayoutInflater inflater = (LayoutInflater) parent.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View adView = inflater.inflate(R.layout.custom_format_ad, parent);

    // Locate the TextView that will hold the value for "Headline" and
    // set its text.
    TextView myHeadlineView = (TextView) adView.findViewById(R.id.headline);
    myHeadlineView.setText(customFormatAd.getText("Headline"));

    // Locate the ImageView that will hold the value for "MainImage" and
    // set its drawable.
    Button myMainImageView = (ImageView) adView.findViewById(R.id.main_image);
    myMainImageView.setImageDrawable(
            customFormatAd.getImage("MainImage").getDrawable());

    ...
    // Continue locating views and displaying assets until finished.
    ...
}

Kotlin

public fun displayCustomFormatAd (parent: ViewGroup,
                                customFormatAd: NativeCustomFormatAd) {
    val adView = layoutInflater
            .inflate(R.layout.ad_simple_custom_format, null)

    val myHeadlineView = adView.findViewById<TextView>(R.id.headline)
    myHeadlineView.setText(customFormatAd.getText("Headline"));

    // Locate the ImageView that will hold the value for "MainImage" and
    // set its drawable.
    val myMainImageView = adView.findViewById(R.id.main_image);
    myMainImageView.setImageDrawable(
            customFormatAd.getImage("MainImage").drawable);

    ...
    // Continue locating views and displaying assets until finished.
    ...
}

Rendern des Datenschutzinfo-Symbols

Im Rahmen der Unterstützung des Gesetzes über digitale Dienste (Gesetz über digitale Märkte, GDM) müssen Reservierungsanzeigen, die im Europäischen Wirtschaftsraum (EWR) ausgeliefert werden, das Datenschutzinfo-Symbol und einen Link zur Google-Seite „Infos zu dieser Anzeige“ enthalten. Wenn Sie benutzerdefinierte native Anzeigen implementieren, sind Sie für das Rendern des Datenschutzinfo-Symbols verantwortlich. Wir empfehlen, beim Rendern der Haupt-Anzeigen-Assets Schritte zu unternehmen, um den Klick-Listener für das Datenschutzinfo-Symbol zu rendern und einzurichten.

Im folgenden Beispiel wird davon ausgegangen, dass du in deiner Ansichtshierarchie ein <ImageView />-Element für das AdChoices-Logo definiert hast.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/adChoices"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:adjustViewBounds="true"
        android:contentDescription="AdChoices icon." />
</LinearLayout>

In den folgenden Beispielen wird das AdChoices-Symbol gerendert und das Klickverhalten konfiguriert.

Java

private AdSimpleCustomTemplateBinding customTemplateBinding;

private void populateAdView(final NativeCustomFormatAd nativeCustomFormatAd) {
  // Render the AdChoices icon.
  String adChoicesKey = NativeAdAssetNames.ASSET_ADCHOICES_CONTAINER_VIEW;
  NativeAd.Image adChoicesAsset = nativeCustomFormatAd.getImage(adChoicesKey);
  if (adChoicesAsset == null) {
    customTemplateBinding.adChoices.setVisibility(View.GONE);
  } else {
    customTemplateBinding.adChoices.setVisibility(View.VISIBLE);
    customTemplateBinding.adChoices.setImageDrawable(adChoicesAsset.getDrawable());

    // Enable clicks on AdChoices.
    customTemplateBinding.adChoices.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            nativeCustomFormatAd.performClick(adChoicesKey);
          }
        });
  }
  ...
}

Kotlin

private lateinit var customTemplateBinding: AdSimpleCustomTemplateBinding

private fun populateAdView(nativeCustomFormatAd: NativeCustomFormatAd) {
  // Render the AdChoices icon.
  val adChoicesKey = NativeAdAssetNames.ASSET_ADCHOICES_CONTAINER_VIEW
  val adChoicesAsset = nativeCustomFormatAd.getImage(adChoicesKey)
  if (adChoicesAsset == null) {
    customTemplateBinding.adChoices.visibility = View.GONE
  } else {
    customTemplateBinding.adChoices.setImageDrawable(adChoicesAsset.drawable)
    customTemplateBinding.adChoices.visibility = View.VISIBLE

    // Enable clicks on AdChoices.
    customTemplateBinding.adChoices.setOnClickListener {
      nativeCustomFormatAd.performClick(adChoicesKey)
    }
  }
  ...
}

Natives Video für benutzerdefinierte native Anzeigenformate

Wenn Sie ein benutzerdefiniertes Format erstellen, können Sie festlegen, dass es für Videos verwendet werden darf.

In Ihrer App-Implementierung können Sie NativeCustomFormatAd.getMediaContent() verwenden, um die Medieninhalte abzurufen. Rufen Sie dann setMediaContent() auf, um die Medieninhalte in Ihrer Medienansicht festzulegen. Wenn die Anzeige keine Videoinhalte hat, sollten Sie alternative Pläne für die Auslieferung der Anzeige ohne Video entwickeln.

Im folgenden Beispiel wird geprüft, ob die Anzeige Videocontent enthält. Wenn kein Video verfügbar ist, wird stattdessen ein Bild angezeigt:

Java

// Called when a custom native ad loads.
@Override
public void onCustomFormatAdLoaded(final NativeCustomFormatAd ad) {

  MediaContent mediaContent = ad.getMediaContent();

  // Assumes you have a FrameLayout in your view hierarchy with the id media_placeholder.
  FrameLayout mediaPlaceholder = (FrameLayout) findViewById(R.id.media_placeholder);

  // Apps can check the MediaContent's hasVideoContent property to determine if the
  // NativeCustomFormatAd has a video asset.
  if (mediaContent != null && mediaContent.hasVideoContent()) {
    MediaView mediaView = new MediaView(mediaPlaceholder.getContext());
    mediaView.setMediaContent(mediaContent);
    mediaPlaceholder.addView(mediaView);

    // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
    // VideoController will call methods on this object when events occur in the video
    // lifecycle.
    VideoController vc = mediaContent.getVideoController();
    vc.setVideoLifecycleCallbacks(
        new VideoController.VideoLifecycleCallbacks() {
          @Override
          public void onVideoEnd() {
            // Publishers should allow native ads to complete video playback before
            // refreshing or replacing them with another ad in the same UI location.
            super.onVideoEnd();
          }
        });
  } else {
    ImageView mainImage = new ImageView(this);
    mainImage.setAdjustViewBounds(true);
    mainImage.setImageDrawable(ad.getImage("MainImage").getDrawable());
    mediaPlaceholder.addView(mainImage);
    mainImage.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View view) {
            ad.performClick("MainImage");
          }
        });
  }
}

Kotlin

// Called when a custom native ad loads.
NativeCustomFormatAd.OnCustomFormatAdLoadedListener { ad ->

  val mediaContent = ad.mediaContent

  // Apps can check the MediaContent's hasVideoContent property to determine if the
  // NativeCustomFormatAd has a video asset.
  if (mediaContent != null && mediaContent.hasVideoContent()) {
    val mediaView = MediaView(mediaPlaceholder.getContest())
    mediaView.mediaContent = mediaContent

    val videoController = mediaContent.videoController

    // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
    // VideoController will call methods on this object when events occur in the video
    // lifecycle.
    if (videoController != null) {
      videoController.videoLifecycleCallbacks =
        object : VideoController.VideoLifecycleCallbacks() {
          override fun onVideoEnd() {
            // Publishers should allow native ads to complete video playback before refreshing
            // or replacing them with another ad in the same UI location.
            super.onVideoEnd()
          }
        }
    }
  } else {
    val mainImage = ImageView(this)
    mainImage.adjustViewBounds = true
    mainImage.setImageDrawable(ad.getImage("MainImage")?.drawable)

    mainImage.setOnClickListener { ad.performClick("MainImage") }
    customTemplateBinding.simplecustomMediaPlaceholder.addView(mainImage)
  }
}

Weitere Informationen dazu, wie Sie die Videowiedergabe einer benutzerdefinierten nativen Anzeige anpassen können, finden Sie unter MediaContent.

Laden Sie das Beispiel für benutzerdefiniertes Rendering in Ad Manager herunter, um ein funktionierendes Beispiel für native Videos zu sehen.

Klicks und Impressionen bei benutzerdefinierten nativen Anzeigenformaten

Bei benutzerdefinierten nativen Anzeigenformaten ist Ihre App dafür verantwortlich, Impressionen zu erfassen und Klickereignisse an das Google Mobile Ads SDK zu melden.

Impressionen erfassen

Wenn Sie eine Impression für eine Anzeige im benutzerdefinierten Format erfassen möchten, rufen Sie die Methode recordImpression für die entsprechende NativeCustomFormatAd auf:

myCustomFormatAd.recordImpression();

Wenn Ihre App die Methode versehentlich zweimal für dieselbe Anzeige aufruft, verhindert das SDK automatisch, dass für eine einzelne Anfrage eine doppelte Impression erfasst wird.

Klicks melden

Wenn du dem SDK mitteilen möchtest, dass ein Klick auf eine Asset-Ansicht erfolgt ist, rufe die Methode performClick für die entsprechende NativeCustomFormatAd auf und gib den Namen des Assets an, auf das geklickt wurde. Wenn Sie beispielsweise ein Asset in Ihrem benutzerdefinierten Format namens „MainImage“ haben und einen Klick auf die ImageView erfassen möchten, die diesem Asset entspricht, würde Ihr Code so aussehen:

myCustomFormatAd.performClick("MainImage");

Sie müssen diese Methode nicht für jede Wiedergabe aufrufen, die mit Ihrer Anzeige verknüpft ist. Wenn du ein weiteres Feld namens „Caption“ hast, das angezeigt werden soll, aber nicht vom Nutzer angeklickt oder angetippt wird, muss deine App performClick für die Ansicht dieses Assets nicht aufrufen.

Auf benutzerdefinierte Klickaktionen reagieren

Wenn auf eine Anzeige im benutzerdefinierten Format geklickt wird, gibt es drei mögliche Antworten vom SDK, die in dieser Reihenfolge versucht werden:

  1. Rufe die OnCustomClickListener von AdLoader auf, falls eine angegeben wurde.
  2. Versuchen Sie, für jede der Deeplink-URLs der Anzeige einen Content-Resolver zu finden, und starten Sie den ersten, der gefunden wird.
  3. Öffnen Sie einen Browser und rufen Sie die klassische Ziel-URL der Anzeige auf.

Die forCustomFormatAd-Methode akzeptiert eine OnCustomClickListener. Wenn Sie ein Listener-Objekt übergeben, ruft das SDK stattdessen die onCustomClick-Methode auf und ergreift keine weiteren Maßnahmen. Wenn Sie jedoch einen Nullwert als Listener übergeben, greift das SDK auf den Deeplink und/oder die Ziel-URLs zurück, die mit der Anzeige registriert sind.

Mit benutzerdefinierten Klick-Listenern kann Ihre App entscheiden, welche Aktion auf einen Klick erfolgen soll, z. B. die Aktualisierung der Benutzeroberfläche, das Starten einer neuen Aktivität oder das einfache Protokollieren des Klicks. Hier ein Beispiel, in dem einfach protokolliert wird, dass ein Klick stattgefunden hat:

Java

AdLoader adLoader = new AdLoader.Builder(context, "/21775744923/example/native")
    .forCustomFormatAd("10063170",
      new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
        // Display the ad.
      },
      new NativeCustomFormatAd.OnCustomClickListener() {
          @Override
          public void onCustomClick(NativeCustomFormatAd ad, String assetName) {
            Log.i("MyApp", "A custom click just happened for " + assetName + "!");
          }
      }).build();

Kotlin

val adLoader = AdLoader.Builder(this, "/21775744923/example/native")
    .forCustomFormatAd("10063170",
        { ad ->
            // Display the ad.
        },
        { ad, assetName ->
                Log.i("MyApp", "A custom click just happened for $assetName!")
    }).build()

Auf den ersten Blick mag es seltsam erscheinen, dass es benutzerdefinierte Klick-Listener gibt. Schließlich hat Ihre App dem SDK gerade mitgeteilt, dass ein Klick stattgefunden hat. Warum sollte das SDK das dann noch einmal an die App melden?

Dieser Informationsfluss ist aus mehreren Gründen nützlich. Vor allem aber ermöglicht er es dem SDK, die Reaktion auf den Klick zu steuern. Es kann beispielsweise automatisch Tracking-URLs von Drittanbietern anpingen, die für das Creative festgelegt wurden, und andere Aufgaben im Hintergrund ausführen, ohne zusätzlichen Code.