自訂原生廣告格式

自訂原生廣告格式

除了系統定義的原生格式以外,Ad Manager 發布商也可以定義自訂的素材資源清單,自行建立原生廣告格式。這類廣告稱為自訂原生廣告格式,可搭配預訂廣告使用。此 API 可讓發布者將任意結構化資料傳遞至應用程式。這些廣告會以 NativeCustomFormatAd 物件表示。

載入自訂原生廣告格式

本指南說明如何載入及顯示自訂原生廣告格式

建構 AdLoader

和原生廣告一樣,系統會使用 AdLoader 類別載入自訂原生廣告格式:

Java

AdLoader adLoader = new AdLoader.Builder(context, "/6499/example/native")
    .forCustomFormatAd("10063170",
      new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
          @Override
          public void onCustomFormatAdLoaded(NativeCustomFormatAd ad) {
              // Show the custom format and record an impression.
          }
      },
      new NativeCustomFormatAd.OnCustomClickListener() {
          @Override
          public void onCustomClick(NativeCustomFormatAd ad, String s) {
              // Handle the click action
          }
      })
    .withAdListener( ... )
    .withNativeAdOptions( ... )
    .build();

Kotlin

val adLoader = AdLoader.Builder(this, "/6499/example/native")
        .forCustomFormatAd("10063170",
            { ad ->
                // Show the custom format and record an impression.
            },
            { ad, s ->
            // Handle the click action
            })
        .withAdListener( ... )
        .withNativeAdOptions( ... )
        .build()

forCustomFormatAd 方法會設定 AdLoader,以便要求自訂原生廣告格式。目前有三個參數傳遞至方法:

  • AdLoader 應要求的自訂原生廣告格式 ID。每個自訂原生廣告格式都有相關聯的 ID。此參數代表應用程式想要 AdLoader 要求的格式。
  • 廣告成功載入時可叫用的 OnCustomFormatAdLoadedListener
  • 使用者輕觸或點選廣告時,要叫用的 OnCustomClickListener 選用項目。如要進一步瞭解這個事件監聽器,請參閱下方的「處理點擊和曝光次數」一節。

由於單一廣告單元可放送多種廣告格式,因此可使用不重複的格式 ID 多次呼叫 forCustomFormatAd,以便為多種可能的自訂原生廣告格式準備廣告載入器。

自訂原生廣告格式 ID

您可以在 Ad Manager UI 的「廣告放送」下拉式選單的「原生」部分,找到用於辨識自訂原生廣告格式的格式 ID:

每個自訂原生廣告格式 ID 都會顯示在名稱旁邊。按一下其中一個名稱,即可前往詳細資料畫面,顯示格式欄位的相關資訊:

您可以在這裡新增、編輯及移除個別欄位。記下每個資產的名稱。名稱是在顯示自訂原生廣告格式時,用來取得每個素材資源資料的鍵。

多媒體自訂原生廣告格式

自訂原生廣告格式與系統定義的廣告格式不同,發布商有權定義自己的廣告素材資源清單。因此,顯示格式的程序與系統定義的格式有下列幾種不同:

  1. NativeCustomFormatAd 類別是用來處理您在 Ad Manager 中定義的任何自訂原生廣告格式,因此資產並未使用「getter」名稱。而是提供 getTextgetImage 等方法,並將欄位名稱做為參數使用。
  2. 目前沒有可與 NativeCustomFormatAd 搭配使用的專屬廣告檢視畫面類別 (例如 NativeAdView)。您可以自由使用任何適合使用者體驗的版面配置,
  3. 由於沒有專屬的 ViewGroup 類別,因此您不必註冊任何用來顯示廣告素材資源的檢視畫面。這樣一來,顯示廣告時就少了幾行程式碼,但您之後必須再完成一些工作來處理點擊。

以下是顯示 NativeCustomFormatAd 的函式範例:

Java

public void displayCustomFormatAd (ViewGroup parent,
                                     NativeCustomFormatAd customFormatAd) {
    // Inflate a layout and add it to the parent ViewGroup.
    LayoutInflater inflater = (LayoutInflater) parent.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View adView = inflater.inflate(R.layout.custom_format_ad, parent);

    // Locate the TextView that will hold the value for "Headline" and
    // set its text.
    TextView myHeadlineView = (TextView) adView.findViewById(R.id.headline);
    myHeadlineView.setText(customFormatAd.getText("Headline"));

    // Locate the ImageView that will hold the value for "MainImage" and
    // set its drawable.
    Button myMainImageView = (ImageView) adView.findViewById(R.id.main_image);
    myMainImageView.setImageDrawable(
            customFormatAd.getImage("MainImage").getDrawable());

    ...
    // Continue locating views and displaying assets until finished.
    ...
}

Kotlin

public fun displayCustomFormatAd (parent: ViewGroup,
                                customFormatAd: NativeCustomFormatAd) {
    val adView = layoutInflater
            .inflate(R.layout.ad_simple_custom_format, null)

    val myHeadlineView = adView.findViewById<TextView>(R.id.headline)
    myHeadlineView.setText(customFormatAd.getText("Headline"));

    // Locate the ImageView that will hold the value for "MainImage" and
    // set its drawable.
    val myMainImageView = adView.findViewById(R.id.main_image);
    myMainImageView.setImageDrawable(
            customFormatAd.getImage("MainImage").drawable;

    ...
    // Continue locating views and displaying assets until finished.
    ...
}

自訂原生廣告格式的原生影片

建立自訂格式時,您可以選擇將該格式用於影片。

在應用程式實作中,您可以使用 NativeCustomFormatAd.getMediaContent() 取得媒體內容。然後呼叫 setMediaContent(),將媒體檢視畫面上的媒體內容設為媒體檢視畫面。如果廣告沒有影片內容,請制定替代計畫,以便在沒有影片的情況下放送廣告。

以下範例會檢查廣告是否包含影片內容,並在沒有影片時,顯示原位圖片:

Java

// Called when a custom native ad loads.
@Override
public void onCustomFormatAdLoaded(final NativeCustomFormatAd ad) {

  MediaContent mediaContent = ad.getMediaContent();

  // Assumes you have a FrameLayout in your view hierarchy with the id media_placeholder.
  FrameLayout mediaPlaceholder = (FrameLayout) findViewById(R.id.media_placeholder);

  // Apps can check the MediaContent's hasVideoContent property to determine if the
  // NativeCustomFormatAd has a video asset.
  if (mediaContent != null && mediaContent.hasVideoContent()) {
    MediaView mediaView = new MediaView(mediaPlaceholder.getContext());
    mediaView.setMediaContent(mediaContent);
    mediaPlaceholder.addView(mediaView);

    // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
    // VideoController will call methods on this object when events occur in the video
    // lifecycle.
    VideoController vc = mediaContent.getVideoController();
    vc.setVideoLifecycleCallbacks(
        new VideoController.VideoLifecycleCallbacks() {
          @Override
          public void onVideoEnd() {
            // Publishers should allow native ads to complete video playback before
            // refreshing or replacing them with another ad in the same UI location.
            super.onVideoEnd();
          }
        });
  } else {
    ImageView mainImage = new ImageView(this);
    mainImage.setAdjustViewBounds(true);
    mainImage.setImageDrawable(ad.getImage("MainImage").getDrawable());
    mediaPlaceholder.addView(mainImage);
    mainImage.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View view) {
            ad.performClick("MainImage");
          }
        });
  }
}

Kotlin

// Called when a custom native ad loads.
NativeCustomFormatAd.OnCustomFormatAdLoadedListener { ad ->

  val mediaContent = ad.mediaContent

  // Apps can check the MediaContent's hasVideoContent property to determine if the
  // NativeCustomFormatAd has a video asset.
  if (mediaContent != null && mediaContent.hasVideoContent()) {
    val mediaView = MediaView(mediaPlaceholder.getContest())
    mediaView.mediaContent = mediaContent

    val videoController = mediaContent.videoController

    // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
    // VideoController will call methods on this object when events occur in the video
    // lifecycle.
    if (videoController != null) {
      videoController.videoLifecycleCallbacks =
        object : VideoController.VideoLifecycleCallbacks() {
          override fun onVideoEnd() {
            // Publishers should allow native ads to complete video playback before refreshing
            // or replacing them with another ad in the same UI location.
            super.onVideoEnd()
          }
        }
    }
  } else {
    val mainImage = ImageView(this)
    mainImage.adjustViewBounds = true
    mainImage.setImageDrawable(ad.getImage("MainImage")?.drawable)

    mainImage.setOnClickListener { ad.performClick("MainImage") }
    customTemplateBinding.simplecustomMediaPlaceholder.addView(mainImage)
  }
}

如要進一步瞭解如何自訂自訂原生廣告的影片體驗,請參閱 MediaContent

下載 Ad Manager 自訂顯示範例,查看原生影片廣告的實際應用範例。

自訂原生廣告格式點擊和曝光

使用自訂原生廣告格式時,您的應用程式會負責記錄曝光,並向 Google Mobile Ads SDK 回報點擊事件。

記錄曝光次數

如要記錄自訂格式廣告的曝光,請在對應的 NativeCustomFormatAd 上呼叫 recordImpression 方法:

myCustomFormatAd.recordImpression();

如果您的應用程式不小心針對同一廣告呼叫該方法兩次,SDK 會自動防止針對單一請求重複記錄重複曝光。

回報點擊次數

如要向 SDK 回報素材資源檢視畫面發生點擊事件,請對對應的 NativeCustomFormatAd 呼叫 performClick 方法,並傳入點選的資產名稱。舉例來說,如果您的自訂格式含有名為「MainImage」的素材資源,想回報與該資產對應的 ImageView 發生點擊,程式碼會如下所示:

myCustomFormatAd.performClick("MainImage");

請注意,您不需要針對每個與廣告相關的檢視畫面呼叫這個方法。如果您的應用程式有另一個名為「Caption」的欄位,而這些欄位可讓使用者點選或輕觸,則應用程式無須針對該資產的檢視畫面呼叫 performClick

回應自訂點擊動作

使用者點選自訂格式廣告時,SDK 會嘗試下列三種可能的回應,依序嘗試:

  1. AdLoader 叫用 OnCustomClickListener (如有提供)。
  2. 針對每則廣告的深層連結網址,嘗試找出內容解析器,並啟動第一個可解析的網址。
  3. 開啟瀏覽器,前往廣告的傳統到達網頁網址。

forCustomFormatAd 方法接受 OnCustomClickListener。如果您傳入事件監聽器物件,SDK 會改為叫用其 onCustomClick 方法,而不採取進一步動作。但是,如果將空值當做事件監聽器傳遞,SDK 就會改回採用廣告註冊的深層連結和/或到達網頁網址。

應用程式可透過自訂點擊事件監聽器,判斷回應點擊的最佳動作,包括更新 UI、啟動新活動,或僅記錄點擊。以下舉例單純記錄點擊發生的情況:

Java

AdLoader adLoader = new AdLoader.Builder(context, "/6499/example/native")
    .forCustomFormatAd("10063170",
      new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
        // Display the ad.
      },
      new NativeCustomFormatAd.OnCustomClickListener() {
          @Override
          public void onCustomClick(NativeCustomFormatAd ad, String assetName) {
            Log.i("MyApp", "A custom click just happened for " + assetName + "!");
          }
      }).build();

Kotlin

val adLoader = AdLoader.Builder(this, "/6499/example/native")
    .forCustomFormatAd("10063170",
        { ad ->
            // Display the ad.
        },
        { ad, assetName ->
                Log.i("MyApp", "A custom click just happened for $assetName!")
    }).build()

起初,自訂點擊事件監聽器看起來好像奇怪。畢竟,您的應用程式只是告知 SDK 發生了點擊,所以為何 SDK 要轉彎,並將該事件回報給應用程式?

這項資訊流程有幾個優點,但最重要的是讓 SDK 保有對點擊回應的控制權。這項功能可自動對為廣告素材設定的第三方追蹤網址進行連線偵測 (ping),並在背景處理其他工作,完全不需要任何其他程式碼。