علاوهبر قالبهای بومی تعریفشده توسط سیستم، ناشران Ad Manager این گزینه را دارند که با تعریف فهرستهای سفارشی داراییها، قالبهای آگهی بومی خودشان را ایجاد کنند. به اینها قالبهای آگهی بومی سفارشی گفته میشود و میتوان از آنها با آگهیهای رزروشده استفاده کرد. این کار به ناشران امکان میدهد دادههای ساختاریافته دلخواه را به
برنامههایشان منتقل کنند. این آگهیها با شیء
NativeCustomFormatAd
نشان داده میشوند.
بار کردن قالبهای آگهی بومی سفارشی
این راهنما نحوه بار کردن و نمایش دادن قالبهای آگهی بومی سفارشی را توضیح میدهد.
بار کردن آگهی بومی سفارشی
مانند آگهیهای بومی،
قالبهای آگهی بومی سفارشی بااستفاده از کلاس AdLoader بارگیری میشوند:
جاوا
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 را برای درخواست قالبهای آگهی بومی سفارشی پیکربندی میکند. میتوانید این روش را چندین بار برای شناسههای قالب سفارشی مختلف فراخوانی کنید. این روش پارامترهای زیر را میپذیرد:
- شناسه قالب آگهی بومی سفارشی که
AdLoaderباید درخواست کند. هر قالب آگهی بومی سفارشی دارای یک شناسه مرتبط با آن است. این پارامتر نشان میدهد که برنامه شما میخواهدAdLoaderکدام قالب را درخواست کند. - یک
OnCustomFormatAdLoadedListenerکه وقتی آگهی باموفقیت بار شد، فراخوانی میشود. OnCustomClickListenerاختیاری که وقتی کاربر روی آگهی تکضرب میزند یا کلیک میکند فراخوانده میشود. برای اطلاعات بیشتر درباره این شنونده، به بخش «رسیدگی به کلیکها و ظهورها» مراجعه کنید.
چون یک واحد آگهی میتواند برای ارائه بیشاز یک قالب طرح آگهی راهاندازی شود، forCustomFormatAd میتواند چندین بار با شناسههای قالب غیرتکراری فراخوانده شود تا بارکننده آگهی را برای بیشاز یک قالب آگهی بومی سفارشی ممکن آماده کند.
شناسه قالب آگهی بومی سفارشی
شناسه قالبی که برای شناسایی قالب آگهی بومی سفارشی استفاده میشود را میتوانید در واسط کاربری Ad Manager در بخش بومی در منو کرکرهای تحویل پیدا کنید:

هر شناسه قالب آگهی بومی سفارشی در کنار نام آن نشان داده میشود. با کلیک کردن روی یکی از نامها، به صفحه جزئیات میروید که اطلاعاتی درباره فیلدهای قالب نشان میدهد:

از اینجا میتوانید فیلدهای تکی را اضافه، ویرایش، و حذف کنید. نام هریک از داراییها را یادداشت کنید. نام کلیدی است که برای دریافت دادههای هر دارایی هنگام نمایش قالب آگهی بومی سفارشی شما استفاده میشود.
نمایش قالبهای آگهی بومی سفارشی
قالبهای آگهی بومی سفارشی با قالبهای تعریفشده توسط سیستم تفاوت دارند زیرا ناشران میتوانند فهرست داراییهای خود را که آگهی را تشکیل میدهند تعریف کنند. بنابراین، فرایند نمایش آن از چند جهت با قالبهای تعریفشده توسط سیستم متفاوت است:
- داراییهای نوشتاری و تصویری ازطریق گیرندههای
getText()وgetImage()که نام فیلد را بهعنوان پارامتر میگیرند دردسترس هستند. - چون کلاس
ViewGroupاختصاصی برای ثبتنام با Google وجود ندارد، باید ظهورها و کلیکها را بهصورت دستی ثبت کنید. - اگر آگهی دارایی ویدیویی نداشته باشد، آگهی بومی سفارشی دارای محتوای رسانهای
nullاست.
در اینجا تابع نمونهای آورده شده است که NativeCustomFormatAd را نمایش میدهد:
جاوا
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 است، برنامههای جایگزینی برای نمایش آگهی بدون ویدیو ایجاد کنید.
مثال زیر بررسی میکند که آیا آگهی محتوای ویدیویی دارد یا نه، و اگر ویدیو دردسترس نباشد، تصویری را بهجای آن نمایش میدهد:
جاوا
// 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 Custom Rendering را بارگیری کنید تا نمونهای از ویدیو بومی درحال اجرا را ببینید.
برای اطلاعات بیشتر درباره نحوه سفارشیسازی تجربه ویدیو آگهی بومی سفارشی، آگهیهای ویدیویی را ببینید.
پرداز زدن نماد 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 را ارائه میدهد و رفتار کلیک مناسب را پیکربندی میکند.
جاوا
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 (Legacy) است.
ظهورهای ضبط
برای ثبت ظهور برای آگهی بومی سفارشی، روش
recordImpression() آگهی را فراخوانی کنید:
myCustomFormatAd.recordImpression();
اگر برنامه شما بهطور تصادفی این روش را دو بار برای یک آگهی فراخوانی کند، کیت توسعه نرمافزار بهطور خودکار از ثبت ظهور تکراری برای یک درخواست جلوگیری میکند.
کلیکهای گزارش تخلف
برای گزارش به کیت توسعه نرمافزار مبنی بر اینکه کلیکی روی نمای دارایی رخ داده است،
روش performClick() آگهی را فراخوانی کنید. نام داراییای را که روی آن کلیک شده است
بااستفاده از همان رشتهای که در واسط کاربر Ad Manager تعریف کردهاید ارائه دهید.
myCustomFormatAd.performClick("MainImage");
توجه داشته باشید که لازم نیست این روش را برای هر نمای مرتبط با آگهیتان فراخوانی کنید. اگر فیلد دیگری بهنام «زیرنویس» داشتید که قرار بود نمایش داده شود اما کاربر روی آن کلیک یا تکضرب نمیزد، برنامهتان نیازی نداشت برای نمای آن دارایی performClick را فراخوانی کند.
پاسخ دادن به کنشهای کلیک سفارشی
وقتی روی آگهی با قالب سفارشی کلیک میشود، سه پاسخ احتمالی از کیت توسعه نرمافزار وجود دارد که بهترتیب زیر امتحان میشوند:
- اگر
OnCustomClickListenerارائه شده است، آن را فراخوانی کنید. - برای هریک از نشانیهای وب پیوند عمیق آگهی، سعی کنید یک حلکننده محتوا پیدا کنید و اولین موردی را که حل میشود شروع کنید.
- مرورگری را باز کنید و به نشانی وب مقصد آگهی بروید.
برای پیادهسازی کنش کلیک سفارشی، OnCustomClickListener را ارائه دهید:
جاوا
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()
در ابتدا، ممکن است وجود شنوندگان کلیک سفارشی عجیب بهنظر برسد. بههرحال، برنامه شما بهتازگی به کیت توسعه نرمافزار گفته است که کلیکی اتفاق افتاده است، پس چرا کیت توسعه نرمافزار باید برگردد و آن را به برنامه گزارش دهد؟
این جریان اطلاعات به چند دلیل مفید است، اما مهمترین دلیل این است که به کیت توسعه نرمافزار اجازه میدهد کنترل پاسخ به کلیک را حفظ کند. برای مثال، میتواند بهطور خودکار به نشانیهای وب ردگیری طرف سوم که برای طرح آگهی تنظیم شدهاند پینگ کند و کارهای دیگر را بدون هیچ کد اضافی در پشت صحنه انجام دهد.