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

前提条件

カスタム イベントの設定を完了します。

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

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

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

このカスタム イベントの例では、SampleCustomEvent がthe Adapter interface を実装し、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 interfaceの実装

  • 広告イベント コールバックを受信して Google Mobile Ads SDK に報告する

UI で定義されたオプション パラメータは、 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 がサンプル 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 値として返されます。ピクセル対 dpi のスケールもさまざまです。

こうした詳細情報を管理しやすくするために、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 にフィールドを追加する

メディエーション向け 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 の両方がインプレッションまたはクリックの発生タイミングを認識する必要がありますが、これらのイベントをトラッキングする必要があるのは 1 つの SDK のみです。カスタム イベントで使用できるアプローチは 2 種類あり、メディエーションされる SDK がインプレッションとクリックの独自のトラッキングをサポートしているかどうかに応じて異なります。

Google Mobile Ads SDK を使ってクリックとインプレッションをトラッキングする

メディエーション向け SDK が独自にインプレッションとクリックのトラッキングを実行せず、クリックとインプレッションを記録するメソッドを提供している場合、Google Mobile Ads SDK はこれらのイベントをトラッキングしてアダプタに通知できます。UnifiedNativeAdMapper interface には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 で入手できます。