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

[プラットフォームを選択]: Android(ベータ版) 新規 Android iOS

前提条件

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

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

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

ネイティブ広告をリクエストするには、Adapter を継承して loadNativeAd() を実装するクラスを作成または変更します。Adapter を継承するクラスがすでに存在する場合は、そこに loadNativeAd() を実装します。また、UnifiedNativeAdMapper を実装する新しいクラスを作成します。

カスタム イベントの例では、カスタム イベントの例SampleCustomEventAdapter クラスを継承(拡張)し、実際の処理を 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 が要求する広告ユニット 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 に求められるインターフェースに合わせて調整されます。カスタム イベントによりこのクラスが拡張され、メディエーション向け 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.
  }
}

ここからは、コンストラクタのコードを詳しく見ていきましょう。

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

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

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

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

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

Java

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

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

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

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

こういった細かい部分を管理しやすいよう、Google Mobile Ads SDK には 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 によっては、AdMob ネイティブ広告フォーマット以外の追加アセットが用意されていることがあります。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

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

Java

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

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

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

クリックとインプレッションのトラッキングを Google Mobile Ads SDK で行う

メディエーション対象の SDK が、インプレッションとクリックの独自トラッキングは行わないものの、クリックとインプレッションを記録するメソッドを提供している場合は、Google Mobile Ads SDKがそれらのイベントをトラッキングしてアダプタに通知することができます。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 に転送する

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

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

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