自訂原生廣告格式

選取平台: Android iOS

除了系統定義的原生格式,Ad Manager 發布商也可以定義自訂素材資源清單,建立自己的原生廣告格式。這類廣告稱為自訂原生廣告格式,可與預訂廣告一起使用。發布商可透過這項功能,將任意結構化資料傳遞至應用程式。這些廣告會以 NativeCustomFormatAd 物件表示。

載入自訂原生廣告格式

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

載入自訂原生廣告

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

Java

AdLoader adLoader = new AdLoader.Builder(this, "/21775744923/example/native")
    .forCustomFormatAd("12387226",
        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
          }
        })
    .forCustomFormatAd("12406343",
        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
          }
        })
    .build();

Kotlin

val adLoader = AdLoader.Builder(this, "/21775744923/example/native")
  .forCustomFormatAd(
    "12387226",
    { customFormatAd ->
      // Show the custom format and record an impression.
    },
    { customFormatAd, s ->
      // Handle the click action
    })
  .forCustomFormatAd(
    "12406343",
    { customFormatAd ->
      // Show the custom format and record an impression.
    },
    { customFormatAd, s ->
      // Handle the click action
    })
  .build()

forCustomFormatAd 方法會設定 AdLoader,要求自訂原生廣告格式。您可以針對不同自訂格式 ID 多次呼叫這個方法。這個方法接受下列參數:

  • AdLoader 應要求的自訂原生廣告格式 ID。每個自訂原生廣告格式都有相關聯的 ID,這項參數表示應用程式希望 AdLoader 要求的格式。
  • 廣告載入成功時叫用的 OnCustomFormatAdLoadedListener
  • 使用者輕觸或點按廣告時要叫用的選用 OnCustomClickListener。如要進一步瞭解這個接聽程式,請參閱「處理點擊和曝光」一節。

因為單一廣告單元可設定為放送多種廣告素材格式,所以可使用不同格式 ID,多次呼叫 forCustomFormatAd 準備廣告載入器,因應多種可能的自訂原生廣告格式。

自訂原生廣告格式 ID

如要找出用於識別自訂原生廣告格式的格式 ID,請前往 Ad Manager 使用者介面,在「放送」下拉式選單的「原生」部分中查看:

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

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

放送自訂原生廣告格式

自訂原生廣告格式與系統定義的格式不同,發布商可自行定義廣告素材資源清單。因此,顯示自訂格式的程序與系統定義格式有幾項差異:

  1. 文字和圖片素材資源可透過 getText()getImage() 取得,這些 getter 會將欄位名稱做為參數。
  2. 由於沒有專屬的 ViewGroup 類別可向 Google 註冊,因此您需要手動記錄曝光和點擊次數。
  3. 如果廣告不含影片素材資源,自訂原生廣告會顯示null媒體內容。

以下範例函式會顯示 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(),在媒體檢視區塊中設定媒體內容。如果廣告有null媒體內容,請另行規劃,在沒有影片的情況下顯示廣告。

以下範例會檢查廣告是否含有影片內容,如果沒有,則會改為顯示圖片:

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

下載 Ad Manager 自訂顯示範例,瞭解原生影片的實際運作方式。

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

顯示 AdChoices 圖示

支援《數位服務法》(DSA),在歐洲經濟區放送的預訂廣告必須包含 AdChoices 圖示和Google 的「關於這則廣告」頁面連結。導入自訂原生廣告時,您必須顯示 AdChoices 圖示。顯示主要廣告素材資源時,建議您採取步驟來顯示及設定 AdChoices 圖示的點擊事件監聽器。

以下範例假設您已在檢視區塊階層中定義 <ImageView /> 元素,用於保存 AdChoices 標誌。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/adChoices"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:adjustViewBounds="true"
        android:contentDescription="AdChoices icon." />
</LinearLayout>

下列範例會算繪 AdChoices 圖示,並設定適當的點擊行為。

Java

private AdSimpleCustomTemplateBinding customTemplateBinding;

private void populateAdView(final NativeCustomFormatAd nativeCustomFormatAd) {
  // Render the AdChoices icon.
  String adChoicesKey = NativeAdAssetNames.ASSET_ADCHOICES_CONTAINER_VIEW;
  NativeAd.Image adChoicesAsset = nativeCustomFormatAd.getImage(adChoicesKey);
  if (adChoicesAsset == null) {
    customTemplateBinding.adChoices.setVisibility(View.GONE);
  } else {
    customTemplateBinding.adChoices.setVisibility(View.VISIBLE);
    customTemplateBinding.adChoices.setImageDrawable(adChoicesAsset.getDrawable());

    // Enable clicks on AdChoices.
    customTemplateBinding.adChoices.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            nativeCustomFormatAd.performClick(adChoicesKey);
          }
        });
  }
  ...
}

Kotlin

private lateinit var customTemplateBinding: AdSimpleCustomTemplateBinding

private fun populateAdView(nativeCustomFormatAd: NativeCustomFormatAd) {
  // Render the AdChoices icon.
  val adChoicesKey = NativeAdAssetNames.ASSET_ADCHOICES_CONTAINER_VIEW
  val adChoicesAsset = nativeCustomFormatAd.getImage(adChoicesKey)
  if (adChoicesAsset == null) {
    customTemplateBinding.adChoices.visibility = View.GONE
  } else {
    customTemplateBinding.adChoices.setImageDrawable(adChoicesAsset.drawable)
    customTemplateBinding.adChoices.visibility = View.VISIBLE

    // Enable clicks on AdChoices.
    customTemplateBinding.adChoices.setOnClickListener {
      nativeCustomFormatAd.performClick(adChoicesKey)
    }
  }
  ...
}

記錄曝光次數及回報點擊次數

您的應用程式必須負責記錄曝光次數,並向 Google Mobile Ads SDK 回報點擊事件。

記錄曝光次數

如要記錄自訂原生廣告的曝光次數,請呼叫廣告的 recordImpression() 方法:

myCustomFormatAd.recordImpression();

如果應用程式不慎對同一則廣告呼叫這個方法兩次,SDK 會自動防止為單一請求記錄重複曝光。

回報點擊

如要向 SDK 回報素材資源檢視畫面有點擊事件,請呼叫廣告的 performClick() 方法。使用您在 Ad Manager 使用者介面中定義的相同字串,提供遭點擊的素材資源名稱。

myCustomFormatAd.performClick("MainImage");

請注意,您不需要為與廣告相關聯的每個檢視區塊呼叫這個方法。如果您有另一個名為「說明」的欄位,該欄位應顯示但使用者不會點選或輕觸,則應用程式不需要為該資產的檢視畫面呼叫 performClick

回應自訂點擊動作

如果自訂格式廣告發生點擊,SDK 可能會依下列順序嘗試回應:

  1. 如果提供 OnCustomClickListener,請叫用該函式。
  2. 針對廣告的每個深層連結網址,嘗試找出內容解析器,然後啟動實際執行解析的第一個解析器。
  3. 開啟瀏覽器,前往廣告的到達網頁網址。

如要實作自訂點擊動作,請提供 OnCustomClickListener

Java

AdLoader adLoader = new AdLoader.Builder(context, "/21775744923/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, "/21775744923/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 作業,並在幕後處理其他工作,完全不需要額外程式碼。