Native Custom Events

本指南适用于希望使用Ad Manager中介功能加载和展示不受Ad Manager支持的广告联盟提供的原生广告的发布商。(有关如何使用Ad Manager中介功能加载和展示横幅广告或插页式广告的信息,请参阅自定义事件。)作为中介适配器类,自定义事件能从其他广告联盟请求广告。当其中一个类的名称添加至广告单元的中介设置后,SDK 就可将其实例化,并通过它获取广告。原生自定义事件类需要能够执行以下任务:

  • 向参与中介的广告联盟请求原生广告。
  • 将事件从参与中介的广告联盟的 SDK 转发至 Google 移动广告 SDK。
  • 使用 UnifiedNativeAdMapper 将参与中介的原生广告映射到Ad Manager的原生广告界面。

下文将具体介绍各个任务。在我们的 GitHub 代码库中,您还可以找到示例自定义事件项目的完整源代码。

前提条件

要实现Ad Manager自定义事件,必须先将移动广告 SDK 集成到您的项目中。您可能还需要先了解如何发出 PublisherAdRequest以及中介的工作原理。

示例 SDK

本指南中的代码段选自我们的示例自定义事件项目,该项目包括了一个“示例 SDK”。我们将在示例中使用这个模拟 SDK 进行演示,介绍如何构建一个使用其他广告联盟的 SDK 进行中介的自定义事件。

示例 SDK 的类与广告联盟的正式版 SDK 中的类相似。它有请求对象(如 SampleNativeAdRequest)、广告加载程序(如 SampleNativeAdLoader),以及用于模拟真实广告联盟 SDK 的其他类、常量和界面。不过,它请求到的广告是模拟广告,不会产生任何额外的网络流量。

请求原生广告

requestNativeAd() 方法

自定义事件类必须实现 CustomEventNative 界面,其中包含 Google 移动广告 SDK 用来从自定义事件请求原生广告的方法:

Java

void requestNativeAd(Context context,
        CustomEventNativeListener listener,
        String serverParameter,
        NativeMediationAdRequest mediationAdRequest,
        Bundle customEventExtras);

Kotlin

override fun requestNativeAd(context: Context,
        listener: CustomEventNativeListener,
        serverParameter: String,
        mediationAdRequest: NativeMediationAdRequest,
        customEventExtras: Bundle?)

调用此方法时,自定义事件应从参与中介的广告联盟异步请求原生广告。requestNativeAd() 的以下参数携带了自定义事件在发出请求时可以使用的信息:

  • serverParameter - 将自定义事件添加至广告单元的中介配置时,发布商可输入一个会随各个请求一起传递的字符串值。此参数会保留该值(通常是由参与中介的广告联盟签发的另一个广告单元 ID)。
  • mediationAdRequest - NativeMediationAdRequest 对象,它包含单个请求特有的各种属性,例如请求了哪些原生格式。NativeMediationAdRequestMediationAdRequest 的子类,因此还会包含发布商在请求时提供的其他定位信息的属性。
  • customEventExtras - 包含与发布商提供的请求相关的任何额外信息的 Bundle。创建广告请求时,发布商可以使用 addNetworkExtrasBundle() 方法来提供适用于特定中介适配器和自定义事件的信息。本参数包含了发布商为给定的自定义事件类提供的所有额外信息。

除了上述携带请求信息的参数外,还有另外两个参数:

  • context - 可根据自定义事件的需求来使用的 Context 对象。
  • listener - CustomEventNativeListener 对象,自定义事件应使用它来转发事件。

监听器对象极为重要,因为要使用它向 Google 移动广告 SDK 报告事件。本指南会在将事件转发至移动广告 SDK 中对此进行介绍。

以下代码段选自我们的示例自定义事件项目,显示了已实现的 requestNativeAd() 方法:

SampleCustomEvent(节选)

Java

@Override
public void requestNativeAd(Context context,
                            CustomEventNativeListener customEventNativeListener,
                            String serverParameter,
                            NativeMediationAdRequest nativeMediationAdRequest,
                            Bundle extras) {
    // Create one of the Sample SDK's ad loaders from which to request ads.
    SampleNativeAdLoader loader = new SampleNativeAdLoader(context);
    loader.setAdUnit(serverParameter);

    // Create a native request to give to the SampleNativeAdLoader.
    SampleNativeAdRequest request = new SampleNativeAdRequest();
    NativeAdOptions options = nativeMediationAdRequest.getNativeAdOptions();
    if (options != null) {
        // If the NativeAdOptions' shouldReturnUrlsForImageAssets is true, the adapter should
        // send just the URLs for the images.
        request.setShouldDownloadImages(!options.shouldReturnUrlsForImageAssets());

        // If your network does not support any of the following options, please make sure
        // that it is documented in your adapter's documentation.
        request.setShouldDownloadMultipleImages(options.shouldRequestMultipleImages());
        switch (options.getImageOrientation()) {
            case NativeAdOptions.ORIENTATION_LANDSCAPE:
                request.setPreferredImageOrientation(
                        SampleNativeAdRequest.IMAGE_ORIENTATION_LANDSCAPE);
                break;
            case NativeAdOptions.ORIENTATION_PORTRAIT:
                request.setPreferredImageOrientation(
                        SampleNativeAdRequest.IMAGE_ORIENTATION_PORTRAIT);
                break;
            case NativeAdOptions.ORIENTATION_ANY:
            default:
                request.setPreferredImageOrientation(
                        SampleNativeAdRequest.IMAGE_ORIENTATION_ANY);
        }
    }

    if (!nativeMediationAdRequest.isUnifiedNativeAdRequested()) {
        Log.e(TAG, "Failed to load ad. Request must be for unified native ads.");
        customEventNativeListener.onAdFailedToLoad(AdRequest.ERROR_CODE_INVALID_REQUEST);
        return;
    }

    loader.setNativeAdListener(
            new SampleCustomNativeEventForwarder(customEventNativeListener, options));

    // Begin a request.
    loader.fetchAd(request);
}

Kotlin

override fun requestNativeAd(context: Context,
                             customEventNativeListener: CustomEventNativeListener,
                             serverParameter: String,
                             nativeMediationAdRequest: NativeMediationAdRequest,
                             extras: Bundle) {
    // Create one of the Sample SDK's ad loaders from which to request ads.
    val loader = SampleNativeAdLoader(context)
    loader.setAdUnit(serverParameter)

    // Create a native request to give to the SampleNativeAdLoader.
    val request = SampleNativeAdRequest()
    val options = nativeMediationAdRequest.nativeAdOptions
    if (options != null) {
        // If the NativeAdOptions' shouldReturnUrlsForImageAssets is true, the adapter should
        // send just the URLs for the images.
        request.shouldDownloadImages = !options.shouldReturnUrlsForImageAssets()

        // If your network does not support any of the following options, please make sure
        // that it is documented in your adapter's documentation.
        request.setShouldDownloadMultipleImages(options.shouldRequestMultipleImages())
        when (options.imageOrientation) {
            NativeAdOptions.ORIENTATION_LANDSCAPE -> request.setPreferredImageOrientation(
                    SampleNativeAdRequest.IMAGE_ORIENTATION_LANDSCAPE)
            NativeAdOptions.ORIENTATION_PORTRAIT -> request.setPreferredImageOrientation(
                    SampleNativeAdRequest.IMAGE_ORIENTATION_PORTRAIT)
            NativeAdOptions.ORIENTATION_ANY -> request.setPreferredImageOrientation(
                    SampleNativeAdRequest.IMAGE_ORIENTATION_ANY)
            else -> request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_ANY)
        }
    }

    if (!nativeMediationAdRequest.isUnifiedNativeAdRequested) {
        Log.e(TAG, "Failed to load ad. Request must be for unified native ads.")
        customEventNativeListener.onAdFailedToLoad(AdRequest.ERROR_CODE_INVALID_REQUEST)
        return
    }

    loader.setNativeAdListener(
            SampleCustomNativeEventForwarder(customEventNativeListener, options))

    // Begin a request.
    loader.fetchAd(request)
}

这是一个示例自定义事件,通过模拟示例 SDK 中转至虚构的广告联盟。自定义事件使用 requestNativeAd() 参数中提供的信息来构建 SampleNativeAdRequest(示例 SDK 提供的类),然后使用该类从示例 SDK 的 SampleNativeAdLoader 请求广告。此外,它还会创建一个 SampleCustomEventNativeForwarder 将事件转发回 Google 移动广告 SDK。

NativeAdOptions

发出原生广告请求时,发布商会使用 NativeAdOptions 对象指定自己对于该请求的各种偏好,例如,应使用何种方式返回图片素材资源。您的自定义事件需要检查并遵从这些偏好设置。自定义事件可以使用由 NativeMediationAdRequest 对象提供的 getNativeAdOptions() 方法来获取请求的 NativeAdOptions 对象:

Java

NativeAdOptions options = mediationAdRequest.getNativeAdOptions();

Kotlin

val options = mediationAdRequest.nativeAdOptions

获取 NativeAdOptions 后,自定义事件可以读取其属性并执行相应的操作。例如,如果 NativeAdOptions 中的 shouldReturnUrlsForImageAssets 值为 false(默认值),则自定义事件必须返回实际图片素材资源,而不只是网址。在这种情况下,如果用作中介的 SDK 只提供图片的网址,那么自定义事件必须通过这些网址下载图片文件,并在其映射的原生广告中将图片文件的数据提供给发布商。

将事件转发至移动广告 SDK

当自定义事件尝试从参与中介的广告联盟加载原生广告时,可能会发生以下几种情况:SDK 可能会成功返回原生广告,也可能返回错误,或者只报告没有可用的广告。类似地,当用户点按某个广告时,参与中介的 SDK 可能会打开叠加层,也可能会彻底退出应用并启动外部浏览器。对 Google 移动广告 SDK 而言,掌握这些事件非常重要,因此它会向 requestNativeAd() 方法提供一个 CustomEventNativeListener 对象作为参数。

自定义事件的工作之一是监听来自参与中介的 SDK 的事件,并将它们映射到相应的 CustomEventNativeListener 回调。您的自定义事件需要掌握以下 CustomEventNativeListener 回调:

  • onAdLoaded() - 此方法应在自定义事件成功加载原生广告时调用。它需要一个 UnifiedNativeAdMapper,后者可将您的广告联盟 SDK 的原生广告映射到 Google 移动广告 SDK 能够识别的对象。有关如何创建 UnifiedNativeAdMapper 的详情,请查阅映射原生广告
  • onAdFailedToLoad() - 当自定义事件尝试加载原生广告但未能成功时,应使用此方法报告失败。它需要一个整数参数,该参数应被设置为以下错误常量之一:

  • onAdLeftApplication() - 当参与中介的 SDK 导致用户的关注点离开发布商的应用(最常见的是打开外部浏览器)时,调用此方法。

  • onAdOpened() - 如果原生广告为响应用户的点按而打开叠加层或覆盖界面的单独活动(包括外部浏览器),则应调用此方法。如果是打开外部浏览器,则自定义事件应在调用 onAdLeftApplication 之前调用 onAdOpened

  • onAdClosed() - 如果叠加层或覆盖界面的单独活动关闭,则应调用此方法,以表示该控件正在转移回包含原生广告的应用。

监听器还提供了各种方法,用于报告那些选择自行跟踪点击或展示的自定义事件提供的点击和展示次数,详情请参阅替换默认的点击处理和展示记录方法。一种方法用于向 Google 移动广告 SDK 报告点击,一种方法用于报告展示:

  • onAdClicked() - 此方法应在用户点击原生广告时调用。
  • onAdImpression() - 类似地,此方法应在参与中介的 SDK 记录广告的展示时调用。

有许多方法可以确保事件的正确转发,但最简单的一个方法就是创建专门用作转发器的类。下面就是我们的自定义事件示例项目中提供的这样一个类:

SampleCustomNativeEventForwarder

Java

public class SampleCustomNativeEventForwarder extends SampleNativeAdListener {
    private CustomEventNativeListener nativeListener;
    private NativeAdOptions nativeAdOptions;

    public SampleCustomNativeEventForwarder(
            CustomEventNativeListener listener, NativeAdOptions options) {
        this.nativeListener = listener;
        this.nativeAdOptions = options;
    }

    @Override
    public void onNativeAdFetched(SampleNativeAd ad) {
        SampleUnifiedNativeAdMapper mapper =
                new SampleUnifiedNativeAdMapper(ad, nativeAdOptions);
        nativeListener.onAdLoaded(mapper);
    }

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

Kotlin

class SampleCustomNativeEventForwarder(
        private val nativeListener: CustomEventNativeListener,
        private val nativeAdOptions: NativeAdOptions) : SampleNativeAdListener() {

    fun onNativeAdFetched(ad: SampleNativeAd) {
        val mapper = SampleUnifiedNativeAdMapper(ad, nativeAdOptions)
        nativeListener.onAdLoaded(mapper)
    }

    fun onAdFetchFailed(errorCode: SampleErrorCode) {
        when (errorCode) {
            UNKNOWN -> nativeListener.onAdFailedToLoad(AdRequest.ERROR_CODE_INTERNAL_ERROR)
            BAD_REQUEST -> nativeListener.onAdFailedToLoad(AdRequest.ERROR_CODE_INVALID_REQUEST)
            NETWORK_ERROR -> nativeListener.onAdFailedToLoad(AdRequest.ERROR_CODE_NETWORK_ERROR)
            NO_INVENTORY -> nativeListener.onAdFailedToLoad(AdRequest.ERROR_CODE_NO_FILL)
        }
    }
}

请注意,此类实现了示例 SDK 的 SampleNativeAdListener 界面。在 SampleCustomEvent(节选)中,已将此转发器类的实例提供给了其 setNativeAdListener() 方法中的 SampleNativeAdLoader

Java

loader.setNativeAdListener(new SampleCustomNativeEventForwarder(customEventNativeListener, options));

Kotlin

loader.setNativeAdListener(SampleCustomNativeEventForwarder(customEventNativeListener, options))

这可确保示例 SDK 在有要报告的事件时调用 SampleCustomNativeEventForwarder 对象的监听器方法(onNativeAdFetched()onAdFetchFailed() 等等)。然后,转发器会调用 Google 移动广告 SDK 的 CustomEventNativeListener 上的相应方法转发事件。简而言之,Google 移动广告 SDK 会监听转发器,而转发器则监听参与中介的 SDK。

上面的 onAdFetchFailed() 示例方法很好地诠释了其中的运行方式。当示例 SDK 加载广告失败时,便会调用转发器的 onAdFetchFailed() 方法,并赋予它错误代码。转发器会检查该错误代码,并通过 Google 移动广告 SDK 使用的一个错误代码调用 CustomEventNativeListeneronAdFailedToLoad() 方法。这样一来,示例 SDK 事件就会转变成了 Google 移动广告 SDK 事件。

映射原生广告

对于原生广告,不同的 SDK 都有自己唯一的广告格式。例如,一个 SDK 可能返回包含“title”字段的对象,而另一个 SDK 返回的可能是包含“headline”字段的对象。此外,用于跟踪展示和处理点击的方法也可能会因 SDK 而异。UnifiedNativeAdMapper 负责调和这些差异,并调整参与中介的 SDK 的原生广告对象,以符合 Google 移动广告 SDK 预期的界面。自定义事件应扩展此类,以创建专属于它们参与中介的 SDK 的映射器。

以下是我们的示例自定义事件项目中的一个示例广告映射器:

SampleUnifiedNativeAdMapper

Java

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);
    }
}

Kotlin

class SampleUnifiedNativeAdMapper(private val sampleAd: SampleNativeAd) : UnifiedNativeAdMapper() {

    init {
        headline = sampleAd.headline
        body = sampleAd.body
        callToAction = sampleAd.callToAction
        starRating = sampleAd.starRating
        store = sampleAd.storeName
        icon = SampleNativeMappedImage(sampleAd.icon, sampleAd.iconUri,
                SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE)
        advertiser = sampleAd.advertiser

        val imagesList = ArrayList<NativeAd.Image>()
        imagesList.add(SampleNativeMappedImage(sampleAd.image, sampleAd.imageUri,
                SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE))
        images = imagesList

        if (sampleAd.price != null) {
            val formatter = NumberFormat.getCurrencyInstance()
            val priceString = formatter.format(sampleAd.price)
            price = priceString
        }

        val extras = Bundle()
        extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, sampleAd.degreeOfAwesomeness)
        this.extras = extras

        overrideClickHandling = false
        overrideImpressionRecording = false

        adChoicesContent = sampleAd.informationIcon
    }

    override fun recordImpression() {
        sampleAd.recordImpression()
    }

    override fun handleClick(view: View?) {
        sampleAd.handleClick(view)
    }
}

下面我们来介绍一下构造函数方法及其执行的一些操作:

保留对参与中介的原生广告对象的引用

构造函数接受 SampleNativeAdNativeAdOptions 参数。 SampleNativeAd 是示例 SDK 用于其原生广告的原生广告类。映射器需要使用对参与中介的广告的引用,以便传递点击和展示事件。 NativeAdOptions 包含了发布商对原生广告的偏好设置。两个参数均存储为局部变量。

设置映射的素材资源属性

构造函数使用 SampleNativeAd 对象在 UnifiedNativeAdMapper 中填充素材资源。例如,此代码可获取参与中介的广告的价格数据,然后用该数据设置映射器的价格:

Java

if (sampleAd.getPrice() != null) {
    NumberFormat formatter = NumberFormat.getCurrencyInstance();
    String priceString = formatter.format(sampleAd.getPrice());
    setPrice(priceString);
}

Kotlin

if (sampleAd.price != null) {
    val formatter = NumberFormat.getCurrencyInstance()
    val priceString = formatter.format(sampleAd.price)
    price = priceString
}

在本例中,参与中介的广告将价格存储为 double 数据,而Ad Manager为同一素材资源使用了 String 数据。映射器会负责处理这些数据类型之间的转换。

映射图片素材资源

与较为简单的数据类型(如 doubleString)相比,映射图片素材资源会复杂一些。因为图片既可以自动下载,也可以仅作为网址值返回,而且其“像素与 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;
    }
}

Kotlin

class SampleNativeMappedImage(private val drawable: Drawable,
                              private val imageUri: Uri,
                              private val scale: Double) : NativeAd.Image() {

    override fun getDrawable(): Drawable {
        return drawable
    }

    override fun getUri(): Uri {
        return imageUri
    }

    override fun getScale(): Double {
        return scale
    }
}

以下代码中的 SampleUnifiedNativeAdMapper 使用了其映射的图片类来设置映射器的图标图片素材资源:

Java

setIcon(new SampleNativeMappedImage(ad.getAppIcon(), ad.getAppIconUri(),
        SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));

Kotlin

icon = SampleNativeMappedImage(sampleAd.appIcon, sampleAd.appIconUri,
        SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE)

向额外信息 Bundle 添加其他字段

除了Ad Manager原生广告格式中的素材资源之外,一些参与中介的 SDK 可能还会提供额外的素材资源。UnifiedNativeAdMapper 类包含一个 setExtras() 方法,用于将这些素材资源传递给发布商。SampleUnifiedNativeAdMapper 将此用于示例 SDK 的“degree of awesomeness”素材资源:

Java

Bundle extras = new Bundle();
extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, ad.getDegreeOfAwesomeness());
this.setExtras(extras);

Kotlin

val extras = Bundle()
extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, sampleAd.degreeOfAwesomeness)
this.extras = extras

发布商可以使用 UnifiedNativeAd 类的 getExtras() 方法检索数据。

广告选择

您的自定义事件负责通过 UnifiedNativeAdMapper 上的 setAdChoicesContent() 方法提供“广告选择”图标。

以下是 SampleUnifiedNativeAdMapper 中的一段代码,展示了如何提供“广告选择”图标:

Java

public SampleUnifiedNativeAdMapper(SampleNativeAd ad) {
    ...
    setAdChoicesContent(sampleAd.getInformationIcon());
}

Kotlin

init {
    ...
    adChoicesContent = sampleAd.informationIcon
}

展示和点击事件

Google 移动广告 SDK 和参与中介的 SDK 都需要知道展示或点击发生的时间,但只有一个 SDK 需要跟踪这些事件。有两种不同做法可供自定义事件选用,具体取决于参与中介的 SDK 是否支持自行跟踪展示和点击。

使用 handleClick 和 recordImpression 处理点击和展示

如果参与中介的 SDK 不支持自行跟踪展示和点击,但提供了记录点击和展示的方法,则 Google 移动广告 SDK 可以跟踪这些事件,并通知适配器。UnifiedNativeAdMapper 包括 recordImpression()handleClick() 两个方法,自定义事件实现这两个方法后,可调用参与中介的原生广告对象上的相应方法。

SampleUnifiedNativeAdMapper 的处理方式如下所示:

Java

@Override
public void recordImpression() {
    sampleAd.recordImpression();
}

@Override
public void handleClick(View view) {
    sampleAd.handleClick(view);
}

Kotlin

override fun recordImpression() {
    sampleAd.recordImpression()
}

override fun handleClick(view: View) {
    sampleAd.handleClick(view)
}

SampleUnifiedNativeAdMapper 保留了对示例 SDK 的原生广告对象的引用,因此可轻松调用该对象上的相应方法来报告点击或展示。请注意,handleClick() 方法的唯一参数是与收到点击的原生广告素材资源相对应的 View 对象。

替换默认的点击处理和展示记录方法

一些参与中介的 SDK 可能偏好自行跟踪点击和展示。在这种情况下,您应该在 UnifiedNativeAdMapper 的构造函数中进行以下两次调用,以便替换默认的点击和展示跟踪方法:

Java

setOverrideClickHandling(true);
setOverrideImpressionRecording(true);

Kotlin

setOverrideClickHandling(true)
setOverrideImpressionRecording(true)

将事件转发至移动广告 SDK 中所述,自行跟踪点击和展示的自定义事件需要通过 onAdClicked()onAdImpression() 方法向 Google 移动广告 SDK 报告这些事件。

此外,您还应替换 trackViews() 方法,并使用它将原生广告视图传递给参与中介的 SDK 进行跟踪。本指南的代码段均来自我们的示例自定义事件项目,但其中的示例 SDK 并不使用这种做法。如果使用这种做法,则自定义事件代码可能如下所示:

Java

@Override
public void trackViews(View containerView,
        Map<String, View> clickableAssetViews,
        Map<String, View> nonClickableAssetViews) {
    sampleAd.setNativeAdViewForTracking(containerView);
}

Kotlin


override fun trackViews(containerView: View?,
        clickableAssetViews: Map<String, View>?,
        nonClickableAssetViews: Map<String, View>?) {
    sampleAd.setNativeAdViewForTracking(containerView)
}

如果参与中介的 SDK 支持跟踪具体素材资源,则可查看 clickableAssetViews 内部,以了解应设置哪些视图供用户点击。此映射的密钥使用了 UnifiedNativeAdAssetNames 中的素材资源名称。

UnifiedNativeAdMapper 提供相应的 untrackView() 方法,自定义事件可以替换该方法从而实现相反的目的,即释放对视图的任何引用并解除它与原生广告对象之间的关联。

使用自定义事件

要使用自定义事件,您需要将其添加至广告单元的中介配置。 这可在 Google Ad Manager 界面中完成。有关如何使用自定义事件配置收益组的说明,请参阅创建和管理收益组

在将自定义事件添加至广告单元的中介配置时,系统会要求您提供三项信息:

  • Class Name - 这是您的自定义事件的类名称,包含完整的软件包名称。
  • Label - 这是您希望Ad Manager界面在展示广告单元的中介来源时用于代表自定义事件的标签。它专供您使用,因为它只出现在Ad Manager界面上。
  • Parameter - 这是一个字符串值,每当针对该广告单元发出请求时,系统就会将其传递给相应的自定义事件。通常情况下,此字符串值会设置为参与中介的广告联盟提供的广告单元 ID。

以下是示例自定义事件条目的屏幕截图:

大功告成!至此,您已学习了为Ad Manager编写您自己的 Android 自定义事件所需掌握的全部内容。

发送以下问题的反馈:

此网页
Mobile Ads SDK for Android
Mobile Ads SDK for Android
需要帮助?请访问我们的支持页面