ネイティブ広告のカスタム イベント

プラットフォームを選択: Android iOS Android(以前のバージョン)

前提条件

カスタム イベントのセットアップを完了しておきます。

ネイティブ広告をリクエストする

ウォーターフォール メディエーションの順序がカスタム イベントの広告申込情報に回ってくると、カスタム イベントの作成時に指定したクラス名で loadNativeAd() メソッドが呼び出されます。この場合、メソッドは SampleCustomEvent 内に定義されており、そこから、SampleNativeCustomEventLoader 内の loadNativeAd() メソッドが呼び出されます。

ネイティブ広告をリクエストするには、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 (Legacy) に報告する。

アド マネージャーの管理画面で定義されたオプション パラメータは、広告設定に含まれます。このパラメータには adConfiguration.getServerParameters().getString(MediationConfiguration.CUSTOM_EVENT_SERVER_PARAMETER_FIELD) を介してアクセスできます。このパラメータは通常、広告オブジェクトをインスタンス化する際に広告ネットワーク SDK が要求する広告ユニット ID です。

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 を実装するクラスのインスタンスを渡すことで呼び出されます。

通常、これらのメソッドは、アダプタが実装するサードパーティ SDK のコールバック内に実装されます。この例では、関連するコールバックを含む SampleAdListener が「Sample SDK」に含まれています。

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 (Legacy) に求められるインターフェースに合わせて調整します。カスタム イベントによりこのクラスが拡張され、メディエーション向け 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.
  }
}

コンストラクタ コードを詳しく見てみましょう。

メディエーション対象ネイティブ広告オブジェクトへの参照を保持する

コンストラクタは、サンプル SDK がネイティブ広告で使用するネイティブ広告クラスである SampleNativeAd パラメータを受け取ります。クリック イベントとインプレッション イベントを渡すため、マッパーはメディエーション対象広告への参照を必要とします。SampleNativeAd はローカル変数として保存されます。

マッピングされたアセット プロパティを設定する

コンストラクタは SampleNativeAd オブジェクトを使用して、アセットを UnifiedNativeAdMapper に自動入力します。

次のスニペットは、メディエーション対象広告の価格データを取得し、そのデータを使ってマッパーの価格を設定します。

Java

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

この例では、メディエーション対象広告では価格は double として保存されますが、アド マネージャーでは、そのアセットに対して String が使用されます。マッパーは、このような変換の処理を担当します。

画像アセットをマッピングする

画像アセットのマッピングは、double や String などのデータ型のマッピングに比べると複雑です。画像は自動でダウンロードされることもあれば、URL 値として返されることもあります。ピクセル密度もさまざまに異なる可能性があります。

こういった細かい部分を管理しやすいよう、Google Mobile Ads SDK (Legacy) には NativeAd.Image クラスが用意されています。デベロッパーは、UnifiedNativeAdMapper のサブクラスを作成して、メディエーション対象ネイティブ広告をマッピングする必要がありますが、同様に NativeAd.Image のサブクラスを作成して、画像アセットをマッピングする必要もあります。

カスタム イベントの SampleNativeMappedImage クラスの例を次に示します。

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));

Bundle(extras)にフィールドを追加する

メディエーション向け SDK によっては、アド マネージャー ネイティブ広告フォーマット以外の追加アセットが用意されていることがあります。UnifiedNativeAdMapper クラスには、これらのアセットをパブリッシャーに渡すために使用される setExtras() メソッドが含まれています。SampleNativeAdMapper では、これが、サンプル SDK の「degree of awesomeness」アセットに対して使用されます。

Java

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

パブリッシャーは、NativeAd クラスの getExtras() メソッドを使用してデータを取得できます。

AdChoices

カスタム イベントは、UnifiedNativeAdMapper の setAdChoicesContent() メソッドを使用して AdChoices アイコンを提供する役割を担います。以下の SampleNativeAdMapper のスニペットは、AdChoices アイコンを提供する方法を示しています。

Java

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

インプレッション イベントとクリック イベント

インプレッションとクリックの発生は、Google Mobile Ads SDK (Legacy) とメディエーション対象 SDK の両方で検知される必要がありますが、それをイベントとしてトラッキングする必要があるのは一方の SDK だけです。カスタム イベントで使用できるトラッキングのアプローチは 2 種類あります。メディエーション対象 SDK がインプレッションとクリックの独自トラッキングに対応しているかどうかに応じて、適切なほうを選びましょう。

Google Mobile Ads SDK (Legacy) でクリックとインプレッションをトラッキングする

メディエーション対象の SDK が、インプレッションとクリックの独自トラッキングは行わないものの、クリックとインプレッションを記録するメソッドを提供している場合は、Google Mobile Ads SDK (Legacy) がそれらのイベントをトラッキングしてアダプタに通知することができます。UnifiedNativeAdMapper クラスには recordImpression() と handleClick() の 2 つのメソッドがあり、カスタム イベントはこれらのメソッドを実装して、メディエーション対象ネイティブ広告オブジェクトの対応メソッドを呼び出します。

Java

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

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

SampleNativeAdMapper は、サンプル SDK のネイティブ広告オブジェクトへの参照を保持しているため、同オブジェクトの適切なメソッドを呼び出して、クリックまたはインプレッションを報告することができます。handleClick() メソッドは単一のパラメータ(クリックを受けたネイティブ広告アセットに対応する View オブジェクト)を受け取ります。

クリックとインプレッションのトラッキングをメディエーション対象 SDK で行う

メディエーション対象 SDK の中には、クリックとインプレッションを独自にトラッキングさせたほうがよいものもあります。その場合は、UnifiedNativeAdMapper のコンストラクタで次の 2 つの呼び出しを行うことによって、デフォルトのクリックとインプレッションのトラッキングをオーバーライドする必要があります。

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 には対応する untrackView() メソッドが用意されており、カスタム イベントはこのメソッドをオーバーライドしてビューへの参照をすべて解放し、ネイティブ広告オブジェクトとの関連付けを解除します。

メディエーション イベントを Google Mobile Ads SDK (Legacy) に転送する

メディエーションでサポートされているすべてのコールバックについては、MediationNativeAdCallback ドキュメントをご覧ください。

カスタム イベントには、こうしたコールバックを可能な限り漏れなく転送させましょう。これにより、アプリは同等イベントを Google Mobile Ads SDK (Legacy) から受け取ることができます。コールバックの使用例を以下に示します。

これで、ネイティブ広告のカスタム イベントの実装が完了しました。サンプル全体は GitHub で入手できます。