自訂原生廣告格式
除了系統定義的原生格式外,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 UI 中,「廣告放送」部分的「原生」部分下方) 下拉式選單:
每個自訂原生廣告格式 ID 會顯示在名稱旁邊。只要點選任一應用程式 名稱可開啟詳細資料畫面,顯示該格式 欄位:
您可以在這裡新增、編輯及移除個別欄位。請注意, 各項資產的名稱。名稱是用來取得 。
多媒體自訂原生廣告格式
自訂原生廣告格式與發布商系統定義的格式不同 有權自行定義素材資源清單 設定廣告因此,顯示通知的程序不同於系統定義 以多種格式
- 因為
NativeCustomFormatAd
類別的用途是處理 您在 Ad Manager 中定義的自訂原生廣告格式不會命名 「getters」。而是提供getText
和 使用欄位名稱做為參數的getImage
。 - 目前沒有專用廣告檢視類別 (例如
NativeAdView
) 可用於NativeCustomFormatAd
。您可以自由運用任何 才能提供良好的使用者體驗 - 由於沒有專屬的
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
取得該資產的檢視畫面。
回應自訂點擊動作
點擊自訂格式廣告時,有三種可能性 這些回應會按照以下順序嘗試:
- 從
AdLoader
叫用OnCustomClickListener
(如有提供)。 - 針對每個廣告的深層連結網址,嘗試找出內容解析器 並啟動第一個解決問題的方法
- 開啟瀏覽器,瀏覽至廣告傳統的到達網頁網址。
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 維持控制點擊的回應。這項服務可以 自動連線偵測 舉例來說,使用者可以盡情發揮創意,在背景處理其他工作,完全不必 額外的程式碼