פורמטים מותאמים אישית של מודעות מותאמות

הפלטפורמה: 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 לבקשת פורמטים מותאמים אישית של מודעות מותאמות. אפשר להפעיל את השיטה כמה פעמים כדי לקבל מזהים של פורמטים מותאמים אישית שונים. השיטה מקבלת את הפרמטרים הבאים:

  • המזהה של פורמט המודעה המותאם אישית לנייטיב שהתג AdLoader צריך לבקש. לכל פורמט מותאם אישית של מודעה מותאמת יש מזהה משלו. הפרמטר הזה מציין את הפורמט שהאפליקציה רוצה לבקש מ-AdLoader.
  • OnCustomFormatAdLoadedListener שיופעל כשהמודעה תיטען בהצלחה.
  • פונקציה אופציונלית OnCustomClickListener שמופעלת כשהמשתמש מקיש על המודעה או לוחץ עליה. מידע נוסף על מאזין כזה זמין בקטע 'טיפול בקליקים ובחשיפות'.

אפשר להגדיר יחידת מודעות אחת כך שתציג יותר מפורמט קריאייטיב אחד, ולכן אפשר לקרוא ל-forCustomFormatAd כמה פעמים עם מזהי פורמט ייחודיים כדי להכין את הכלי לטעינת מודעות ליותר מפורמט אחד אפשרי של מודעה מותאמת אישית.

מזהה של פורמט מותאם אישית של מודעה מותאמת

אפשר למצוא את מזהה הפורמט שמשמש לזיהוי פורמט מותאם אישית של מודעה מותאמת בממשק המשתמש של Ad Manager בקטע Native בתפריט הנפתח Delivery:

מזהה כל פורמט מותאם של מודעה מותאמת מופיע לצד השם שלו. לחיצה על אחד השמות תעביר אתכם למסך פרטים שבו מוצג מידע על השדות בפורמט:

מכאן אפשר להוסיף, לערוך ולהסיר שדות ספציפיים. רושמים את השם של כל אחד מהנכסים. השם הוא המפתח שמשמש לאחזור הנתונים של כל נכס כשמציגים את פורמט המודעה המותאם אישית שלכם.

הצגת פורמטים מותאמים אישית של מודעות מותאמות

פורמטים מותאמים אישית של מודעות מותאמות שונים מפורמטים שמוגדרים על ידי המערכת בכך שלבעלי האתרים יש אפשרות להגדיר רשימה משלהם של נכסים שמרכיבים מודעה. לכן, התהליך להצגת פורמט אחד שונה מהפורמטים שמוגדרים על ידי המערכת בכמה דרכים:

  1. נכסי תמונות וטקסט זמינים באמצעות getText() ו-getImage()getters שמקבלים את שם השדה כפרמטר.
  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 Custom Rendering ‎.

מידע נוסף על התאמה אישית של חוויית הצפייה בסרטון במודעה מותאמת אישית מוצג במאמר מודעות וידאו.

הצגת סמל AdChoices

במסגרת התמיכה ב-Digital Services Act (חוק השירותים הדיגיטליים, 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)
    }
  }
  ...
}

תיעוד חשיפות ודיווח על קליקים

האפליקציה שלכם אחראית לתיעוד החשיפות ולדיווח על אירועי קליקים אל Google Mobile Ads SDK.

תיעוד חשיפות

כדי לתעד חשיפה של מודעה מותאמת אישית, קוראים לשיטה recordImpression() של המודעה:

myCustomFormatAd.recordImpression();

אם האפליקציה קוראת בטעות למתודה פעמיים עבור אותה מודעה, ה-SDK מונע אוטומטית רישום של צפייה כפולה עבור בקשה יחידה.

קליקים על פוסט

כדי לדווח ל-SDK על לחיצה על תצוגת נכס, קוראים לשיטה performClick() של המודעה. מציינים את שם הנכס שהמשתמש לחץ עליו באמצעות אותה מחרוזת שהגדרתם בממשק המשתמש של Ad Manager.

myCustomFormatAd.performClick("MainImage");

שימו לב שלא צריך להפעיל את השיטה הזו לכל צפייה שמשויכת למודעה שלכם. לדוגמה, אם יש לכם שדה אחר בשם Caption (כיתוב) שנועד להצגה אבל לא לקליק או להקשה של המשתמש, לא תצטרכו להפעיל את performClick כדי להציג את הנכס הזה באפליקציה.

תגובה לפעולות מותאמות אישית של קליקים

כשמשתמש לוחץ על מודעה בפורמט מותאם אישית, יכולות להיות שלוש תגובות אפשריות מ-SDK, והן מוצגות לפי הסדר הזה:

  1. מפעילים את OnCustomClickListener אם צוין.
  2. לכל אחת מכתובות ה-URL של קישורי העומק של המודעה, המערכת מנסה לאתר פותר תוכן ולהפעיל את הראשון שפותר.
  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 לשלוט בתגובה לקליק. לדוגמה, הוא יכול לשלוח פינג אוטומטי לכתובות אתר למעקב של צד שלישי שהוגדרו עבור הקריאייטיב, ולבצע משימות אחרות ברקע, ללא צורך בקוד נוסף.