אירועים בהתאמה אישית של מודעות מותאמות

דרישות מוקדמות

משלימים את הגדרת האירועים המותאמים אישית.

שליחת בקשה להצגת מודעה מותאמת

כשמגיעים לפריט של אירוע מותאם אישית בשרשרת של רשימת הרשתות בתהליך בחירת הרשת, מתבצעת קריאה לשיטה loadNativeAd() בשם המחלקה שציינתם כשיצרתם אירוע מותאם אישית. במקרה הזה, ה-method נמצא ב-SampleCustomEvent, שקורא ל-method‏ loadNativeAd() ב-SampleNativeCustomEventLoader.

כדי לבקש מודעה מותאמת, צריך ליצור או לשנות מחלקה שמרחיבה את Adapter כדי להטמיע את loadNativeAd(). אם כבר קיימת כיתה שמרחיבה את Adapter, צריך להטמיע את loadNativeAd() שם. בנוסף, צריך ליצור כיתה חדשה כדי להטמיע את UnifiedNativeAdMapper.

בדוגמה לאירוע מותאם אישית, המחלקה SampleCustomEvent מרחיבה את המחלקה Adapter ואז מעבירה את ההרשאה אל SampleNativeCustomEventLoader.

Java

package com.google.ads.mediation.sample.customevent;

import com.google.android.gms.ads.mediation.Adapter;
import com.google.android.gms.ads.mediation.MediationAdConfiguration;
import com.google.android.gms.ads.mediation.MediationAdLoadCallback;

import com.google.android.gms.ads.mediation.MediationNativeAdCallback;
...
public class SampleCustomEvent extends Adapter {
  private SampleNativeCustomEventLoader nativeLoader;

  @Override
  public void loadNativeAd(
      @NonNull MediationNativeAdConfiguration adConfiguration,
      @NonNull MediationAdLoadCallback<UnifiedNativeAdMapper, MediationNativeAdCallback> callback) {
    nativeLoader = new SampleNativeCustomEventLoader(adConfiguration, callback);
    nativeLoader.loadAd();
  }
}

SampleNativeCustomEventLoader אחראי למשימות הבאות:

  • טעינה של המודעה המותאמת.

  • הטמעה של המחלקה UnifiedNativeAdMapper.

  • קבלת נתוני אירועים שקשורים למודעות ודיווח עליהם אל Google Mobile Ads SDK.

הפרמטר האופציונלי שמוגדר בממשק המשתמש של AdMob נכלל בהגדרת המודעה. אפשר לגשת לפרמטר באמצעות adConfiguration.getServerParameters().getString(MediationConfiguration.CUSTOM_EVENT_SERVER_PARAMETER_FIELD). הפרמטר הזה הוא בדרך כלל מזהה של יחידת מודעות שנדרש על ידי SDK של רשת מודעות כשיוצרים מופע של אובייקט מודעה.

Java

package com.google.ads.mediation.sample.customevent;

import com.google.android.gms.ads.mediation.Adapter;
import com.google.android.gms.ads.mediation.MediationNativeAdConfiguration;
import com.google.android.gms.ads.mediation.MediationAdLoadCallback;
import com.google.android.gms.ads.mediation.MediationNativeAdCallback;
...

public class SampleNativeCustomEventLoader extends SampleNativeAdListener {
  /** Configuration for requesting the native ad from the third-party network. */
  private final MediationNativeAdConfiguration mediationNativeAdConfiguration;

  /** Callback that fires on loading success or failure. */
  private final MediationAdLoadCallback<UnifiedNativeAdMapper, MediationNativeAdCallback>
      mediationAdLoadCallback;

  /** Callback for native ad events. */
  private MediationNativeAdCallback nativeAdCallback;

  /** Constructor */
  public SampleNativeCustomEventLoader(
      @NonNull MediationNativeAdConfiguration mediationNativeAdConfiguration,
      @NonNull MediationAdLoadCallback<MediationNativeAd, MediationNativeAdCallback>
              mediationAdLoadCallback) {
    this.mediationNativeAdConfiguration = mediationNativeAdConfiguration;
    this.mediationAdLoadCallback = mediationAdLoadCallback;
  }

  /** Loads the native ad from the third-party ad network. */
  public void loadAd() {
    // Create one of the Sample SDK's ad loaders to request ads.
    Log.i("NativeCustomEvent", "Begin loading native ad.");
    SampleNativeAdLoader loader =
        new SampleNativeAdLoader(mediationNativeAdConfiguration.getContext());

    // All custom events have a server parameter named "parameter" that returns
    // back the parameter entered into the UI when defining the custom event.
    String serverParameter = mediationNativeAdConfiguration
        .getServerParameters()
        .getString(MediationConfiguration
        .CUSTOM_EVENT_SERVER_PARAMETER_FIELD);
    Log.d("NativeCustomEvent", "Received server parameter.");

    loader.setAdUnit(serverParameter);

    // Create a native request to give to the SampleNativeAdLoader.
    SampleNativeAdRequest request = new SampleNativeAdRequest();
    NativeAdOptions options = mediationNativeAdConfiguration.getNativeAdOptions();
    if (options != null) {
      // If the NativeAdOptions' shouldReturnUrlsForImageAssets is true, the adapter should
      // send just the URLs for the images.
      request.setShouldDownloadImages(!options.shouldReturnUrlsForImageAssets());

      request.setShouldDownloadMultipleImages(options.shouldRequestMultipleImages());
      switch (options.getMediaAspectRatio()) {
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_LANDSCAPE:
          request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_LANDSCAPE);
          break;
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_PORTRAIT:
          request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_PORTRAIT);
          break;
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_SQUARE:
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_ANY:
        case NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_UNKNOWN:
        default:
          request.setPreferredImageOrientation(SampleNativeAdRequest.IMAGE_ORIENTATION_ANY);
      }
    }

    loader.setNativeAdListener(this);

    // Begin a request.
    Log.i("NativeCustomEvent", "Start fetching native ad.");
    loader.fetchAd(request);
  }
}

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

בדרך כלל, השיטות האלה מוטמעות בתוך קריאות חוזרות (callbacks) מ-SDK של צד שלישי שהמתאם מטמיע. בדוגמה הזו, ל-Sample SDK יש SampleAdListener עם קריאות חוזרות רלוונטיות:

Java

@Override
public void onNativeAdFetched(SampleNativeAd ad) {
  SampleUnifiedNativeAdMapper mapper = new SampleUnifiedNativeAdMapper(ad);
  mediationNativeAdCallback = mediationAdLoadCallback.onSuccess(mapper);
}

@Override
public void onAdFetchFailed(SampleErrorCode errorCode) {
  mediationAdLoadCallback.onFailure(SampleCustomEventError.createSampleSdkError(errorCode));
}

מודעות מותאמות במפות

לערכות SDK שונות יש פורמטים ייחודיים משלהן למודעות מותאמות. לדוגמה, יכול להיות שפונקציה אחת תחזיר אובייקטים שמכילים שדה בשם title, ואילו פונקציה אחרת תחזיר אובייקטים עם שדה בשם headline. בנוסף, השיטות שמשמשות למעקב אחר חשיפות ולעיבוד קליקים יכולות להיות שונות מ-SDK אחד לאחר.

ה-UnifiedNativeAdMapper אחראי לגשר על הפערים האלה ולהתאים את אובייקט המודעה המותאמת של SDK בתהליך בחירת הרשת כך שיתאים לממשק שנדרש על ידי Google Mobile Ads SDK. אירועים מותאמים אישית צריכים להרחיב את המחלקה הזו כדי ליצור ממפים משלהם שספציפיים ל-SDK של הגישור. הנה דוגמה למיפוי מודעות מתוך פרויקט הדוגמה שלנו של אירועים בהתאמה אישית:

Java

package com.google.ads.mediation.sample.customevent;

import com.google.android.gms.ads.mediation.UnifiedNativeAdMapper;
import com.google.android.gms.ads.nativead.NativeAd;
...

public class SampleUnifiedNativeAdMapper extends UnifiedNativeAdMapper {

  private final SampleNativeAd sampleAd;

  public SampleUnifiedNativeAdMapper(SampleNativeAd ad) {
    sampleAd = ad;
    setHeadline(sampleAd.getHeadline());
    setBody(sampleAd.getBody());
    setCallToAction(sampleAd.getCallToAction());
    setStarRating(sampleAd.getStarRating());
    setStore(sampleAd.getStoreName());
    setIcon(
        new SampleNativeMappedImage(
            ad.getIcon(), ad.getIconUri(), SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));
    setAdvertiser(ad.getAdvertiser());

    List<NativeAd.Image> imagesList = new ArrayList<NativeAd.Image>();
    imagesList.add(new SampleNativeMappedImage(ad.getImage(), ad.getImageUri(),
        SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));
    setImages(imagesList);

    if (sampleAd.getPrice() != null) {
      NumberFormat formatter = NumberFormat.getCurrencyInstance();
      String priceString = formatter.format(sampleAd.getPrice());
      setPrice(priceString);
    }

    Bundle extras = new Bundle();
    extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, ad.getDegreeOfAwesomeness());
    this.setExtras(extras);

    setOverrideClickHandling(false);
    setOverrideImpressionRecording(false);

    setAdChoicesContent(sampleAd.getInformationIcon());
  }

  @Override
  public void recordImpression() {
    sampleAd.recordImpression();
  }

  @Override
  public void handleClick(View view) {
    sampleAd.handleClick(view);
  }

  // The Sample SDK doesn't do its own impression/click tracking, instead relies on its
  // publishers calling the recordImpression and handleClick methods on its native ad object. So
  // there's no need to pass a reference to the View being used to display the native ad. If
  // your mediated network does need a reference to the view, the following method can be used
  // to provide one.

  @Override
  public void trackViews(View containerView, Map<String, View> clickableAssetViews,
      Map<String, View> nonClickableAssetViews) {
    super.trackViews(containerView, clickableAssetViews, nonClickableAssetViews);
    // If your ad network SDK does its own impression tracking, here is where you can track the
    // top level native ad view and its individual asset views.
  }

  @Override
  public void untrackView(View view) {
    super.untrackView(view);
    // Here you would remove any trackers from the View added in trackView.
  }
}

עכשיו נבחן את קוד ה-constructor.

החזקת הפניה לאובייקט של מודעה מותאמת שמוצגת באמצעות בחירת רשת

הבונה מקבל את הפרמטר SampleNativeAd, מחלקת המודעות המותאמות שבה נעשה שימוש ב-Sample SDK בשביל המודעות המותאמות שלו. למיפוי נדרש הפניה למודעה שעברה תיווך, כדי שיוכל להעביר אירועים מסוג קליק וחשיפה. ‫SampleNativeAd מאוחסן כמשתנה מקומי.

הגדרת מאפייני נכסים ממופים

הפעולה ליצירת אובייקט משתמשת באובייקט SampleNativeAd כדי לאכלס נכסים ב-UnifiedNativeAdMapper.

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

Java

if (sampleAd.getPrice() != null) {
    NumberFormat formatter = NumberFormat.getCurrencyInstance();
    String priceString = formatter.format(sampleAd.getPrice());
    setPrice(priceString);
}

בדוגמה הזו, המודעה שעוברת תיווך שומרת את המחיר כ-double, אבל AdMob משתמשת ב-String לאותו נכס. המיפוי אחראי לטיפול בסוגי ההמרות האלה.

נכסי תמונות של מפות

מיפוי של נכסי תמונות הוא מורכב יותר ממיפוי של סוגי נתונים כמו double או String. יכול להיות שהתמונות יורדו באופן אוטומטי או שיוחזרו כערכי כתובות URL. גם קנה המידה של הפיקסלים ל-DPI יכול להיות שונה.

כדי לעזור לכם לנהל את הפרטים האלה, Google Mobile Ads SDK מספק את המחלקה NativeAd.Image. בדומה ליצירת מחלקת משנה של UnifiedNativeAdMapper כדי למפות מודעה מותאמת שמוצגת דרך שרשור, צריך ליצור מחלקת משנה של NativeAd.Image כשממפים נכסי תמונה.

דוגמה לSampleNativeMappedImage class של אירוע מותאם אישית:

Java

public class SampleNativeMappedImage extends NativeAd.Image {

  private Drawable drawable;
  private Uri imageUri;
  private double scale;

  public SampleNativeMappedImage(Drawable drawable, Uri imageUri, double scale) {
    this.drawable = drawable;
    this.imageUri = imageUri;
    this.scale = scale;
  }

  @Override
  public Drawable getDrawable() {
    return drawable;
  }

  @Override
  public Uri getUri() {
    return imageUri;
  }

  @Override
  public double getScale() {
    return scale;
  }
}

ה-SampleNativeAdMapper משתמש במחלקת התמונות הממופה שלו בשורה הזו כדי להגדיר את נכס תמונת הסמל של הממפה:

Java

setIcon(new SampleNativeMappedImage(ad.getAppIcon(), ad.getAppIconUri(),
    SampleCustomEvent.SAMPLE_SDK_IMAGE_SCALE));

הוספת שדות לחבילת התוספים

חלק מה-SDKs של רשתות גישור מספקים נכסים נוספים מעבר לאלה שבפורמט המודעה המותאמת של AdMob. המחלקות UnifiedNativeAdMapper כוללות שיטה setExtras() שמשמשת להעברת הנכסים האלה לבעלי תוכן דיגיטלי. ה-SampleNativeAdMapper משתמש בזה בשביל נכס 'רמת המגניבות' של Sample SDK:

Java

Bundle extras = new Bundle();
extras.putString(SampleCustomEvent.DEGREE_OF_AWESOMENESS, ad.getDegreeOfAwesomeness());
this.setExtras(extras);

בעלי התוכן הדיגיטלי יכולים לאחזר את הנתונים באמצעות השיטה getExtras() של המחלקה NativeAd.

AdChoices

האירוע המותאם אישית אחראי לספק סמל AdChoices באמצעות השיטה setAdChoicesContent() ב-UnifiedNativeAdMapper. קטע קוד מתוך SampleNativeAdMapper שמראה איך מספקים את סמל AdChoices:

Java

public SampleNativeAdMapper(SampleNativeAd ad) {
    ...
    setAdChoicesContent(sampleAd.getInformationIcon());
}

אירועי חשיפה וקליק

גם Google Mobile Ads SDK וגם ה-SDK של הרשת המגשרת צריכים לדעת מתי מתרחשת חשיפה או מתי מתרחש קליק, אבל רק אחד מהם צריך לעקוב אחרי האירועים האלה. יש שני סוגים של אירועים מותאמים אישית, בהתאם לשאלה אם ה-SDK של הרשת המגשרת תומך במעקב אחרי חשיפות וקליקים באופן עצמאי.

מעקב אחרי קליקים וחשיפות באמצעות Google Mobile Ads SDK

אם ה-SDK של הרשת המתווכת לא מבצע מעקב משלו אחר חשיפות וקליקים, אבל מספק שיטות לתיעוד קליקים וחשיפות, Google Mobile Ads SDK יכול לעקוב אחרי האירועים האלה ולעדכן את המתאם. המחלקה UnifiedNativeAdMapper כוללת שתי שיטות: recordImpression() ו-handleClick(). אירועים מותאמים אישית יכולים להטמיע את השיטות האלה כדי להפעיל את השיטה המתאימה באובייקט המודעה המותאמת אישית שמוצגת באמצעות גישור:

Java

@Override
public void recordImpression() {
  sampleAd.recordImpression();
}

@Override
public void handleClick(View view) {
  sampleAd.handleClick(view);
}

האובייקט SampleNativeAdMapper מכיל הפניה לאובייקט המודעה המקורי של ה-SDK לדוגמה, ולכן הוא יכול להפעיל את השיטה המתאימה באובייקט הזה כדי לדווח על קליק או על חשיפה. שימו לב שהשיטה handleClick() מקבלת פרמטר יחיד: אובייקט View שמתאים לנכס של המודעה המותאמת שקיבל את הקליק.

מעקב אחר קליקים וחשיפות באמצעות ה-SDK של הגישור

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

Java

setOverrideClickHandling(true);
setOverrideImpressionRecording(true);

כדי לדווח על האירועים onAdClicked() ו-onAdImpression() אל Google Mobile Ads SDK, צריך להשתמש באירועים מותאמים אישית שמבטלים את המעקב אחרי קליקים וחשיפות.

כדי לעקוב אחרי חשיפות וקליקים, יכול להיות ש-SDK בתיווך צריך גישה לתצוגות כדי להפעיל את המעקב. האירוע המותאם אישית צריך לבטל את השיטה trackViews() ולהשתמש בה כדי להעביר את התצוגה של המודעה המותאמת ל-SDK של רשת המודעות שנבחרה באמצעות בחירת רשת כדי לעקוב אחרי התצוגה. ה-SDK לדוגמה מפרויקט הדוגמה של האירוע המותאם אישית שלנו (שממנו נלקחו קטעי הקוד במדריך הזה) לא משתמש בגישה הזו, אבל אם הוא היה משתמש בה, קוד האירוע המותאם אישית היה נראה בערך כך:

Java

@Override
public void trackViews(View containerView,
    Map<String, View> clickableAssetViews,
    Map<String, View> nonClickableAssetViews) {
  sampleAd.setNativeAdViewForTracking(containerView);
}

אם ה-SDK של הרשת המגשרת תומך במעקב אחר נכסים ספציפיים, הוא יכול לבדוק בתוך clickableAssetViews אילו תצוגות צריכות להיות קליקביליות. המפה הזו מבוססת על שם נכס ב-NativeAdAssetNames. ‫UnifiedNativeAdMapper offers a corresponding untrackView() method that custom events can override to release any references to the view and disassociate it from the native ad object.

העברת אירועי תהליך בחירת רשת מודעות אל Google Mobile Ads SDK

אפשר למצוא את כל הקריאות החוזרות שנתמכות בתהליך בחירת הרשת במסמכי MediationNativeAdCallback.

חשוב שהאירוע המותאם אישית יעביר כמה שיותר מהקריאות החוזרות האלה, כדי שהאפליקציה תקבל את האירועים המקבילים האלה מ-Google Mobile Ads SDK. דוגמה לשימוש בפונקציות קריאה חוזרת:

כך מסיימים את ההטמעה של אירועים מותאמים אישית במודעות מותאמות. הדוגמה המלאה זמינה ב-GitHub.