أشكال الإعلانات المدمجة مع المحتوى المخصّصة
بالإضافة إلى أشكال الإعلانات المدمجة مع المحتوى التي يحدّدها النظام، يتوفّر لصنّاع المحتوى في "مدير إعلانات Google"
خيار إنشاء أشكال إعلانات مدمجة مع المحتوى من خلال تحديد قوائم مخصّصة
للمواد. وتُعرف هذه الإعلانات باسم أشكال الإعلانات المدمجة مع المحتوى المخصّصة، ويمكن استخدامها مع
الإعلانات المحجوزة. ويسمح هذا للناشرين بإتاحة بيانات منظَّمة عشوائية
لتطبيقاتهم. يتم تمثيل هذه الإعلانات بكائن
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
. لكل شكل إعلان مُدمَج مع المحتوى مخصّص معرّف مرتبط به. تشير هذه المَعلمة إلى الشكل الذي يريد تطبيقك منAdLoader
طلبه. OnCustomFormatAdLoadedListener
للاطّلاع على القيمة التي سيتمّ استدعاؤها عند تحميل إعلان بنجاح.OnCustomClickListener
اختياري لتشغيله عندما ينقر المستخدم على الإعلان لمزيد من المعلومات عن هذا المستمع، اطّلِع على قسم "معالجة النقرات ومرّات الظهور" أدناه.
بما أنّه يمكن إعداد وحدة إعلانية واحدة لعرض أكثر من شكل واحد لتصميم الإعلان، يمكن استدعاء forCustomFormatAd
عدة مرات باستخدام أرقام تعريف تشكل فريدة من أجل إعداد أداة تحميل الإعلانات لأكثر من شكل واحد ممكن
لإعلان مضمّن معيّن.
رقم تعريف شكل الإعلان المدمج مع المحتوى المخصّص
يمكن العثور على رقم تعريف التنسيق المستخدَم لتحديد شكل إعلان مخصّص مدمج مع المحتوى في واجهة مستخدِم "مدير إعلانات Google" ضمن قسم الإعلانات المدمجة مع المحتوى في القائمة المنسدلة العرض:
يظهر رقم تعريف كل شكل إعلان مخصّص مدمج مع المحتوى بجانب اسمه. يؤدي النقر على أحد الأسماء إلى نقلك إلى شاشة تفاصيل تعرض معلومات عن ملف التنسيق الحاوي على الاسم:
من هنا، يمكن إضافة حقول فردية وتعديلها وإزالتها. دوِّن الاسم لكل مادة عرض. الاسم هو المفتاح المستخدَم للحصول على بيانات كل مادة عرض عند عرض تنسيق الإعلان المُدمج مع المحتوى المخصّص.
عرض أشكال الإعلانات المدمجة مع المحتوى المخصّصة
تختلف أشكال الإعلانات المدمجة مع المحتوى المخصّصة عن تلك التي يحدّدها النظام، إذ يمكن للناشرين تحديد قائمة مواد العرض التي تشكّل الإعلان. لذلك، تختلف عملية عرض أحدها عن التنسيقات التي يحدّدها النظام بعدة طرق:
- بما أنّ فئة
NativeCustomFormatAd
مخصّصة للتعامل مع أيّ من أشكال الإعلانات المُدمَجة مع المحتوى المخصّصة التي تحدّدها في "مدير إعلانات Google"، فهي لا تتضمّن "أدوات جلب" مُسمّاة لمواد العرض. بدلاً من ذلك، يوفّر طرقًا مثل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. ... }
عرض رمز "خيارات الإعلان"
كجزء من الامتثال لقانون الخدمات الرقمية (DSA)، يجب أن تتضمّن الإعلانات المحجوزة المعروضة في المنطقة الاقتصادية الأوروبية (EEA) رمز خيارات الإعلان ورابطًا إلى صفحة "تفاصيل عن الإعلان" من 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>
تعرِض الأمثلة التالية رمز "خيارات الإعلان" و تضبط سلوك النقرات المناسب.
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 للحصول على مزيد من المعلومات حول كيفية تخصيص تجربة إعلان مُدمَج مع المحتوى مخصّص.
نزِّل مثال المعالجة المخصّصة في "مدير إعلانات Google" للحصول على مثال عملي على إعلان الفيديو المدمج مع المحتوى.
النقرات ومرّات الظهور لأشكال الإعلانات المدمجة مع المحتوى المخصّصة
باستخدام أشكال الإعلانات المدمجة مع المحتوى المخصّصة، يتحمّل تطبيقك مسؤولية تسجيل مرّات الظهور والإبلاغ عن أحداث النقرات إلى حزمة SDK لإعلانات Google على الأجهزة الجوّالة.
تسجيل مرّات الظهور
لتسجيل مرّة ظهور لإعلان بتنسيق مخصّص، استخدِم recordImpression
الطريقة على NativeCustomFormatAd
المقابل:
myCustomFormatAd.recordImpression();
إذا استدعى تطبيقك الطريقة مرتين للإعلان نفسه عن طريق الخطأ، سيمنع حِزم تطوير البرامج (SDK) تلقائيًا تسجيل مرّة ظهور مكرّرة لطلب واحد.
الإبلاغ عن النقرات
للإبلاغ إلى حِزم تطوير البرامج (SDK) عن حدوث نقرة على عرض مادة عرض، يمكنك استدعاء performClick
على NativeCustomFormatAd
المعنيّ وإدخال اسم مادة العرض التي تم النقر عليها. على سبيل المثال، إذا كانت لديك مادة عرض في
التنسيق المخصّص الذي تُستخدِمه باسم "MainImage" وأردت الإبلاغ عن نقرة على
ImageView
تتوافق مع مادة العرض هذه، سيبدو الرمز البرمجي على النحو التالي:
myCustomFormatAd.performClick("MainImage");
يُرجى العِلم أنّه ليس عليك استدعاء هذه الطريقة لكلّ مشاهدة مرتبطة
بإعلانك. إذا كان لديك حقل آخر يُسمى "الترجمة والشرح" كان من المفترض أن يتم
عرضه ولكن لم ينقر عليه المستخدم، لن يحتاج تطبيقك إلى
استدعاء performClick
لعرض مادة العرض هذه.
الردّ على إجراءات النقر المخصّصة
عند النقر على إعلان بتنسيق مخصّص، هناك ثلاثة possible ردود من حزمة تطوير البرامج (SDK)، ويتمّ المحاولة بالترتيب التالي:
- استدعاء
OnCustomClickListener
منAdLoader
، إذا تم توفيره - بالنسبة إلى كل عنوان من عناوين URL لرابط الربط بصفحة معيّنة في الإعلان، حاوِل تحديد موقع أداة حلّ عناوين URL للمحتوى وشغِّل أول أداة يتم العثور عليها.
- افتح متصفحًا وانتقِل إلى عنوان URL التقليدي للوجهة في الإعلان.
تقبل طريقة forCustomFormatAd
OnCustomClickListener
. في حال
تمرير عنصر مستمع، ستستدعي حزمة تطوير البرامج (SDK) onCustomClick
بدلاً من ذلك
ولن تتّخذ أي إجراء آخر. في حال تمّ ضبط قيمة فارغة كمُستمع،
ستستخدم حزمة تطوير البرامج (SDK) عنوان URL لرابط الانتقال إلى صفحة معيّنة و/أو عناوين URL للوجهة المسجّلة في
الإعلان.
تسمح أدوات الاستماع المخصّصة إلى النقرات لتطبيقك بتحديد أفضل إجراء اتّخاذه استجابةً للنقرة، سواء كان ذلك من خلال تعديل واجهة المستخدم أو بدء نشاط جديد أو تسجيل النقرة فقط. في ما يلي مثال يسجّل ببساطة حدوث نقرة:
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 بمواصلة التحكّم في الاستجابة للنقرة. يمكنه مثلاً إرسال إشعارات تلقائية إلى عناوين URL لتتبُّع الجهات الخارجية التي تم إعدادها لمواد حملة إعلانية معيّنة، وتنفيذ مهام أخرى في الخلفية بدون أي رمز إضافي.