前提条件
完成自定义事件设置。
请求原生广告
当到达广告瀑布流中介链中的自定义事件订单项时,
系统将对您提供的类名称调用 loadNativeAd()
方法,
创建自定义
事件。在这种情况下,该方法位于 SampleCustomEvent
中,后者随后会调用 SampleNativeCustomEventLoader
中的 loadNativeAd()
方法。
若要请求原生广告,请创建或修改扩展 Adapter
以实现 loadNativeAd()
的类。如果扩展 Adapter
的类已存在,请在该类中实现 loadNativeAd()
。此外,请创建一个新类来实现 UnifiedNativeAdMapper
。
在我们的自定义事件示例中,
SampleCustomEvent
会扩展 Adapter
类,然后委托给
SampleNativeCustomEventLoader
。
Java
package com.google.ads.mediation.sample.customevent; import com.google.android.gms.ads.mediation.Adapter; import com.google.android.gms.ads.mediation.MediationAdConfiguration; import com.google.android.gms.ads.mediation.MediationAdLoadCallback; import com.google.android.gms.ads.mediation.MediationNativeAdCallback; ... public class SampleCustomEvent extends Adapter { private SampleNativeCustomEventLoader nativeLoader; @Override public void loadNativeAd( @NonNull MediationNativeAdConfiguration adConfiguration, @NonNull MediationAdLoadCallback<UnifiedNativeAdMapper, MediationNativeAdCallback> callback) { nativeLoader = new SampleNativeCustomEventLoader(adConfiguration, callback); nativeLoader.loadAd(); } }
SampleNativeCustomEventLoader
负责以下任务:
加载原生广告。
实现
UnifiedNativeAdMapper
类。接收广告事件回调并将其报告给 Google 移动广告 SDK。
AdMob 界面中定义的可选参数是
包含的广告配置中此参数可通过 adConfiguration.getServerParameters().getString(MediationConfiguration.CUSTOM_EVENT_SERVER_PARAMETER_FIELD)
进行访问。此参数通常是广告联盟 SDK
所需的资源。
Java
package com.google.ads.mediation.sample.customevent; import com.google.android.gms.ads.mediation.Adapter; import com.google.android.gms.ads.mediation.MediationNativeAdConfiguration; import com.google.android.gms.ads.mediation.MediationAdLoadCallback; import com.google.android.gms.ads.mediation.MediationNativeAdCallback; ... public class SampleNativeCustomEventLoader extends SampleNativeAdListener { /** Configuration for requesting the native ad from the third-party network. */ private final MediationNativeAdConfiguration mediationNativeAdConfiguration; /** Callback that fires on loading success or failure. */ private final MediationAdLoadCallback<UnifiedNativeAdMapper, MediationNativeAdCallback> mediationAdLoadCallback; /** Callback for native ad events. */ private MediationNativeAdCallback nativeAdCallback; /** Constructor */ public SampleNativeCustomEventLoader( @NonNull MediationNativeAdConfiguration mediationNativeAdConfiguration, @NonNull MediationAdLoadCallback<MediationNativeAd, MediationNativeAdCallback> mediationAdLoadCallback) { this.mediationNativeAdConfiguration = mediationNativeAdConfiguration; this.mediationAdLoadCallback = mediationAdLoadCallback; } /** Loads the native ad from the third-party ad network. */ public void loadAd() { // Create one of the Sample SDK's ad loaders to request ads. Log.i("NativeCustomEvent", "Begin loading native ad."); SampleNativeAdLoader loader = new SampleNativeAdLoader(mediationNativeAdConfiguration.getContext()); // All custom events have a server parameter named "parameter" that returns // back the parameter entered into the UI when defining the custom event. String serverParameter = mediationNativeAdConfiguration .getServerParameters() .getString(MediationConfiguration .CUSTOM_EVENT_SERVER_PARAMETER_FIELD); Log.d("NativeCustomEvent", "Received server parameter."); loader.setAdUnit(serverParameter); // Create a native request to give to the SampleNativeAdLoader. SampleNativeAdRequest request = new SampleNativeAdRequest(); NativeAdOptions options = mediationNativeAdConfiguration.getNativeAdOptions(); if (options != null) { // If the NativeAdOptions' shouldReturnUrlsForImageAssets is true, the adapter should // send just the URLs for the images. request.setShouldDownloadImages(!options.shouldReturnUrlsForImageAssets()); request.setShouldDownloadMultipleImages(options.shouldRequestMultipleImages()); switch (options.getMediaAspectRatio()) { case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_LANDSCAPE: request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_LANDSCAPE); break; case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_PORTRAIT: request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_PORTRAIT); break; case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_SQUARE: case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_ANY: case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_UNKNOWN: default: request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_ANY); } } loader.setNativeAdListener(this); // Begin a request. Log.i("NativeCustomEvent", "Start fetching native ad."); loader.fetchAd(request); } }
根据广告是成功抓取还是遇到错误,您可以
会调用
onSuccess()
或
onFailure()
。
通过传入实现 MediationNativeAd
的类的实例调用 onSuccess()
。
通常,这些方法是在您的适配器所实现的第三方 SDK 的回调中实现的。在此示例中,示例 SDK 具有一个 SampleAdListener
及相关回调:
Java
@Override public void onNativeAdFetched(SampleNativeAd ad) { SampleUnifiedNativeAdMapper mapper = new SampleUnifiedNativeAdMapper(ad); mediationNativeAdCallback = mediationAdLoadCallback.onSuccess(mapper); } @Override public void onAdFetchFailed(SampleErrorCode errorCode) { mediationAdLoadCallback.onFailure(SampleCustomEventError.createSampleSdkError(errorCode)); }
映射原生广告
对于原生广告,不同的 SDK 都有自己独特的广告格式。例如,一个 SDK 可能返回包含“title”字段的对象,而另一个 SDK 返回的对象可能包含“headline”字段。此外,用于跟踪展示和处理点击的方法也可能会因 SDK 而异。
UnifiedNativeAdMapper
负责调和这些差异,并调整参与中介的 SDK 的原生广告对象,使其与 Google 移动广告 SDK 预期的接口相匹配。自定义事件应扩展此类以创建
他们自己的参与中介的 SDK 专属的映射器。以下是 Google Ads 提供的
我们的示例自定义事件项目:
Java
package com.google.ads.mediation.sample.customevent; import com.google.android.gms.ads.mediation.UnifiedNativeAdMapper; import com.google.android.gms.ads.nativead.NativeAd; ... public class SampleUnifiedNativeAdMapper extends UnifiedNativeAdMapper { private final SampleNativeAd sampleAd; public SampleUnifiedNativeAdMapper(SampleNativeAd ad) { sampleAd = ad; setHeadline(sampleAd.getHeadline()); setBody(sampleAd.getBody()); setCallToAction(sampleAd.getCallToAction()); setStarRating(sampleAd.getStarRating()); setStore(sampleAd.getStoreName()); setIcon( new SampleNativeMappedImage( ad.getIcon(), ad.getIconUri(), SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE)); setAdvertiser(ad.getAdvertiser()); List<NativeAd.Image> imagesList = new ArrayList<NativeAd.Image>(); imagesList.add(new SampleNativeMappedImage(ad.getImage(), ad.getImageUri(), SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE)); setImages(imagesList); if (sampleAd.getPrice() != null) { NumberFormat formatter = NumberFormat.getCurrencyInstance(); String priceString = formatter.format(sampleAd.getPrice()); setPrice(priceString); } Bundle extras = new Bundle(); extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, ad.getDegreeOfAwesomeness()); this.setExtras(extras); setOverrideClickHandling(false); setOverrideImpressionRecording(false); setAdChoicesContent(sampleAd.getInformationIcon()); } @Override public void recordImpression() { sampleAd.recordImpression(); } @Override public void handleClick(View view) { sampleAd.handleClick(view); } // The Sample SDK doesn't do its own impression/click tracking, instead relies on its // publishers calling the recordImpression and handleClick methods on its native ad object. So // there's no need to pass a reference to the View being used to display the native ad. If // your mediated network does need a reference to the view, the following method can be used // to provide one. @Override public void trackViews(View containerView, Map<String, View> clickableAssetViews, Map<String, View> nonClickableAssetViews) { super.trackViews(containerView, clickableAssetViews, nonClickableAssetViews); // If your ad network SDK does its own impression tracking, here is where you can track the // top level native ad view and its individual asset views. } @Override public void untrackView(View view) { super.untrackView(view); // Here you would remove any trackers from the View added in trackView. } }
现在,我们来详细了解构造函数代码。
保留对参与中介的原生广告对象的引用
构造函数接受 SampleNativeAd
参数,即所使用的原生广告类
。映射器需要引用参与中介的广告才能传递点击和展示事件。SampleNativeAd
会存储为局部变量。
设置映射的素材资源属性
构造函数使用 SampleNativeAd
对象在
UnifiedNativeAdMapper
。
此代码段可获取参与中介的广告的价格数据,并用该数据设置映射器的 价格:
Java
if (sampleAd.getPrice() != null) { NumberFormat formatter = NumberFormat.getCurrencyInstance(); String priceString = formatter.format(sampleAd.getPrice()); setPrice(priceString); }
在此示例中,参与中介的广告以 double
格式存储价格,而 AdMob 对同一素材资源使用的却是 String
格式。通过
映射器负责处理这些类型的转换。
映射图片素材资源
与映射 double
或 String
等数据类型相比,映射图片素材资源会更加复杂。图片既可以自动下载,也可以作为网址值返回,而且其“像素与 dpi 的比例”可能也不尽相同。
为帮助您管理这些详细信息,Google 移动广告 SDK 提供了
NativeAd.Image
类。您需要创建 UnifiedNativeAdMapper
的子类来映射参与中介的原生广告,还应采用几乎与此相同的方式创建 NativeAd.Image
的子类来映射图片素材资源。
下面是自定义事件的 SampleNativeMappedImage
类示例:
Java
public class SampleNativeMappedImage extends NativeAd.Image { private Drawable drawable; private Uri imageUri; private double scale; public SampleNativeMappedImage(Drawable drawable, Uri imageUri, double scale) { this.drawable = drawable; this.imageUri = imageUri; this.scale = scale; } @Override public Drawable getDrawable() { return drawable; } @Override public Uri getUri() { return imageUri; } @Override public double getScale() { return scale; } }
以下代码中的 SampleNativeAdMapper
使用了其映射的图片类来设置映射器的图标图片素材资源:
Java
setIcon(new SampleNativeMappedImage(ad.getAppIcon(), ad.getAppIconUri(), SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));
向 extras 包添加字段
除了
AdMob 原生广告格式。UnifiedNativeAdMapper
类包含一个 setExtras()
方法,用于将这些素材资源传递给发布商。SampleNativeAdMapper
将其用于示例 SDK 的
"超棒程度"资产:
Java
Bundle extras = new Bundle(); extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, ad.getDegreeOfAwesomeness()); this.setExtras(extras);
发布商可以使用 NativeAd
类的 getExtras()
方法检索数据。
广告选择
您的自定义事件负责使用
UnifiedNativeAdMapper
上的 setAdChoicesContent()
方法。以下是 SampleNativeAdMapper
中的一段代码,展示了如何提供“广告选择”图标:
Java
public SampleNativeAdMapper(SampleNativeAd ad) { ... setAdChoicesContent(sampleAd.getInformationIcon()); }
展示和点击事件
Google 移动广告 SDK 和参与中介的 SDK 都需要知道展示或点击发生的时间,但只需要有一个 SDK 跟踪这些事件。有两种不同做法可供自定义事件选用,具体取决于参与中介的 SDK 是否支持自行跟踪展示和点击。
使用 Google 移动广告 SDK 跟踪点击和展示
如果参与中介的 SDK 不自行执行展示和点击跟踪,但提供了记录点击和展示的方法,则 Google 移动广告 SDK 可以跟踪这些事件并通知适配器。通过
UnifiedNativeAdMapper
类包含两个方法:
recordImpression()
和handleClick()
通过实现自定义事件,您可以对参与中介的
原生广告对象:
Java
@Override public void recordImpression() { sampleAd.recordImpression(); } @Override public void handleClick(View view) { sampleAd.handleClick(view); }
由于 SampleNativeAdMapper
存储着对示例 SDK 的原生代码的引用,
它可以调用该对象中的相应方法来报告点击
。请注意,handleClick()
方法仅接受一个参数(即 View
对象),该对象与获得点击的原生广告素材资源相对应。
使用参与中介的 SDK 跟踪点击和展示
一些参与中介的 SDK 可能偏好自行跟踪点击和展示。在这种情况下,您应在 UnifiedNativeAdMapper
的构造函数中执行以下两项调用,以替换默认的点击和展示跟踪方法:
Java
setOverrideClickHandling(true); setOverrideImpressionRecording(true);
替换点击和展示跟踪方法的自定义事件需要向 Google 移动广告 SDK 报告 onAdClicked()
和 onAdImpression()
事件。
如需跟踪展示和点击次数,参与中介的 SDK 可能需要访问相应视图才能启用跟踪。自定义事件应覆盖
trackViews()
方法,并使用它将原生广告的视图传递给参与中介的
要跟踪的 SDK。我们自定义事件示例项目(本指南中的代码段均选自这一项目)中的示例 SDK 并没有采用这种做法。但如要采用这种做法,则自定义事件代码会大致如下:
Java
@Override public void trackViews(View containerView, Map<String, View> clickableAssetViews, Map<String, View> nonClickableAssetViews) { sampleAd.setNativeAdViewForTracking(containerView); }
如果参与中介的 SDK 支持跟踪具体素材资源,则可深入了解
clickableAssetViews
,用于了解应将哪些视图设置为可点击。此映射的键是 NativeAdAssetNames
中的素材资源名称。UnifiedNativeAdMapper
提供相应的 untrackView()
方法,自定义事件可以替换该方法
释放对视图的所有引用并解除它与原生广告的关联
对象。
将中介事件转发至 Google 移动广告 SDK
您可以在
MediationNativeAdCallback
文档。
您的自定义事件必须尽可能多地转发这些回调,以便您的应用从 Google 移动广告 SDK 接收这些等效事件。以下示例展示了如何使用回调:
到这里,我们已经实现针对原生广告的自定义事件。GitHub 上提供了完整的示例。