本指南适用于要构建中介适配器的广告联盟。如果您是发布商,请参阅发布商中介说明。
广告联盟适配器是广告联盟与 Google 移动广告中介之间的通信层。
适配器负责实现 MediationBannerAdapter
(用于支持横幅广告)和 MediationInterstitialAdapter
(用于支持插页式广告)。此外,它还必须在适当的时间调用 MediationBannerListener
和 MediationInterstitialListener
中的回调,将这些事件通知 Google 移动广告中介,这些事件也可以转发给开发者。
示例广告联盟
本指南演示了如何为示例广告联盟构建适配器。示例广告联盟包含以下大多数广告联盟都会提供的一些典型的类:
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();
}
如需详细了解这些类,请参阅完整的 SDK 实现。
实现横幅广告适配器
如需实现支持横幅广告的适配器,请创建一个实现 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() {}
}
在深入了解如何实现 MediationBannerAdapter
之前,我们先来介绍一下服务器参数和中介额外信息 (extras),以及如何将这些值传递给适配器。
服务器参数
您的广告网络可能需要使用一些标识符来识别发布商。例如,示例广告联盟只需要一个广告单元。requestBannerAd()
内的 serverParameters
软件包中为您提供了这些必需参数。在开发期间,您可以假设该 bundle 中已经填充了您需要的键:
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 会向您发送一份调查问卷,询问您需要从发布商处获取哪些服务器参数才能请求和投放广告。AdMob 将根据输入的内容在 AdMob 界面中配置您的广告网络。下面的屏幕截图显示 Millennial Media 需要 APID,InMobi 需要 App ID。
AdMob 将在实例化适配器时使用此信息来填充 serverParameters
bundle。
如需详细了解发布商如何配置中介广告联盟,请参阅这篇文章。
其他定位参数
MediationAdRequest
包含一些可用于广告定位的常用定位信息,例如:
中介额外信息 (extras)
如果您的广告网络支持 MediationAdRequest
未提供的定位信息,应用开发者可以将一系列 mediationExtras
专门传递到您的广告网络。中介提供了如何传递中介额外信息的示例。
为了让开发者更轻松地选择传递这些信息,您可以在适配器中提供 bundle 构建器类。假设您的网络支持传递收入值。您可以在适配器中添加用于设置收入的构建器类:
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;
}
}
此类将为开发者提供一个干净的 API,用于为您的广告联盟生成 bundle:
Bundle sampleAdapterBundle =
new SampleAdapter.BundleBuilder().setIncome(100000).build();
requestBannerAd()
现在,您已经了解了服务器参数和中介额外信息 (extras),我们可以使用它们来构建 MediationBannerAdapter
。
系统会在适配器实例化后立即调用 requestBannerAd()
方法。您应在此处创建广告视图并发出横幅广告请求。
示例广告联盟的 requestBannerAd()
实现如下所示:
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);
}
}
请勿假设上下文参数的类型为 Activity
。根据发布商的实现情况,Google 移动广告中介可能会向您的适配器转发应用上下文。如果您的适配器无法处理应用上下文,建议您使用错误代码 AdRequest.ERROR_CODE_INVALID_REQUEST
调用 onAdFailedToLoad()
。
MediationBannerListener 回调
您应将提供给您的 MediationBannerListener
保存在 requestBannerAd()
中,以便将广告事件转发回 Google 移动广告中介。每个回调函数均必须在广告生命周期的适当时间调用:
方法 | 致电时间 |
---|---|
onAdLoaded() |
横幅广告请求成功。 |
onAdFailedToLoad() |
横幅广告请求失败。 |
onAdClicked() |
用户点击了横幅广告。 |
onAdOpened() |
横幅广告呈现全屏视图时。 |
onAdClosed() |
用户在点击横幅广告后返回应用。 |
onAdLeftApplication() |
横幅广告会导致用户离开应用。 |
示例广告联盟适配器会创建一个名为 SampleBannerEventForwarder
的类来处理事件转发:
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);
}
}
请注意示例广告联盟适配器如何在同一回调中发送 onAdClicked
、onAdOpened
和 onAdLeftApplication
。虽然您广告联盟的回调可能与 Google 移动广告所需的回调并不完全匹配,但适配器仍负责提供合理的映射。
getBannerView
一旦您调用 MediationBannerListener.onAdLoaded()
,中介将会调用 getBannerView()
,以便在屏幕上显示您广告联盟的横幅广告视图。只需返回您在 requestBannerAd()
中创建的横幅广告视图即可:
@Override
public View getBannerView() {
return sampleAdView;
}
activity 生命周期事件
如果应用开发者向中介通知 onPause()
和 onResume()
活动事件,中介会向适配器通知这些事件。为横幅广告执行任何必要的暂停和恢复操作:
@Override
public void onPause() {
}
@Override
public void onResume() {
}
Sample Ad Network 不包括暂停或恢复调用,因此它会提供一个空的实现。
当适配器即将销毁时,中介会尽力尝试调用 onDestroy()
。请在此时执行必要的清理:
@Override
public void onDestroy() {
if (sampleAdView != null) {
sampleAdView.destroy();
}
}
智能横幅广告
Google 移动广告 SDK 支持智能横幅广告尺寸,即根据设备尺寸调整高度并采用全宽。
为了准确获取智能横幅广告的广告尺寸,适配器应使用 adSize.getWidthInPixels(context)
获取宽度,使用 adSize.getHeightInPixels(context)
(而不是 adSize.getHeight()
)获取高度。然后,此值应除以设备密度:
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);
然后,您可以在发出广告请求时使用 widthInDp
和 heightInDp
作为尺寸。
大功告成!现在,您已得到一个适用于横幅广告的有效中介适配器!有关参考信息,请点击此处查看 SampleAdapter 的完整实现。
实现插页式广告适配器
插页式广告的适配器实现与横幅广告的类似。如需实现支持插页式广告的适配器,请创建一个实现 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() {}
}
如果您的适配器还支持横幅广告,您可以使用同一适配器类来实现这两种接口。
在继续实现 MediationInterstitialAdapter
之前,请先熟悉服务器参数和中介额外信息 (extras)。
服务器参数(插页式)
请参阅横幅广告服务器参数部分。
其他定位参数(插页式)
请参阅横幅广告其他定位参数部分。
中介额外信息 (extras)(插页式)
请参阅横幅广告中介额外信息 (extras) 部分。
requestInterstitialAd
系统会在适配器实例化后立即调用 requestInterstitialAd()
方法。您应在此处创建插页式广告并发出插页式广告请求。
示例广告联盟的 requestInterstitialAd()
实现将如下所示:
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);
}
}
请勿假设上下文参数的类型为 Activity!Google 移动广告中介会转发应用开发者传递的上下文,而且很有可能传递应用上下文。如果您的适配器无法处理应用上下文,建议您使用错误代码 AdRequest.ERROR_CODE_INVALID_REQUEST
调用 onAdFailedToLoad
。
MediationInterstitialListener 回调
您应将提供给您的 MediationInterstitialListener
保存在 requestInterstitialAd
中,以便将广告事件转发回 Google 移动广告中介。每个回调函数均必须在广告生命周期的适当时间调用:
方法 | 致电时间 |
---|---|
onAdLoaded | 插页式广告请求成功时。 |
onAdFailedToLoad | 插页式广告请求失败。 |
onAdOpened | 插页式广告展示时。 |
onAdClosed | 插页式广告关闭时。 |
onAdLeftApplication | 插页式广告导致用户离开应用时。 |
showInterstitial
调用 MediationInterstitialListener.onAdLoaded()
后,您应等到调用 showInterstitial()
后再展示插页式广告。插页式广告何时展示,可能需要在请求发出几分钟之后才能展示。
showInterstitial()
的实现非常简单。只需展示您的插页式广告对象即可:
@Override
public void showInterstitial() {
sampleInterstitial.show();
}
活动生命周期事件(插页式广告)
请参阅横幅广告 activity 生命周期事件部分。
实现活动生命周期事件后,中介适配器就可以处理插页式广告了!有关参考信息,请点击此处查看 SampleAdapter 的完整实现。
常见问题解答
- 如果我的适配器仅支持横幅广告或插页式广告,而不是同时支持这两种广告,该怎么办?
-
如果您的适配器仅支持横幅广告,您只需实现
MediationBannerAdapter
接口。如果您的适配器仅支持插页式广告,您只需实现MediationInterstitialAdapter
接口即可。