Eventos personalizados de anuncios nativos

Requisitos previos

Completa la configuración de eventos personalizados.

Cómo solicitar un anuncio nativo

Cuando se alcanza el concepto de línea de pedido del evento personalizado en la cadena de mediación en cascada, se llama al método loadNativeAd() en el nombre de la clase que proporcionaste cuando creaste un evento personalizado. En este caso, ese método se encuentra en SampleCustomEvent, que luego llama al método loadNativeAd() en SampleNativeCustomEventLoader.

Para solicitar un anuncio nativo, crea o modifica una clase que extienda Adapter para implementar loadNativeAd(). Si ya existe una clase que extiende Adapter, implementa loadNativeAd() allí. Además, crea una clase nueva para implementar UnifiedNativeAdMapper.

En nuestro ejemplo de evento personalizado, SampleCustomEvent extiende la clase Adapter y, luego, delega en SampleNativeCustomEventLoader.

Java

package com.google.ads.mediation.sample.customevent;

import com.google.android.gms.ads.mediation.Adapter;
import com.google.android.gms.ads.mediation.MediationAdConfiguration;
import com.google.android.gms.ads.mediation.MediationAdLoadCallback;

import com.google.android.gms.ads.mediation.MediationNativeAdCallback;
...
public class SampleCustomEvent extends Adapter {
  private SampleNativeCustomEventLoader nativeLoader;

  @Override
  public void loadNativeAd(
      @NonNull MediationNativeAdConfiguration adConfiguration,
      @NonNull MediationAdLoadCallback<UnifiedNativeAdMapper, MediationNativeAdCallback> callback) {
    nativeLoader = new SampleNativeCustomEventLoader(adConfiguration, callback);
    nativeLoader.loadAd();
  }
}

SampleNativeCustomEventLoader es responsable de las siguientes tareas:

  • Se está cargando el anuncio nativo.

  • Implementar la clase UnifiedNativeAdMapper

  • Recibir y registrar devoluciones de llamada de eventos de anuncios en el SDK de anuncios de Google para dispositivos móviles

El parámetro opcional definido en la IU de Ad Manager se incluye en la configuración del anuncio. Se puede acceder al parámetro a través de adConfiguration.getServerParameters().getString(MediationConfiguration.CUSTOM_EVENT_SERVER_PARAMETER_FIELD). Por lo general, este parámetro es un identificador de unidad de anuncios que requiere un SDK de red publicitaria cuando se crea una instancia de un objeto de anuncio.

Java

package com.google.ads.mediation.sample.customevent;

import com.google.android.gms.ads.mediation.Adapter;
import com.google.android.gms.ads.mediation.MediationNativeAdConfiguration;
import com.google.android.gms.ads.mediation.MediationAdLoadCallback;
import com.google.android.gms.ads.mediation.MediationNativeAdCallback;
...

public class SampleNativeCustomEventLoader extends SampleNativeAdListener {
  /** Configuration for requesting the native ad from the third-party network. */
  private final MediationNativeAdConfiguration mediationNativeAdConfiguration;

  /** Callback that fires on loading success or failure. */
  private final MediationAdLoadCallback<UnifiedNativeAdMapper, MediationNativeAdCallback>
      mediationAdLoadCallback;

  /** Callback for native ad events. */
  private MediationNativeAdCallback nativeAdCallback;

  /** Constructor */
  public SampleNativeCustomEventLoader(
      @NonNull MediationNativeAdConfiguration mediationNativeAdConfiguration,
      @NonNull MediationAdLoadCallback<MediationNativeAd, MediationNativeAdCallback>
              mediationAdLoadCallback) {
    this.mediationNativeAdConfiguration = mediationNativeAdConfiguration;
    this.mediationAdLoadCallback = mediationAdLoadCallback;
  }

  /** Loads the native ad from the third-party ad network. */
  public void loadAd() {
    // Create one of the Sample SDK's ad loaders to request ads.
    Log.i("NativeCustomEvent", "Begin loading native ad.");
    SampleNativeAdLoader loader =
        new SampleNativeAdLoader(mediationNativeAdConfiguration.getContext());

    // All custom events have a server parameter named "parameter" that returns
    // back the parameter entered into the UI when defining the custom event.
    String serverParameter = mediationNativeAdConfiguration
        .getServerParameters()
        .getString(MediationConfiguration
        .CUSTOM_EVENT_SERVER_PARAMETER_FIELD);
    Log.d("NativeCustomEvent", "Received server parameter.");

    loader.setAdUnit(serverParameter);

    // Create a native request to give to the SampleNativeAdLoader.
    SampleNativeAdRequest request = new SampleNativeAdRequest();
    NativeAdOptions options = mediationNativeAdConfiguration.getNativeAdOptions();
    if (options != null) {
      // If the NativeAdOptions' shouldReturnUrlsForImageAssets is true, the adapter should
      // send just the URLs for the images.
      request.setShouldDownloadImages(!options.shouldReturnUrlsForImageAssets());

      request.setShouldDownloadMultipleImages(options.shouldRequestMultipleImages());
      switch (options.getMediaAspectRatio()) {
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_LANDSCAPE:
          request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_LANDSCAPE);
          break;
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_PORTRAIT:
          request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_PORTRAIT);
          break;
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_SQUARE:
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_ANY:
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_UNKNOWN:
        default:
          request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_ANY);
      }
    }

    loader.setNativeAdListener(this);

    // Begin a request.
    Log.i("NativeCustomEvent", "Start fetching native ad.");
    loader.fetchAd(request);
  }
}

Según si el anuncio se recupera correctamente o si se produce un error, llamarás a onSuccess() o a onFailure(). Se llama a onSuccess() pasando una instancia de la clase que implementa MediationNativeAd.

Por lo general, estos métodos se implementan dentro de las devoluciones de llamada del SDK de terceros que implementa tu adaptador. En este ejemplo, el SDK de muestra tiene un SampleAdListener con devoluciones de llamada relevantes:

Java

@Override
public void onNativeAdFetched(SampleNativeAd ad) {
  SampleUnifiedNativeAdMapper mapper = new SampleUnifiedNativeAdMapper(ad);
  mediationNativeAdCallback = mediationAdLoadCallback.onSuccess(mapper);
}

@Override
public void onAdFetchFailed(SampleErrorCode errorCode) {
  mediationAdLoadCallback.onFailure(SampleCustomEventError.createSampleSdkError(errorCode));
}

Anuncios nativos en el mapa

Cada SDK tiene sus propios formatos únicos para los anuncios nativos. Por ejemplo, uno podría devolver objetos que contengan un campo "title", mientras que otro podría tener el campo "headline". Además, los métodos que se usan para hacer un seguimiento de las impresiones y procesar los clics pueden variar entre un SDK y otro.

El objeto UnifiedNativeAdMapper es responsable de conciliar estas diferencias y adaptar el objeto de anuncio nativo de un SDK mediado para que coincida con la interfaz que espera el SDK de anuncios de Google para dispositivos móviles. Los eventos personalizados deben extender esta clase para crear sus propios asignadores específicos para su SDK mediado. A continuación, se muestra un ejemplo de asignador de anuncios de nuestro proyecto de eventos personalizados de ejemplo:

Java

package com.google.ads.mediation.sample.customevent;

import com.google.android.gms.ads.mediation.UnifiedNativeAdMapper;
import com.google.android.gms.ads.nativead.NativeAd;
...

public class SampleUnifiedNativeAdMapper extends UnifiedNativeAdMapper {

  private final SampleNativeAd sampleAd;

  public SampleUnifiedNativeAdMapper(SampleNativeAd ad) {
    sampleAd = ad;
    setHeadline(sampleAd.getHeadline());
    setBody(sampleAd.getBody());
    setCallToAction(sampleAd.getCallToAction());
    setStarRating(sampleAd.getStarRating());
    setStore(sampleAd.getStoreName());
    setIcon(
        new SampleNativeMappedImage(
            ad.getIcon(), ad.getIconUri(), SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));
    setAdvertiser(ad.getAdvertiser());

    List<NativeAd.Image> imagesList = new ArrayList<NativeAd.Image>();
    imagesList.add(new SampleNativeMappedImage(ad.getImage(), ad.getImageUri(),
        SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));
    setImages(imagesList);

    if (sampleAd.getPrice() != null) {
      NumberFormat formatter = NumberFormat.getCurrencyInstance();
      String priceString = formatter.format(sampleAd.getPrice());
      setPrice(priceString);
    }

    Bundle extras = new Bundle();
    extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, ad.getDegreeOfAwesomeness());
    this.setExtras(extras);

    setOverrideClickHandling(false);
    setOverrideImpressionRecording(false);

    setAdChoicesContent(sampleAd.getInformationIcon());
  }

  @Override
  public void recordImpression() {
    sampleAd.recordImpression();
  }

  @Override
  public void handleClick(View view) {
    sampleAd.handleClick(view);
  }

  // The Sample SDK doesn't do its own impression/click tracking, instead relies on its
  // publishers calling the recordImpression and handleClick methods on its native ad object. So
  // there's no need to pass a reference to the View being used to display the native ad. If
  // your mediated network does need a reference to the view, the following method can be used
  // to provide one.

  @Override
  public void trackViews(View containerView, Map<String, View> clickableAssetViews,
      Map<String, View> nonClickableAssetViews) {
    super.trackViews(containerView, clickableAssetViews, nonClickableAssetViews);
    // If your ad network SDK does its own impression tracking, here is where you can track the
    // top level native ad view and its individual asset views.
  }

  @Override
  public void untrackView(View view) {
    super.untrackView(view);
    // Here you would remove any trackers from the View added in trackView.
  }
}

Ahora, analizaremos el código del constructor con más detalle.

Mantén una referencia al objeto de anuncio nativo mediado

El constructor acepta el parámetro SampleNativeAd, la clase de anuncio nativo que usa el SDK de muestra para sus anuncios nativos. El asignador necesita una referencia al anuncio mediado para poder pasar los eventos de impresiones y clics. SampleNativeAd se almacena como una variable local.

Cómo establecer propiedades de elementos asignados

El constructor usa el objeto SampleNativeAd para propagar recursos en UnifiedNativeAdMapper.

Este fragmento obtiene los datos de precios del anuncio mediado y los usa para establecer el precio del asignador:

Java

if (sampleAd.getPrice() != null) {
    NumberFormat formatter = NumberFormat.getCurrencyInstance();
    String priceString = formatter.format(sampleAd.getPrice());
    setPrice(priceString);
}

En este ejemplo, el anuncio mediado almacena el precio como un double, mientras que Ad Manager usa un String para el mismo recurso. El asignador es responsable de controlar estos tipos de conversiones.

Cómo asignar elementos de imagen

La asignación de recursos de imagen es más compleja que la asignación de tipos de datos, como double o String. Las imágenes se pueden descargar de forma automática o se pueden devolver como valores de URL. Sus escalas de píxeles por DPI también pueden variar.

Para ayudarte a administrar estos detalles, el SDK de anuncios de Google para dispositivos móviles proporciona la clase NativeAd.Image. De la misma manera en que necesitas crear una subclase de UnifiedNativeAdMapper para asignar un anuncio nativo mediado, también debes crear una subclase de NativeAd.Image cuando asignes recursos de imagen.

A continuación, se muestra un ejemplo de la clase SampleNativeMappedImage del evento personalizado:

Java

public class SampleNativeMappedImage extends NativeAd.Image {

  private Drawable drawable;
  private Uri imageUri;
  private double scale;

  public SampleNativeMappedImage(Drawable drawable, Uri imageUri, double scale) {
    this.drawable = drawable;
    this.imageUri = imageUri;
    this.scale = scale;
  }

  @Override
  public Drawable getDrawable() {
    return drawable;
  }

  @Override
  public Uri getUri() {
    return imageUri;
  }

  @Override
  public double getScale() {
    return scale;
  }
}

El SampleNativeAdMapper usa su clase de imagen asignada en esta línea para establecer el recurso de imagen del ícono del asignador:

Java

setIcon(new SampleNativeMappedImage(ad.getAppIcon(), ad.getAppIconUri(),
    SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));

Cómo agregar campos al paquete de adicionales

Algunos SDKs mediados proporcionan recursos adicionales aparte de los que se encuentran en el formato de anuncio nativo de Ad Manager. La clase UnifiedNativeAdMapper incluye un método setExtras() que se usa para pasar estos recursos a los publicadores. SampleNativeAdMapper usa esto para el activo "grado de genialidad" del SDK de Sample:

Java

Bundle extras = new Bundle();
extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, ad.getDegreeOfAwesomeness());
this.setExtras(extras);

Los editores pueden recuperar los datos con el método getExtras() de la clase NativeAd.

AdChoices

Tu evento personalizado es responsable de proporcionar un ícono de AdChoices con el método setAdChoicesContent() en UnifiedNativeAdMapper. A continuación, se incluye un fragmento de SampleNativeAdMapper que muestra cómo proporcionar el ícono de AdChoices:

Java

public SampleNativeAdMapper(SampleNativeAd ad) {
    ...
    setAdChoicesContent(sampleAd.getInformationIcon());
}

Eventos de impresiones y clics

Tanto el SDK de anuncios de Google para dispositivos móviles como el SDK mediado deben saber cuándo se produce una impresión o un clic, pero solo uno de los SDKs debe hacer un seguimiento de estos eventos. Existen dos enfoques diferentes que pueden usar los eventos personalizados, según si el SDK mediado admite el seguimiento de impresiones y clics por sí solo.

Realiza un seguimiento de los clics y las impresiones con el SDK de anuncios de Google para dispositivos móviles

Si el SDK mediado no realiza su propio seguimiento de impresiones y clics, pero proporciona métodos para registrar clics e impresiones, el SDK de anuncios de Google para dispositivos móviles puede hacer un seguimiento de estos eventos y notificar al adaptador. La clase UnifiedNativeAdMapper incluye dos métodos: recordImpression() y handleClick(), que los eventos personalizados pueden implementar para llamar al método correspondiente en el objeto de anuncio nativo mediado:

Java

@Override
public void recordImpression() {
  sampleAd.recordImpression();
}

@Override
public void handleClick(View view) {
  sampleAd.handleClick(view);
}

Dado que SampleNativeAdMapper contiene una referencia al objeto de anuncio nativo del SDK de muestra, puede llamar al método adecuado en ese objeto para informar un clic o una impresión. Ten en cuenta que el método handleClick() toma un solo parámetro: el objeto View correspondiente al recurso del anuncio nativo que recibió el clic.

Haz un seguimiento de los clics y las impresiones con el SDK mediado

Es posible que algunos SDKs mediados prefieran hacer un seguimiento de los clics y las impresiones por su cuenta. En ese caso, debes anular el seguimiento predeterminado de clics y de impresiones realizando las siguientes dos llamadas en el constructor de tu UnifiedNativeAdMapper:

Java

setOverrideClickHandling(true);
setOverrideImpressionRecording(true);

Los eventos personalizados que anulan el seguimiento de clics y de impresiones deben registrar los eventos onAdClicked() y onAdImpression() en el SDK de anuncios de Google para dispositivos móviles.

Para hacer un seguimiento de las impresiones y los clics, es probable que el SDK mediado necesite acceder a las vistas para habilitar el seguimiento. El evento personalizado debe anular el método trackViews() y usarlo para pasar la vista del anuncio nativo al SDK mediado para realizar el seguimiento. El SDK de muestra de nuestro proyecto de ejemplo de evento personalizado (del que se tomaron los fragmentos de código de esta guía) no usa este enfoque, pero, si lo hiciera, el código del evento personalizado se vería de la siguiente manera:

Java

@Override
public void trackViews(View containerView,
    Map<String, View> clickableAssetViews,
    Map<String, View> nonClickableAssetViews) {
  sampleAd.setNativeAdViewForTracking(containerView);
}

Si el SDK mediado admite el seguimiento de recursos individuales, puede consultar clickableAssetViews para ver qué vistas se deben hacer clicables. Este mapa se indexa con un nombre de recurso en NativeAdAssetNames. El UnifiedNativeAdMapper ofrece un método untrackView() correspondiente que los eventos personalizados pueden anular para liberar cualquier referencia a la vista y desvincularla del objeto de anuncio nativo.

Cómo reenviar eventos de mediación al SDK de anuncios de Google para dispositivos móviles

Puedes encontrar todas las devoluciones de llamada que admite la mediación en la documentación de MediationNativeAdCallback.

Es importante que tu evento personalizado reenvíe tantas devoluciones de llamada como sea posible para que tu app reciba estos eventos equivalentes del SDK de anuncios de Google para dispositivos móviles. A continuación, se muestra un ejemplo del uso de devoluciones de llamada:

Con esto, se completa la implementación de eventos personalizados para los anuncios nativos. El ejemplo completo está disponible en GitHub.