自訂原生廣告格式

自訂原生廣告格式

除了系統定義的原生格式外,Ad Manager 發布商還可 不必自行定義原生廣告格式 資產。這就是所謂的自訂原生廣告 格式,並適用於 預訂廣告。這可讓發布商將任意結構化資料傳遞至應用程式。這類廣告會由 NativeCustomFormatAd 物件。

載入自訂原生廣告格式

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

建立 AdLoader

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

Java

AdLoader adLoader = new AdLoader.Builder(context, "/21775744923/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, "/21775744923/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 在使用者輕觸或點擊廣告時叫用。如要進一步瞭解這個事件監聽器,請參閱下方的「處理點擊和曝光」一節。

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

自訂原生廣告格式 ID

您可以在 Ad Manager 使用者介面中找到用於識別自訂原生廣告格式的格式 ID,位於「Delivery」下拉式選單中的「Native」專區:

每個自訂原生廣告格式 ID 會顯示在名稱旁邊。只要點選任一應用程式 名稱可開啟詳細資料畫面,顯示該格式 欄位:

您可以在這裡新增、編輯及移除個別欄位。請記下每個資產的名稱。名稱是用來取得 。

多媒體自訂原生廣告格式

自訂原生廣告格式與發布商系統定義的格式不同 有權自行定義素材資源清單 設定廣告因此,顯示通知的程序不同於系統定義 定義多個格式

  1. 因為 NativeCustomFormatAd 類別的用途是處理 您在 Ad Manager 中定義的自訂原生廣告格式不會命名 「getters」。而是提供 getTextgetImage 等方法,這些方法會將欄位名稱做為參數。
  2. 沒有像 NativeAdView 這樣的專用廣告檢視畫面類別可搭配 NativeCustomFormatAd 使用。您可以自由使用任何對使用者體驗有意義的版面配置。
  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.
    ...
}

顯示 AdChoices 圖示

遵循《數位服務法》(DSA) 規定,在歐洲經濟區 (EEA) 放送的預訂廣告必須包含 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)
    }
  }
  ...
}

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

建立自訂格式時,您可以選擇讓格式符合影片播放資格。

在實作中,您可以使用 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。

記錄曝光

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

myCustomFormatAd.recordImpression();

如果應用程式不小心對相同廣告呼叫方法兩次,SDK 會針對 就能自動避免系統為 請求。

回報點擊次數

如要向 SDK 回報素材資源檢視畫面獲得的點擊,請呼叫 對應的 NativeCustomFormatAd 上的 performClick 方法並傳入 獲得點擊的資產名稱。舉例來說,如果您的資產在 名為「MainImage」的自訂格式並想記錄一次廣告點擊 與該資產對應的 ImageView,程式碼會如下所示:

myCustomFormatAd.performClick("MainImage");

請注意,您不需要針對與每個相關聯的檢視畫面, 。如果同時有另一個名為「說明文字」的欄位確實要達到 而非使用者點選或輕觸後,您的應用程式就無須 呼叫 performClick 取得該資產的檢視畫面。

回應自訂點擊動作

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

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

forCustomFormatAd 方法接受 OnCustomClickListener。如果發生以下情況: 傳遞事件監聽器物件,SDK 改為叫用其 onCustomClick 方法 且不會採取進一步行動不過,如果您將空值做為事件監聽器傳遞,SDK 會改用廣告註冊的深層連結和/或目的地網址。

自訂點擊事件監聽器可讓應用程式決定應採取的最佳做法 例如更新使用者介面、啟動新活動,或是 其實只要記錄點擊以下是只記錄點擊事件的範例:

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 維持控制點擊的回應。這項服務可以 自動連線偵測 舉例來說,玩家可以繼續發揮創意,在背景處理其他工作,完全不必 額外的程式碼