Banner ads custom events

Prerequisites

Before you can create custom events, you need to integrate the banner ad format into your app.

You may also want to first read about making an AdRequest and how mediation works.

In the following example, you'll first create a banner custom event within AdMob mediation. This requires that you define a custom event that points to that specific class in your app through the AdMob UI, then implement a CustomEventBanner to serve a view. This example defines a custom event to display ads from the sample ad network.

Define a custom event

The custom event must be defined in the AdMob UI. Follow these instructions to create a custom event.

Below is a screenshot showing some sample custom event settings:

Request a banner

To request a banner ad, define a class that implements CustomEventBanner and call it SampleCustomEventBanner. When the custom event is chosen from the ad mediation flow, the requestBannerAd() method is called on the class name you provided in the settings.

The optional parameter defined above is passed into your custom event as part of the requestBannerAd() method. Typically, this parameter is an identifier that enables the custom event to determine which ad to load.

You should also implement lifecycle methods as appropriate. AdMob mediation forwards the adapter onPause() and onResume() activity events if the user calls the AdView.pause() and AdView.resume() methods. The sample ad network doesn't include a pause or resume call, so it provides an empty implementation. Mediation makes its best attempt to call onDestroy() when the adapter is about to be destroyed. Perform any necessary cleanup there.

Here's an example implementation of 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 AdMob 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 AdMob
     * 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 AdMob.
        // The callback forwarding is handled by SampleBannerEventForwarder.
        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 AdMob 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 AdMob
     * 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
        // AdMob mediation. The callback forwarding
        // is handled by SampleBannerEventForwarder.
        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
    }
}

The SampleAdView class used in the sample is a simple example of a third-party ad view from the Sample SDK.

Send ad network extras for custom event requests (optional)

If you need to send extra parameters to your custom event, use the addCustomEventExtrasBundle() method of the AdRequest.Builder class. You must pass in your custom event adapter class and a bundle of the extras expected by your custom event adapter.

Here is a code snippet that shows how to pass a SampleExtra parameter for the SampleCustomEventBanner class defined earlier:

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

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

If you don't call addCustomEventExtras() with the correct custom event class and a bundle for a custom event request, the bundle parameter received by the adapter will be null.

Notify AdMob mediation

Your custom event must notify mediation via the CustomEventBannerListener interface when it loads or fails to load an ad. Otherwise, the custom event times out, and ad mediation moves on to the next network.

Implement the ad listener for your network and invoke the relevant callbacks on CustomEventBannerListener to send messages back to AdMob mediation.

We've created the SampleCustomBannerEventForwarder class, implementing the SampleAdListener interface, to forward callbacks from the sample ad network.

AdMob mediation supports the following callbacks:

Method When to call
onAdLoaded() The banner request succeeded.
onAdFailedToLoad() The banner request failed.
onAdClicked() The banner was clicked.
onAdOpened() The banner is rendering a full-screen view.
onAdClosed() The user returns to the app after clicking on a banner.

Here's an example implementation of 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(AdRequest.ERROR_CODE_INTERNAL_ERROR);
                break;
            case BAD_REQUEST:
                mBannerListener.onAdFailedToLoad(AdRequest.ERROR_CODE_INVALID_REQUEST);
                break;
            case NETWORK_ERROR:
                mBannerListener.onAdFailedToLoad(AdRequest.ERROR_CODE_NETWORK_ERROR);
                break;
            case NO_INVENTORY:
                mBannerListener.onAdFailedToLoad(AdRequest.ERROR_CODE_NO_FILL);
                break;
        }
    }

    @Override
    public void onAdFullScreen() {
        mBannerListener.onAdClicked();
        mBannerListener.onAdOpened();
    }

    @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(AdRequest.ERROR_CODE_INTERNAL_ERROR)
            BAD_REQUEST -> mBannerListener.onAdFailedToLoad(AdRequest.ERROR_CODE_INVALID_REQUEST)
            NETWORK_ERROR -> mBannerListener.onAdFailedToLoad(AdRequest.ERROR_CODE_NETWORK_ERROR)
            NO_INVENTORY -> mBannerListener.onAdFailedToLoad(AdRequest.ERROR_CODE_NO_FILL)
        }
    }

    override fun onAdFullScreen() {
        mBannerListener.onAdClicked()
        mBannerListener.onAdOpened()
    }

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

Send ad network extras for custom event requests (optional)

If you need to send extra parameters to your custom event, use the addCustomEventExtrasBundle() method of the AdRequest.Builder class. You must pass in your custom event adapter class and a bundle of the extras expected by your custom event adapter.

Here is a code snippet that shows how to pass a "SampleExtra" parameter for the SampleCustomEventInterstitial class defined earlier:

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

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

If you don't call addCustomEventExtrasBundle() with the correct custom event class and a bundle for a custom event request, the bundle parameter received by the adapter will be null.

This completes the custom events implementation for banner ads. The full example is available on GitHub. You can use it with an ad network that is already supported or modify it to display custom banner ads.