Ad Network Mediation Adapter Development

This guide is intended for ad networks looking to build a mediation adapter. If you are a publisher, see the publisher mediation instructions.

An ad network adapter is the layer of communication between your ad network and Google Mobile Ads Mediation.

The adapter is responsible for implementing MediationBannerAdapter to support banner ads and MediationInterstitialAdapter to support interstitial ads. It must also invoke the callbacks in MediationBannerListener and MediationInterstitialListener at the appropriate times to notify Google Mobile Ads Mediation of these events, which can also be forwarded to the developer.

Sample ad network

This guide demonstrates how to build an adapter for a Sample ad network. The Sample ad network contains the following classes that are representative of the classes offered by most ad networks:

class SampleAdView {
    public SampleAdView(Context context);
    public void setSize(SampleAdSize size);
    public void setAdUnit(String sampleAdUnit);
    public void setAdListener(SampleAdListener listener);
    public void fetchAd(SampleAdRequest request);
    public void destroy();
}

class SampleAdSize {
    public SampleAdSize(int width, int height);
    public int getWidth();
    public int getHeight();
}

class SampleAdRequest {
    public SampleAdRequest();
    public void setKeywords(Set<String> keywords);
    public void setTestMode(boolean useTesting);
}

class SampleAdListener {
    public void onAdFetchSucceeded();
    public void onAdFetchFailed(SampleErrorCode code);
    public void onAdFullScreen();
    public void onAdClosed();
}

enum SampleErrorCode {
    UNKNOWN,
    BAD_REQUEST,
    NETWORK_ERROR,
    NO_INVENTORY
}

class SampleInterstitial {
    public SampleInterstitial(Context context);
    public void setAdUnit(String sampleAdUnit);
    public void setAdListener(SampleAdListener listener);
    public void fetchAd(SampleAdRequest request);
    public void show();
    public void destroy();
}

See the complete SDK implementation for more information about these classes.

Implement a banner adapter

To implement an adapter that supports banner ads, create a class that implements MediationBannerAdapter.

public class SampleAdapter implements MediationBannerAdapter {
    @Override
    public void requestBannerAd(
            Context context,
            MediationBannerListener listener,
            Bundle serverParameters,
            AdSize adSize,
            MediationAdRequest mediationAdRequest,
            Bundle mediationExtras) {}

    @Override
    public View getBannerView() {}

    @Override
    public void onDestroy() {}

    @Override
    public void onPause() {}

    @Override
    public void onResume() {}
}

Before we dive into implementing MediationBannerAdapter, let's discuss server parameters, mediation extras, and how these values are passed to the adapter.

Server parameters

Your ad network likely needs some identifier(s) in order to identify a publisher. The Sample ad network, for example, only requires an ad unit. These required parameters are provided to you in the serverParameters bundle inside of requestBannerAd(). During development, you can assume that the bundle will already be populated with the keys that you need:

private static final String SAMPLE_AD_UNIT_KEY = "ad_unit";

@Override
public void requestBannerAd(
        Context context,
        MediationBannerListener listener,
        Bundle serverParameters,
        AdSize adSize,
        MediationAdRequest mediationAdRequest,
        Bundle mediationExtras) {
    String adUnit = serverParameters.getString(SAMPLE_AD_UNIT_KEY);
    ...
}

AdMob will send you a questionnaire asking what server parameters you need from a publisher in order to request and serve ads. AdMob will use that input to configure your network in the AdMob UI. The screenshot below shows that APID is required for Millennial Media, and App ID is required for InMobi.

AdMob will use this information to populate the serverParameters bundle when instantiating your adapter.

See this article for more information on how publishers will configure mediation ad networks.

Additional targeting parameters

The MediationAdRequest contains some common targeting information that you can use for ad targeting such as:

Mediation extras

If your ad network supports targeting information that the MediationAdRequest doesn't provide, app developers can pass a bundle of mediationExtras specifically to your network. Mediation provides an example of how to pass mediation extras.

To make it easier for developers to optionally pass this information, you can provide a bundle builder class in your adapter. Let's say your network supports passing an income value. You can add a builder class in your adapter that sets the income:

public static final class BundleBuilder {
    private int income;

    public BundleBuilder setIncome(int income) {
        this.income = income;
        return this;
    }

    public Bundle build() {
        Bundle bundle = new Bundle();
        bundle.putInt("income", income);
        return bundle;
    }
}

This class provides a clean API for the developer to generate a bundle for your network:

Bundle sampleAdapterBundle =
        new SampleAdapter.BundleBuilder().setIncome(100000).build();

requestBannerAd()

Now that you've been introduced to server parameters and mediation extras, we can use them to build a MediationBannerAdapter.

The requestBannerAd() method is called immediately after the adapter is instantiated. This is where you should create your ad view and make a banner ad request.

An implementation of requestBannerAd() for the Sample ad network looks like this:

public class SampleAdMobAdapter implements MediationBannerAdapter {
    private static final String SAMPLE_AD_UNIT_KEY = "ad_unit";
    private SampleAdView sampleAdView;

    @Override
    public void requestBannerAd(
            Context context, // May be an application context.
            MediationBannerListener listener,
            Bundle serverParameters,
            AdSize adSize,
            MediationAdRequest mediationAdRequest,
            Bundle mediationExtras) {
        sampleAdView = new SampleAdView(context);

        if (serverParameters.containsKey(SAMPLE_AD_UNIT_KEY)) {
            sampleAdView.setAdUnit(serverParameters.getString(SAMPLE_AD_UNIT_KEY));
        } else {
            listener.onAdFailedToLoad(this, AdRequest.ERROR_CODE_INVALID_REQUEST);
        }

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

        sampleAdView.setAdListener(
                new SampleBannerEventForwarder(listener, this));

        SampleAdRequest request = new SampleAdRequest();
        request.setTestMode(mediationAdRequest.isTesting());
        request.setKeywords(mediationAdRequest.getKeywords());
        sampleAdView.fetchAd(request);
    }
}

Don't assume that the context parameter is of type Activity. Depending on publisher implementation, Google Mobile Ads Mediation may forward an application context to your adapter. If your adapter can't handle an application context, it is recommended to invoke onAdFailedToLoad() with error code AdRequest.ERROR_CODE_INVALID_REQUEST.

MediationBannerListener callbacks

You should save the MediationBannerListener provided to you in requestBannerAd() so that you can forward ad events back to Google Mobile Ads Mediation. Each callback must be invoked at the appropriate time in the ad's lifecycle:

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.
onAdLeftApplication() The banner causes the user to leave the app.

The Sample ad network adapter creates a class called SampleBannerEventForwarder to handle event forwarding:

public class SampleBannerEventForwarder extends SampleAdListener {
    private MediationBannerListener mediationListener;
    private SampleAdapter adapter;

    public SampleBannerEventForwarder(
            MediationBannerListener listener, SampleAdapter adapter) {
        this.mediationListener = listener;
        this.adapter = adapter;
    }

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

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

    @Override
    public void onAdFullScreen() {
        mediationListener.onAdClicked(adapter);
        mediationListener.onAdOpened(adapter);
        mediationListener.onAdLeftApplication(adapter);
    }

    @Override
    public void onAdClosed() {
        mediationListener.onAdClosed(adapter);
    }
}

Note how the Sample ad network adapter sent onAdClicked, onAdOpened, and onAdLeftApplication in the same callback. Even though the callbacks for your network may not exactly match the callbacks Google Mobile Ads requires, it is the adapter's responsibility to provide a reasonable mapping.

getBannerView

Once you call MediationBannerListener.onAdLoaded(), mediation will call getBannerView() to get your ad network's banner view to display on the screen. Simply return the banner view that you created in requestBannerAd():

@Override
public View getBannerView() {
    return sampleAdView;
}

Activity lifecycle events

Mediation will notify the adapter of onPause() and onResume() activity events if the app developer notifies mediation of the events. Perform any necessary pausing and resuming of your banner:

@Override
public void onPause() {
}

@Override
public void onResume() {
}

The Sample ad network doesn't include a pause or resume call, so it provides an empty implementation.

Mediation will make its best attempt to call onDestroy() when the adapter is about to be destroyed. Perform any necessary cleanup here:

@Override
public void onDestroy() {
    if (sampleAdView != null) {
        sampleAdView.destroy();
    }
}

Smart banners

The Google Mobile Ads SDK supports a smart banner ad size, which is full width and variable height depending on the size of the device.

To accurately get the ad size of a smart banner, your adapter should use adSize.getWidthInPixels(context) to get the width and adSize.getHeightInPixels(context) instead of adSize.getHeight() to get the height. It should then divide by the device density:

int widthInPixels = adSize.getWidthInPixels(context);
int heightInPixels = adSize.getHeightInPixels(context);
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
int widthInDp = Math.round(widthInPixels / displayMetrics.density);
int heightInDp = Math.round(heightInPixels / displayMetrics.density);

You can then use widthInDp and heightInDp as the size when making an ad request.

That's it! You now have a working mediation adapter for banners! For reference, a complete implementation of the SampleAdapter can be found here.

Implement an interstitial adapter

The adapter implementation for interstitial ads is similar to banner ads. To implement an adapter that supports interstitial ads, create a class that implements MediationInterstitialAdapter:

public class SampleAdapter implements MediationInterstitialAdapter {
    @Override
    public void requestInterstitialAd(
            Context context,
            MediationInterstitialListener listener,
            Bundle serverParameters,
            MediationAdRequest mediationAdRequest,
            Bundle mediationExtras) {}

    @Override
    public View showInterstitial() {}

    @Override
    public void onDestroy() {}

    @Override
    public void onPause() {}

    @Override
    public void onResume() {}
}

If your adapter also supports banners, you can use the same adapter class to implement both interfaces.

Familiarize yourself now with server parameters and mediation extras before proceeding to implement a MediationInterstitialAdapter.

Server parameters (interstitial)

See the Banner server parameters section.

Additional targeting parameters (interstitial)

See the Banner additional targeting parameters section.

Mediation extras (interstitial)

See the Banner mediation extras section.

requestInterstitialAd

The requestInterstitialAd() method is called immediately after the adapter is instantiated. This is where you should create your interstitial ad and make an interstitial request.

An implementation of requestInterstitialAd() for the Sample ad network would look like this:

public class SampleAdapter implements MediationBannerAdapter {
    private static final String SAMPLE_AD_UNIT_KEY = "ad_unit";

    private SampleInterstitial sampleInterstitial;

    @Override
    public void requestInterstitialAd(
            Context context, // May be an application context.
            MediationInterstitialListener listener,
            Bundle serverParameters,
            MediationAdRequest mediationAdRequest,
            Bundle mediationExtras) {
        sampleInterstitial = new SampleInterstitial(context);

        if (serverParameters.containsKey(SAMPLE_AD_UNIT_KEY)) {
            sampleInterstitial.setAdUnit(serverParameters.getString(SAMPLE_AD_UNIT_KEY));
        } else {
            listener.onAdFailedToLoad(this, AdRequest.ERROR_CODE_INVALID_REQUEST);
        }

        sampleInterstitial.setAdListener(
                new SampleInterstitialEventForwarder(listener, this));

        // Make an ad request.
        SampleAdRequest request = new SampleAdRequest();
        request.setTestMode(mediationAdRequest.isTesting());
        request.setKeywords(mediationAdRequest.getKeywords());
        sampleInterstitial.fetchAd(request);
    }
}

Do not assume that the context parameter is of type Activity! Google Mobile Ads Mediation forwards the context passed by the app developer, and it's possible that an application context is passed. If your adapter can't handle an application context, it is recommended to invoke onAdFailedToLoad with error code AdRequest.ERROR_CODE_INVALID_REQUEST.

MediationInterstitialListener callbacks

You should save the MediationInterstitialListener provided to you in requestInterstitialAd so that you can forward ad events back to Google Mobile Ads Mediation. Each callback must be invoked at the appropriate time in the ad's lifecycle:

Method When to call
onAdLoaded The interstitial request succeeded.
onAdFailedToLoad The interstitial request failed.
onAdOpened The interstitial is being shown.
onAdClosed The interstitial is closed.
onAdLeftApplication The interstitial causes the user to leave the app.

showInterstitial

Once you call MediationInterstitialListener.onAdLoaded(), you should wait to show the interstitial until showInterstitial() is called. The app developer decides when to show the interstitial, which may be up to several minutes after it was requested.

The implementation for showInterstitial() is pretty straightforward. Just show your interstitial object:

@Override
public void showInterstitial() {
    sampleInterstitial.show();
}

Activity lifecycle events (interstitial)

See the Banner activity lifecycle events section.

After implementing activity lifecycle events, your mediation adapter is ready to handle interstitial ads! For reference, a complete implementation of the SampleAdapter can be found here.

FAQ

What do I do if my adapter only supports banner or interstitial ads, but not both?

If your adapter only supports banners, you only need to implement the MediationBannerAdapter interface. If your adapter only supports interstitials, you only need to implement the MediationInterstitialAdapter interface.