This guide is intended for those looking to use the AdMob Mediation platform to display rewarded video ads from a third party ad network.
AdMob supported ad networks and custom events
Ad networks that are directly supported by the AdMob mediation platform will implement standard mediation adapters. Ad networks that are not directly supported by AdMob can still be be used to request and display rewarded videos by implementing custom event adapters. The differences between standard mediation adapters and custom event adapters are outlined below.
Defining server parameters
Ad networks mediated to through the AdMob mediation platform need one or more identifiers in order to identify a publisher. These identifiers are represented as server parameters and are defined when configuring a third party ad network for mediation in the AdMob interface. If you are building a custom event adapter, follow the creating a custom event step below. If you are building an adapter your ad network and corresponding server parameters will be configured as part of the ad netowrk onboarding process with AdMob.
Creating a custom event
To define a custom event, you must first create it in the AdMob
interface. You can find instructions for creating a custom event in this help center
guide. Once the custom event is defined,
it points to a class within your app that implements MediationRewardedVideoAdAdapter
to serve a rewarded video. The custom event also lists a server parameter that is
passed to your rewarded video adapter.
Here is a screenshot showing some sample custom event settings:
The entries in the example screen shown above represent the following:
Class Name | The fully qualified name of the class that implements the custom event. |
Label | A unique name for the event. |
Parameter | An optional argument passed to your custom event. |
Implementing a mediation adapter
This guide demonstrates the steps required to implement an adapter. To show what adapter code may look like in practice, we have created a Sample Ad Network SDK and will be building the adapter for this SDK.
Initialize the adapter
On an app’s initial rewarded video ad request, the Google Mobile Ads SDK invokes the
initialize()
method of your adapter.
Your adapter is responsible for implementing this method to initialize the third
party ad network. This method provides you a Bundle of serverParameters
that may be
required to complete the initialization. There is a slight difference in how these
parameters can be accessed if you’re developing a mediation adapter or a custom event
adapter.
For a mediation adapter, the keys for server parameters are preconfigured, and you can extract the server parameters individually. For custom events, there is a single parameter that can be accessed via the MediationRewardedVideoAdAdapter.CUSTOM_EVENT_SERVER_PARAMETER_FIELD key:
Mediation Adapter
String parameter1 = serverParameters.getString("SERVER_PARAMETER_KEY1");
String parameter2 = serverParameters.getString("SERVER_PARAMETER_KEY2");
Custom Events
String parameter = serverParameters.getString(MediationRewardedVideoAdAdapter.CUSTOM_EVENT_SERVER_PARAMETER_FIELD);
The adapter should retain a reference to the MediationRewardedVideoAdListener
instance
so it can forward ad events to the
Google Mobile Ads SDK. If initialization succeeds, the adapter should call
MediationRewardedVideoAdListener.onInitializationSucceeded()
. If adapter initialization fails,
the adapter should invoke MediationRewardedVideoAdListener.onInitializationFailed()
. In the
event that initialization fails, the Google Mobile Ads SDK reattempts to initialize the adapter
each time a rewarded video ad request is made. A sample implementation of the initialize()
method is shown below:
@Override
public void initialize(Context context,
MediationAdRequest mediationAdRequest,
String unused,
MediationRewardedVideoAdListener listener,
Bundle serverParameters,
Bundle mediationExtras) {
// In this method you should initialize your SDK.
// The sample SDK requires activity context to initialize, so check that the context
// provided by the app is an activity context before initializing.
if (!(context instanceof Activity)) {
// Context not an Activity context, log the reason for failure and fail the
// initialization.
Log.d(TAG, "Sample SDK requires an Activity context to initialize");
listener.onInitializationFailed(
SampleAdapter.this, AdRequest.ERROR_CODE_INVALID_REQUEST);
return;
}
// Get the Ad Unit ID for the Sample SDK from serverParameters bundle.
String adUnit = serverParameters.getString(
MediationRewardedVideoAdAdapter.CUSTOM_EVENT_SERVER_PARAMETER_FIELD);
if (TextUtils.isEmpty(adUnit)) {
listener.onAdFailedToLoad(this, AdRequest.ERROR_CODE_INVALID_REQUEST);
return;
}
// Create a rewarded video event forwarder to forward the events from the Sample SDK to
// the Google Mobile Ads SDK.
mRewardedVideoEventForwarder =
new SampleMediationRewardedVideoEventForwarder(listener, SampleAdapter.this);
// Initialize the Sample SDK.
SampleRewardedVideo.initialize((Activity) context, adUnit, mRewardedVideoEventForwarder);
}
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 onInitializationFailed()
with error code AdRequest.ERROR_CODE_INVALID_REQUEST
.
public class SampleMediationRewardedVideoEventForwarder extends SampleRewardedVideoAdListener {
...
@Override
public void onRewardedVideoInitialized() {
super.onRewardedVideoInitialized();
mIsInitialized = true;
mMediationRewardedVideoAdListener.onInitializationSucceeded(mSampleAdapter);
}
@Override
public void onRewardedVideoInitializationFailed(SampleErrorCode error) {
super.onRewardedVideoInitializationFailed(error);
mIsInitialized = false;
mMediationRewardedVideoAdListener.onInitializationFailed(
mSampleAdapter, getAdMobErrorCode(error));
}
}
Return initialization state
The isInitialized()
method of your adapter should return false until the adapter’s first call to
MediationRewardedVideoAdListener.onInitializationSucceeded()
. At that point, this method should always
return true, as shown below:
@Override
public boolean isInitialized() {
return mRewardedVideoEventForwarder != null && mRewardedVideoEventForwarder.isInitialized();
}
Load a rewarded video
Once the adapter invokes the MediationRewardedVideoAdListener.onInitializationSucceeded()
method, the Google Mobile Ads SDK can call the loadAd()
method of your adapter. This method should
request a rewarded video and call MediationRewardedVideoAdListener.onAdLoaded()
once it has a
rewarded video to show. If no videos are available, the adapter should call
MediationRewardedVideoAdListener.onAdFailedToLoad()
.
For rewarded videos, many ad networks employ an API where there is no notion of ad requests.
Once the ad network has been initialized, you can check if there is inventory for the current user and
an ad is ready. If this criteria is met, you can show the ad to the user. A sample implementation of the
loadAd()
for such an ad network is shown below.
@Override
public void loadAd(MediationAdRequest mediationAdRequest,
Bundle serverParameters,
Bundle mediationExtras) {
if (SampleRewardedVideo.isAdAvailable()) {
// Ad already available, use the forwarder to send a success callback to AdMob.
mRewardedVideoEventForwarder.onAdLoaded();
} else {
// No ad available, use the forwarder to send a failure callback.
mRewardedVideoEventForwarder.onAdFailedToLoad();
}
}
On the first ad request, loadAd()
may be called on the adapter immediately after it’s invocation of the
MediationRewardedVideoAdListener.onInitializationSucceeded()
method. If an ad network is still loading
ads at this time, immediately reporting an ad failing to load can result in a large proportion of no fills
on that initial rewarded video ad request. In this case, we recommend that adapters track when the loading
of ads is in progress and delay responding to the Google Mobile Ads SDK until ads have either successfully
loaded or failed to load. The Google Mobile Ads SDK has a timeout in place in case the adapter doesn’t respond
fast enough.
Show the rewarded video
The Google Mobile Ads SDK may call the showVideo()
method of your adapter any time after the adapter notifies
the Google Mobile Ads SDK of a successful ad load. The showVideo()
method will only ever get called
once per successful loadAd callback. Upon invocation of this method, the adapter should play the rewarded
video.
@Override
public void showVideo() {
// Show the rewarded video ad.
if (SampleRewardedVideo.isAdAvailable()) {
// Rewarded video ad available, show ad.
SampleRewardedVideo.showAd();
} else {
// Show ad will only be called if the adapter sends back an ad loaded callback in
// response to a loadAd request. If for any reason the adapter is not ready to show
// an ad after sending an ad loaded callback, log a warning.
Log.w(TAG, "No ads to show.");
}
}
Define a reward
When the adapter is ready to reward the user, it must create an object that conforms to the RewardItem
interface. A sample implementation of RewardItem
is shown below:
/**
* A {@link RewardItem} that maps the sample reward type and reward amount.
*/
public class SampleRewardItem implements RewardItem {
private String mRewardType;
private int mRewardAmount;
/**
* Creates a {@link SampleRewardItem}.
*
* @param rewardType the sample reward type.
* @param rewardAmount the sample reward amount.
*/
public SampleRewardItem(String rewardType, int rewardAmount) {
this.mRewardType = rewardType;
this.mRewardAmount = rewardAmount;
}
@Override
public String getType() {
return mRewardType;
}
@Override
public int getAmount() {
return mRewardAmount;
}
}
To notify the Google Mobile Ads SDK that a user should be rewarded, the adapter is required to
invoke the MediationRewardedVideoAdListener.onRewarded()
method with an instance of RewardItem
as an argument.
Forward ad events to Google Mobile Ads SDK
Your adapter is required to notify the Google Mobile Ads SDK when any of the following ad events occur:
MediationRewardedVideoAdListener method | Call when |
---|---|
onAdOpened() | A full screen overlay covers the app content |
onVideoStarted() | The video ad starts |
onAdClicked() | The video ad is clicked |
onAdLeftApplication() | The user leaves the application due to the video ad (for example, to go to the browser) |
onRewarded() | The video ad rewards the user |
onAdClosed() | The video ad is closed |
An example implementation of ad forwarding to the Google Mobile Ads SDK is shown below:
/**
* A {@link SampleRewardedVideoAdListener} that forwards events to AdMob mediation's {@link }.
*/
public class SampleMediationRewardedVideoEventForwarder extends SampleRewardedVideoAdListener {
private MediationRewardedVideoAdListener mMediationRewardedVideoAdListener;
private SampleAdapter mSampleAdapter;
private boolean mIsInitialized;
/**
* Creates a new {@link SampleMediationRewardedVideoEventForwarder}.
*
* @param listener An AdMob Mediation {@link MediationRewardedVideoAdListener} that should
* receive forwarded events.
* @param sampleAdapter A {@link SampleAdapter} mediation adapter.
*/
public SampleMediationRewardedVideoEventForwarder(MediationRewardedVideoAdListener listener,
SampleAdapter sampleAdapter) {
this.mMediationRewardedVideoAdListener = listener;
this.mSampleAdapter = sampleAdapter;
}
/**
* @return whether or not the Sample SDK is initialized.
*/
public boolean isInitialized() {
return mIsInitialized;
}
@Override
public void onRewardedVideoInitialized() {
super.onRewardedVideoInitialized();
mIsInitialized = true;
mMediationRewardedVideoAdListener.onInitializationSucceeded(mSampleAdapter);
}
@Override
public void onRewardedVideoInitializationFailed(SampleErrorCode error) {
super.onRewardedVideoInitializationFailed(error);
mIsInitialized = false;
mMediationRewardedVideoAdListener.onInitializationFailed(
mSampleAdapter, getAdMobErrorCode(error));
}
@Override
public void onAdRewarded(final String rewardType, final int amount) {
super.onAdRewarded(rewardType, amount);
/*
* AdMob requires a reward item with a reward type and amount to be sent when sending the
* rewarded callback. If your SDK does not have a reward amount you need to do the following:
*
* 1. AdMob provides an ability to override the reward value in the front end. Document
* this asking the publisher to override the reward value on AdMob's front end.
* 2. Send a reward item with default values for the type (an empty string "") and reward
* amount (1).
*/
mMediationRewardedVideoAdListener.onRewarded(
mSampleAdapter, new SampleRewardItem(rewardType, amount));
}
@Override
public void onAdClicked() {
super.onAdClicked();
mMediationRewardedVideoAdListener.onAdClicked(mSampleAdapter);
}
@Override
public void onAdFullScreen() {
super.onAdFullScreen();
mMediationRewardedVideoAdListener.onAdOpened(mSampleAdapter);
// Only send video started here if your SDK starts video immediately after the ad has been
// opened/is fullscreen.
mMediationRewardedVideoAdListener.onVideoStarted(mSampleAdapter);
}
@Override
public void onAdClosed() {
super.onAdClosed();
mMediationRewardedVideoAdListener.onAdClosed(mSampleAdapter);
}
/**
* Forwards the ad loaded event to AdMob SDK. The Sample SDK does not have an ad loaded
* callback, the adapter calls this method if an ad is available when loadAd is called.
*/
protected void onAdLoaded() {
mMediationRewardedVideoAdListener.onAdLoaded(mSampleAdapter);
}
/**
* Forwards the ad failed event to AdMob SDK. The Sample SDK does not have an ad failed to
* load callback, the adapter calls this method to forward the failure callback.
*/
protected void onAdFailedToLoad() {
mMediationRewardedVideoAdListener.onAdFailedToLoad(
mSampleAdapter, AdRequest.ERROR_CODE_NO_FILL);
}
/**
* Converts {@link SampleErrorCode} into an AdMob SDK's {@link AdRequest} error code.
*
* @param errorCode a Sample SDK error code.
* @return an AdMob SDK readable error code.
*/
private int getAdMobErrorCode(SampleErrorCode errorCode) {
switch (errorCode) {
case BAD_REQUEST:
return AdRequest.ERROR_CODE_INVALID_REQUEST;
case NETWORK_ERROR:
return AdRequest.ERROR_CODE_NETWORK_ERROR;
case NO_INVENTORY:
return AdRequest.ERROR_CODE_NO_FILL;
case UNKNOWN:
default:
return AdRequest.ERROR_CODE_INTERNAL_ERROR;
}
}
}
Third party ad networks likely have ad events listeners for their ad network. Ad events from
the third party SDK should be mapped to corresponding ad events for the
MediationRewardedVideoAdListener
provided in the initialize()
method of the adapter and
invoked at the appropriate time.
Notification of context changes
Your adapter can optionally implement the OnContextChangedListener
to be notified of a change to
the current context. The onContextChanged
method is invoked when there is an update to the
RewardedVideoAd
object's current context. The updated activity context can be accessed as shown below:
@Override
public void onContextChanged(Context context) {
if (context instanceof Activity) {
SampleRewardedVideo.setCurrentActivity((Activity) context);
}
}
Additional targeting parameters
The
MediationAdRequest
contains some common targeting information that you can use for ad targeting
such as:
Accept custom parameters to your adapter
The ad network your adapter is mediating to may support extra targeting parameters or inputs that are
not covered by the information provided in the MediationAdRequest
. If this applies to your adapter,
you can ask publishers to provide a bundle of information to your network. This bundle is passed to your
adapter in both the initialize()
and loadAd()
methods.
For example, here is how a publisher could provide a bundle to the SampleAdapter
adapter:
Bundle bundle = new Bundle();
bundle.putBoolean("ShouldAddAwesomeSauce", true);
AdRequest adRequest = new AdRequest.Builder()
.addNetworkExtrasBundle(SampleAdapter.class, bundle)
.build();
To make it easier for developers to create this bundle for you, a best practice is adding a convenience class into your adapter to help publishers construct a bundle for your adapter:
public static final class MediationExtrasBundleBuilder {
// Keys to add and obtain the extra parameters from the bundle.
private static final String KEY_AWESOME_SAUCE = "awesome_sauce";
/**
* An extra value used to populate the "ShouldAddAwesomeSauce" property of the Sample
* SDK's ad request.
*/
private boolean mShouldAddAwesomeSauce;
public MediationExtrasBundleBuilder setShouldAddAwesomeSauce(
boolean shouldAddAwesomeSauce) {
this.mShouldAddAwesomeSauce = shouldAddAwesomeSauce;
return MediationExtrasBundleBuilder.this;
}
public MediationExtrasBundleBuilder setIncome(int income) {
this.mIncome = income;
return MediationExtrasBundleBuilder.this;
}
public Bundle build() {
Bundle extras = new Bundle();
extras.putInt(KEY_INCOME, mIncome);
return extras;
}
}
This convenience class provides a cleaner API for the developer to generate a bundle for your network:
Bundle sampleAdNetworkBundle =
new SampleAdapter.MediationExtrasBundleBuilder().setShouldAddAwesomeSauce(true).build();