Custom Events for Banner and Interstitial Ads

Esta guía está dirigida a los editores que quieran utilizar la mediación de Ad Manager para hacer lo siguiente:

  • Mostrar anuncios de una red que no se admita directamente en la interfaz de Ad Manager.
  • Mostrar una vista personalizada en lugar de un anuncio.

Con los eventos personalizados puedes crear un adaptador de mediación personalizado para colocar cualquier vista en un espacio publicitario. En esta guía, abordaremos cómo crear eventos de este tipo para solicitar anuncios con un SDK de ejemplo que hemos desarrollado. Puedes encontrar el código fuente completo del evento personalizado y el SDK de ejemplo correspondiente en GitHub.

Requisitos previos

Antes de integrar eventos personalizados para anuncios de banner o intersticiales, debes integrar ese formato de anuncio en tu aplicación. Estas son las guías relevantes:

En el siguiente ejemplo, primero deberás crear un evento de banner personalizado en la mediación de Ad Manager. Para ello, tendrás que definir un evento personalizado que dirija a esa clase específica en tu aplicación a través de la interfaz de Ad Manager. Después, deberás implementar un CustomEventBanner para servir una vista. En este ejemplo se define un evento personalizado para mostrar anuncios de la red publicitaria de ejemplo.

Definir un evento personalizado

El evento personalizado se debe definir en la interfaz de Google Ad Manager. Encontrarás instrucciones sobre cómo configurar un grupo de rendimiento de Ad Manager para la mediación en este artículo del Centro de Ayuda.

En esta captura de pantalla se muestran algunos ejemplos de ajustes de eventos personalizados:

Solicitar un banner

Para solicitar un anuncio de banner, define una clase que implemente CustomEventBanner y llámala SampleCustomEventBanner. Cuando se selecciona el evento personalizado en el flujo de mediación de anuncios, se hace una llamada al método requestBannerAd() en el nombre de clase que has proporcionado en la configuración.

El parámetro opcional que se ha definido más arriba se transfiere a tu evento personalizado como parte del método requestBannerAd(). Normalmente, este parámetro es un identificador que permite al evento personalizado determinar qué anuncio debe cargarse.

También debes implementar métodos de ciclo de vida según corresponda. La mediación de Ad Manager reenvía al adaptador los eventos de actividad onPause() y onResume() si el usuario hace una llamada a los métodos PublisherAdView.pause() y PublisherAdView.resume() . La red publicitaria de ejemplo no incluye ninguna llamada de pausa ni de reactivación, por lo que proporciona una implementación vacía. La mediación intentará hacer una llamada a onDestroy() cuando el adaptador esté a punto de destruirse. En esta parte del proceso puedes eliminar todos los recursos utilizados.

Aquí tienes un ejemplo de implementación de SampleCustomEventBanner:

Java

public class SampleCustomEventBanner implements CustomEventBanner {

    /** The SampleAdView representing a banner ad. */
    private SampleAdView sampleAdView;

    /** The event is being destroyed. Perform any necessary cleanup here. */
    @Override
    public void onDestroy() {
        if (sampleAdView != null) {
            sampleAdView.destroy();
        }
    }

    /**
     * The app is being paused. This call is only forwarded to the adapter if
     * the developer notifies Ad Manager mediation that
     * the app is being paused.
     */
    @Override
    public void onPause() {
        // The sample ad network doesn't have an onPause method, so does nothing.
    }

    /**
     * The app is being resumed. This call is only forwarded to the
     * adapter if the developer notifies Ad Manager
     * mediation that the app is being resumed.
     */
    @Override
    public void onResume() {
        // The sample ad network doesn't have an onResume method, so does nothing.
    }

    @Override
    public void requestBannerAd(Context context,
            CustomEventBannerListener listener,
            String serverParameter,
            AdSize size,
            MediationAdRequest mediationAdRequest,
            Bundle customEventExtras) {

        sampleAdView = new SampleAdView(context);

        // Assumes that the serverParameter is the AdUnit for the Sample Network.
        sampleAdView.setAdUnit(serverParameter);

        sampleAdView.setSize(new SampleAdSize(size.getWidth(), size.getHeight()));

        // Implement a SampleAdListener and forward callbacks to Ad Manager.
        // The callback forwarding is handled by SampleBannerEventFowarder.
        sampleAdView.setAdListener(new SampleCustomBannerEventForwarder(listener, sampleAdView));

        // Make an ad request.
        sampleAdView.fetchAd(createSampleRequest(mediationAdRequest));

        }

    private SampleAdRequest createSampleRequest(MediationAdRequest mediationAdRequest) {
        SampleAdRequest request = new SampleAdRequest();
        request.setTestMode(mediationAdRequest.isTesting());
        request.setKeywords(mediationAdRequest.getKeywords());
        return request;
        }
}

Kotlin

class SampleCustomEventBanner : CustomEventBanner {

    /** The SampleAdView representing a banner ad. */
    private lateinit var mSampleAdView: SampleAdView

    /** The event is being destroyed. Perform any necessary cleanup here. */
    override fun onDestroy() {
        mSampleAdView.destroy()
    }

    /**
     * The app is being paused. This call is only forwarded to the adapter if
     * the developer notifies Ad Manager mediation that
     * the app is being paused.
     */
    override fun onPause() {
        // The sample ad network doesn't have an onPause method, so does nothing.
    }

    /**
     * The app is being resumed. This call is only forwarded to the
     * adapter if the developer notifies Ad Manager
     * mediation that the app is being resumed.
     */
    override fun onResume() {
        // The sample ad network doesn't have an onResume method, so does nothing.
    }

    override fun requestBannerAd(context: Context,
                                 listener: CustomEventBannerListener,
                                 serverParameter: String,
                                 size: AdSize,
                                 mediationAdRequest: MediationAdRequest,
                                 customEventExtras: Bundle?) {

        mSampleAdView = SampleAdView(context)

        // Assumes that the serverParameter is the AdUnit for the Sample Network.
        mSampleAdView.adUnit = serverParameter
        mSampleAdView.size = SampleAdSize(size.width, size.height)

        // Implement a SampleAdListener and forward callbacks to
        // Ad Manager mediation. The callback forwarding
        // is handled by SampleBannerEventFowarder.
        mSampleAdView.adListener = SampleCustomBannerEventForwarder(listener, mSampleAdView)

        // Make an ad request.
        mSampleAdView.fetchAd(createSampleRequest(mediationAdRequest))
    }

    private fun createSampleRequest(mediationAdRequest: MediationAdRequest): SampleAdRequest {
        val request = SampleAdRequest()
        request.testMode = mediationAdRequest.isTesting
        request.keywords = mediationAdRequest.keywords
        return request
    }
}

La clase SampleAdView utilizada en el ejemplo es una muestra sencilla de una vista de anuncio de terceros del SDK de ejemplo.

Enviar parámetros adicionales de la red publicitaria en las solicitudes de eventos personalizados (opcional)

Si necesitas enviar más parámetros a tu evento personalizado, utiliza el método addCustomEventExtrasBundle() de la clase PublisherAdRequest.Builder. Debes transferir la clase del adaptador de eventos personalizados y un paquete con los parámetros adicionales que el adaptador espera recibir.

El fragmento de código siguiente muestra cómo se transmite un parámetro SampleExtra para la clase SampleCustomEventBanner definida anteriormente:

Bundle extras = new Bundle();
extras.putBoolean("SampleExtra", true);

PublisherAdRequest request = new PublisherAdRequest.Builder()
        .addCustomEventExtrasBundle(SampleCustomEventBanner.class, extras)
        .build();

Si no haces una llamada a addCustomEventExtras() con la clase de evento personalizado correcta y con un paquete que corresponda a una solicitud de evento personalizado, el parámetro bundle que recibirá el adaptador será null.

Notificar a la mediación de Ad Manager

Tu evento personalizado debe notificar a la mediación a través de la interfaz de CustomEventBannerListener cuando cargue o no pueda cargar un anuncio. De lo contrario, se agota el tiempo de espera del evento personalizado y la mediación de anuncios se transfiere a la siguiente red.

Implementa el procesador de anuncios de tu red e invoca las retrollamadas pertinentes en CustomEventBannerListener para devolver mensajes a la mediación de Ad Manager.

La mediación de Ad Manager admite las siguientes retrollamadas:

Método Cuándo llamarlo
onAdLoaded() La solicitud de banner se ha realizado correctamente.
onAdFailedToLoad() Se ha producido un error al realizar la solicitud de banner.
onAdClicked() Se ha hecho clic en el banner.
onAdOpened() El banner se renderiza a pantalla completa.
onAdClosed() El usuario vuelve a la aplicación después de hacer clic en un banner.
onAdLeftApplication() El banner hace que el usuario salga de la aplicación.

Anuncios intersticiales

Método Cuándo llamarlo
onAdLoaded() La solicitud de intersticial se ha realizado correctamente.
onAdFailedToLoad() Se ha producido un error al realizar la solicitud de intersticial.
onAdClicked() Se ha hecho clic en el intersticial.
onAdOpened() Se ha mostrado el intersticial, renderizando una vista a pantalla completa.
onAdClosed() El intersticial se ha cerrado.
onAdLeftApplication() El intersticial ha provocado que el usuario salga de la aplicación.

Aquí tienes un ejemplo de implementación de SampleCustomBannerEventForwarder:

Java

public class SampleCustomBannerEventForwarder extends SampleAdListener {
    private CustomEventBannerListener mBannerListener;
    private SampleAdView mAdView;

    /**
     * Creates a new {@code SampleBannerEventForwarder}.
     * @param listener A {@link CustomEventBannerListener} that should receive
     *                 forwarded events.
     * @param adView   A {@link SampleAdView}.
     */
    public SampleCustomBannerEventForwarder(
            CustomEventBannerListener listener, SampleAdView adView) {
        this.mBannerListener = listener;
        this.mAdView = adView;
    }

    @Override
    public void onAdFetchSucceeded() {
        mBannerListener.onAdLoaded(mAdView);
    }

    @Override
    public void onAdFetchFailed(SampleErrorCode errorCode) {
        switch (errorCode) {
            case UNKNOWN:
                mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INTERNAL_ERROR);
                break;
            case BAD_REQUEST:
                mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INVALID_REQUEST);
                break;
            case NETWORK_ERROR:
                mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NETWORK_ERROR);
                break;
            case NO_INVENTORY:
                mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NO_FILL);
                break;
        }
    }

    @Override
    public void onAdFullScreen() {
        mBannerListener.onAdClicked();
        mBannerListener.onAdOpened();
        // Only call onAdLeftApplication if your ad network actually exits the developer's app.
        mBannerListener.onAdLeftApplication();
    }

    @Override
    public void onAdClosed() {
        mBannerListener.onAdClosed();
    }
}

Kotlin

class SampleCustomBannerEventForwarder(private val mBannerListener: CustomEventBannerListener,
                                       private val mAdView: SampleAdView) : SampleAdListener() {

    override fun onAdFetchSucceeded() {
        mBannerListener.onAdLoaded(mAdView)
    }

    override fun onAdFetchFailed(errorCode: SampleErrorCode) {
        when (errorCode) {
            UNKNOWN -> mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INTERNAL_ERROR)
            BAD_REQUEST -> mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INVALID_REQUEST)
            NETWORK_ERROR -> mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NETWORK_ERROR)
            NO_INVENTORY -> mBannerListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NO_FILL)
        }
    }

    override fun onAdFullScreen() {
        mBannerListener.onAdClicked()
        mBannerListener.onAdOpened()
        // Only call onAdLeftApplication if your ad network actually exits the developer's app.
        mBannerListener.onAdLeftApplication()
    }

    override fun onAdClosed() {
        mBannerListener.onAdClosed()
    }
}

Evento de intersticial personalizado

Para implementar un evento de intersticial personalizado, primero debes crearlo en la mediación de Ad Manager, igual que lo harías con un evento de banner personalizado. Después, implementa un CustomEventInterstitial para enviar la notificación. En este ejemplo se utiliza la red publicitaria de ejemplo, al igual que en el caso anterior.

Definir un evento personalizado

Puedes definir un evento de intersticial personalizado en la interfaz de Ad Manager.

Especifica un valor de nombre de clase que tenga una ruta completa. El parámetro debe contener toda la información necesaria para hacer una solicitud de anuncio a la red que vas a implementar en el evento personalizado.

Solicitar un intersticial

Para solicitar un intersticial, define una clase que implemente CustomEventInterstitial y llámala SampleCustomEventInterstitial. Cuando se selecciona el evento personalizado en el flujo de mediación, la mediación hace una llamada al método requestInterstitialAd() en el nombre de clase que has proporcionado en la configuración. Puedes utilizar el parámetro que se indica en este método para hacer una solicitud de intersticial a la red seleccionada. En el ejemplo que aparece a continuación se muestra cómo solicitar un intersticial de la red publicitaria de ejemplo mediante un evento personalizado.

Este es un ejemplo de implementación de SampleCustomEventInterstitial:

Java

public class SampleCustomEventInterstitial implements CustomEventInterstitial {

    /** Represents a SampleInterstitial. */
    private SampleInterstitial sampleInterstitial;

    @Override
    public void requestInterstitialAd(Context context,
            CustomEventInterstitialListener listener,
            String serverParameter,
            MediationAdRequest mediationAdRequest,
            Bundle customEventExtras) {
        /**
         * In this method, you should:
         * 1. Create your interstitial ad.
         * 2. Set your ad network's listener.
         * 3. Make an ad request.
         */

        sampleInterstitial = new SampleInterstitial(context);

        // Here we're assuming the serverParameter is the ad unit for the sample ad network.
        sampleInterstitial.setAdUnit(serverParameter);

        // Implement a SampleAdListener and forward callbacks to
        // Ad Manager.
        sampleInterstitial.setAdListener(new SampleCustomInterstitialEventForwarder(listener));

        // Make an ad request.
        sampleInterstitial.fetchAd(createSampleRequest(mediationAdRequest));
    }

    /**
     * Helper method to create a SampleAdRequest.
     * @param mediationAdRequest The mediation request with targeting information.
     * @return The created SampleAdRequest.
     */
    private SampleAdRequest createSampleRequest(MediationAdRequest mediationAdRequest) {
        SampleAdRequest request = new SampleAdRequest();
        request.setTestMode(mediationAdRequest.isTesting());
        request.setKeywords(mediationAdRequest.getKeywords());
        return request;
    }

    @Override
    public void showInterstitial() {
        // Show your interstitial ad.
        sampleInterstitial.show();
    }

    /** The event is being destroyed. Perform any necessary cleanup here. */
    @Override
    public void onDestroy() {
        if (sampleInterstitial != null) {
            sampleInterstitial.destroy();
        }
    }

    /**
     * The app is being paused. This call is only forwarded to the adapter if
     * the developer notifies Ad Manager mediation
     * that the app is being paused.
     */
    @Override
    public void onPause() {
        // The sample ad network doesn't have an onPause method, so does nothing.
    }

    /**
     * The app is being resumed. This call is only forwarded to the
     * adapter if the developer notifies Ad Manager
     * mediation that the app is being resumed.
     */
    @Override
    public void onResume() {
        // The sample ad network doesn't have an onResume method, so does nothing.
    }
}

Kotlin

class SampleCustomEventInterstitial : CustomEventInterstitial {

    /** Represents a SampleInterstitial.  */
    private lateinit var mSampleInterstitial: SampleInterstitial

    override fun requestInterstitialAd(context: Context,
                                       listener: CustomEventInterstitialListener,
                                       serverParameter: String,
                                       mediationAdRequest: MediationAdRequest,
                                       customEventExtras: Bundle?) {
        /**
         * In this method, you should:
         * 1. Create your interstitial ad.
         * 2. Set your ad network's listener.
         * 3. Make an ad request.
         */

        mSampleInterstitial = SampleInterstitial(context)

        // Here we're assuming the serverParameter is the ad unit for the sample ad network.
        mSampleInterstitial.adUnit = serverParameter

        // Implement a SampleAdListener and forward callbacks to
        // Ad Manager mediation.
        mSampleInterstitial.adListener = SampleCustomInterstitialEventForwarder(listener)

        // Make an ad request.
        mSampleInterstitial.fetchAd(createSampleRequest(mediationAdRequest))
    }

    /**
     * Helper method to create a [SampleAdRequest].
     * @param mediationAdRequest The mediation request with targeting information.
     * *
     * @return The created [SampleAdRequest].
     */
    private fun createSampleRequest(mediationAdRequest: MediationAdRequest): SampleAdRequest {
        val request = SampleAdRequest()
        request.testMode = mediationAdRequest.isTesting
        request.keywords = mediationAdRequest.keywords
        return request
    }

    override fun showInterstitial() {
        // Show your interstitial ad.
        mSampleInterstitial.show()
    }

    /** The event is being destroyed. Perform any necessary cleanup here. */
    override fun onDestroy() {
        mSampleInterstitial.destroy()
    }

    /**
     * The app is being paused. This call is only forwarded to the adapter if
     * the developer notifies Ad Manager mediation that
     * the app is being paused.
     */
    override fun onPause() {
        // The sample ad network doesn't have an onPause method, so does nothing.
    }

    /**
     * The app is being resumed. This call is only forwarded to the adapter if
     * the developer notifies Ad Manager mediation that
     * the app is being resumed.
     */
    override fun onResume() {
        // The sample ad network doesn't have an onResume method, so does nothing.
    }
}

La interfaz de eventos de intersticial personalizados requiere que implementes el método showInterstitial(). La mediación invoca este método cuando solicitas al SDK de anuncios de Google para móviles que muestre el anuncio intersticial.

Enviar parámetros adicionales de la red publicitaria en las solicitudes de eventos personalizados (opcional)

Si necesitas enviar más parámetros a tu evento personalizado, utiliza el método addCustomEventExtrasBundle() de la clase PublisherAdRequest.Builder. Debes transferir la clase del adaptador de eventos personalizados y un paquete con los parámetros adicionales que el adaptador espera recibir.

En el siguiente fragmento de código se muestra cómo transferir un parámetro "SampleExtra" de la clase SampleCustomEventInterstitial que se ha definido anteriormente:

Bundle extras = new Bundle();
extras.putBoolean("SampleExtra", true);

PublisherAdRequest request = new PublisherAdRequest.Builder()
        .addCustomEventExtrasBundle(SampleCustomEventInterstitial.class, extras)
        .build();

Si no haces una llamada a addCustomEventExtrasBundle() con la clase de evento personalizado correcta y con un paquete que corresponda a una solicitud de evento personalizado, el parámetro bundle que recibirá el adaptador será null.

Notificar a la mediación de Ad Manager

Al igual que con el ejemplo de evento personalizado de banner, debe implementar el procesador de anuncios de su red para enviar mensajes de vuelta a la mediación Ad Manager.

Esta clase SampleCustomInterstitialEventForwarder de ejemplo implementa la interfaz de SampleAdListener para desviar las retrollamadas de la red publicitaria de ejemplo:

Java

public class SampleCustomInterstitialEventForwarder extends SampleAdListener {
    private CustomEventInterstitialListener mInterstitialListener;

    /**
     * Creates a new SampleInterstitialEventForwarder.
     * @param listener An AdMob CustomEventInterstitialListener that should
     *                 receive forwarded events.
     */
    public SampleCustomInterstitialEventForwarder(CustomEventInterstitialListener listener) {
        this.mInterstitialListener = listener;
    }

    @Override
    public void onAdFetchSucceeded() {
        mInterstitialListener.onAdLoaded();
    }

    @Override
    public void onAdFetchFailed(SampleErrorCode errorCode) {
        switch (errorCode) {
            case UNKNOWN:
                mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INTERNAL_ERROR);
                break;
            case BAD_REQUEST:
                mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INVALID_REQUEST);
                break;
            case NETWORK_ERROR:
                mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NETWORK_ERROR);
                break;
            case NO_INVENTORY:
                mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NO_FILL);
                break;
        }
    }

    @Override
    public void onAdFullScreen() {
        mInterstitialListener.onAdOpened();
        // Only call onAdLeftApplication if your ad network actually exits the developer's app.
        mInterstitialListener.onAdLeftApplication();
    }

    @Override
    public void onAdClosed() {
        mInterstitialListener.onAdClosed();
    }
}

Kotlin

class SampleCustomInterstitialEventForwarder(private val mInterstitialListener: CustomEventInterstitialListener)
        : SampleAdListener() {

    override fun onAdFetchSucceeded() {
        mInterstitialListener.onAdLoaded()
    }

    override fun onAdFetchFailed(errorCode: SampleErrorCode) {
        when (errorCode) {
            UNKNOWN -> mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INTERNAL_ERROR)
            BAD_REQUEST -> mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_INVALID_REQUEST)
            NETWORK_ERROR -> mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NETWORK_ERROR)
            NO_INVENTORY -> mInterstitialListener.onAdFailedToLoad(PublisherAdRequest.ERROR_CODE_NO_FILL)
        }
    }

    override fun onAdFullScreen() {
        mInterstitialListener.onAdOpened()
        // Only call onAdLeftApplication if your ad network actually exits the developer's app.
        mInterstitialListener.onAdLeftApplication()
    }

    override fun onAdClosed() {
        mInterstitialListener.onAdClosed()
    }
}

Con esto se completa la implementación de eventos personalizados de anuncios intersticiales. El ejemplo completo está disponible en GitHub, y puedes usarlo con una red publicitaria que ya se admita o modificarlo para mostrar anuncios intersticiales personalizados.