Пользовательские события нативной рекламы

Предпосылки

Завершите настройку пользовательских событий .

Запросить нативную рекламу

При достижении элемента строки пользовательского события в каскадной цепочке медиации вызывается метод loadNativeAd() для имени класса, указанного вами при создании пользовательского события . В данном случае этот метод находится в SampleCustomEvent , который затем вызывает метод loadNativeAd() в SampleNativeCustomEventLoader .

Чтобы запросить нативную рекламу, создайте или измените класс, расширяющий Adapter , для реализации loadNativeAd() . Если класс, расширяющий Adapter , уже существует, реализуйте в нём loadNativeAd() . Кроме того, создайте новый класс для реализации UnifiedNativeAdMapper .

В нашем примере пользовательского события SampleCustomEvent расширяет класс Adapter , а затем делегирует полномочия SampleNativeCustomEventLoader .

Ява

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 рекламной сети требует при создании экземпляра объекта объявления.

Ява

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 .

Обычно эти методы реализуются внутри обратных вызовов стороннего SDK, который реализует ваш адаптер. В данном примере в Sample SDK есть SampleAdListener с соответствующими обратными вызовами:

Ява

@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. Вот пример маппера рекламы из нашего проекта пользовательского события:

Ява

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.
  }
}

Теперь подробнее рассмотрим код конструктора.

Сохраните ссылку на опосредованный объект нативной рекламы.

Конструктор принимает параметр SampleNativeAd — класс нативной рекламы, используемый Sample SDK для своих нативных объявлений. Для передачи событий кликов и показов модулю сопоставления необходима ссылка на промежуточную рекламу. SampleNativeAd хранится как локальная переменная.

Установить сопоставленные свойства активов

Конструктор использует объект SampleNativeAd для заполнения ресурсов в UnifiedNativeAdMapper .

Этот фрагмент получает данные о цене рекламного объявления и использует их для установки цены сопоставителя:

Ява

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

В этом примере рекламное объявление сохраняет цену как значение типа double , тогда как AdMob использует String для того же актива. За обработку этих типов конверсий отвечает маппер.

Активы изображения карты

Сопоставление ресурсов изображений сложнее, чем сопоставление типов данных, таких как double или String . Изображения могут загружаться автоматически или возвращаться в виде значений URL. Их масштабы пикселей в точках на дюйм также могут различаться.

Для управления этими данными в Google Mobile Ads SDK есть класс NativeAd.Image . Подобно тому, как для сопоставления медиа-объявлений нативной рекламы требуется создать подкласс UnifiedNativeAdMapper , для сопоставления изображений также необходимо создать подкласс NativeAd.Image .

Вот пример класса SampleNativeMappedImage пользовательского события:

Ява

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 использует свой класс сопоставленного изображения в этой строке для установки ресурса изображения значка средства сопоставления:

Ява

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

Добавить поля в пакет дополнительных услуг

Некоторые опосредованные SDK предоставляют дополнительные ресурсы, выходящие за рамки формата нативной рекламы AdMob. Класс UnifiedNativeAdMapper включает метод setExtras() , который используется для передачи этих ресурсов издателям. SampleNativeAdMapper использует этот метод для ресурса «степень крутости» в Sample SDK:

Ява

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

Издатели могут получить данные с помощью метода getExtras() класса NativeAd .

AdChoices

Ваше пользовательское событие отвечает за отображение значка AdChoices с помощью метода setAdChoicesContent() в UnifiedNativeAdMapper . Вот фрагмент кода из SampleNativeAdMapper показывающий, как добавить значок AdChoices:

Ява

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

События показа и клика

Как Google Mobile Ads SDK, так и опосредованный SDK должны знать, когда происходит показ или клик, но только один SDK должен отслеживать эти события. Существует два разных подхода к пользовательским событиям, в зависимости от того, поддерживает ли опосредованный SDK отслеживание показов и кликов самостоятельно.

Отслеживайте клики и показы с помощью Google Mobile Ads SDK

Если опосредованный SDK не отслеживает показы и клики самостоятельно, но предоставляет методы для регистрации кликов и показов, Google Mobile Ads SDK может отслеживать эти события и уведомлять адаптер. Класс UnifiedNativeAdMapper включает два метода: recordImpression() и handleClick() , которые пользовательские события могут реализовать для вызова соответствующего метода в объекте опосредованной нативной рекламы:

Ява

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

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

Поскольку SampleNativeAdMapper содержит ссылку на объект нативной рекламы Sample SDK, он может вызвать соответствующий метод этого объекта, чтобы сообщить о клике или показе. Обратите внимание, что метод handleClick() принимает один параметр: объект View , соответствующий активу нативной рекламы, по которому был совершен клик.

Отслеживайте клики и показы с помощью опосредованного SDK

Некоторые опосредованные SDK могут предпочесть самостоятельное отслеживание кликов и показов. В этом случае следует переопределить отслеживание кликов и показов по умолчанию, выполнив следующие два вызова в конструкторе UnifiedNativeAdMapper :

Ява

setOverrideClickHandling(true);
setOverrideImpressionRecording(true);

Для передачи событий onAdClicked() и onAdImpression() в Google Mobile Ads SDK необходимы пользовательские события, которые переопределяют отслеживание кликов и показов.

Для отслеживания показов и кликов опосредованному SDK, вероятно, потребуется доступ к представлениям. Пользовательское событие должно переопределять метод trackViews() и использовать его для передачи представления нативной рекламы в опосредованный SDK для отслеживания. В примере SDK из нашего проекта с пользовательскими событиями (из которого взяты фрагменты кода для этого руководства) этот подход не используется; но если бы он использовался, код пользовательского события выглядел бы примерно так:

Ява

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

Если опосредованный SDK поддерживает отслеживание отдельных объектов, он может просматривать данные в clickableAssetViews , чтобы определить, какие представления следует сделать кликабельными. Эта карта определяется именем объекта в NativeAdAssetNames . UnifiedNativeAdMapper предлагает соответствующий метод untrackView() , который пользовательские события могут переопределять, чтобы освободить все ссылки на представление и отсоединить его от объекта нативной рекламы.

Пересылка событий медиации в Google Mobile Ads SDK

Все обратные вызовы, поддерживаемые медиацией, можно найти в документации MediationNativeAdCallback .

Важно, чтобы ваше пользовательское событие пересылало как можно больше таких обратных вызовов, чтобы ваше приложение получало эквивалентные события от Google Mobile Ads SDK. Вот пример использования обратных вызовов:

На этом реализация пользовательских событий для нативной рекламы завершена. Полный пример доступен на GitHub .