前提条件
カスタム イベントのセットアップを完了します。
ネイティブ広告をリクエストする
ウォーターフォール メディエーション チェーンでカスタム イベント広告申込情報に到達すると、カスタム イベントの作成時に指定したクラス名で 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 に報告する。
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. } }
次に、コンストラクタ コードについて詳しく見てみましょう。
メディエーション対象ネイティブ広告オブジェクトへの参照を保持する
コンストラクタは、サンプル SDK がネイティブ広告用に使用するネイティブ広告クラスである SampleNativeAd
パラメータを受け取ります。クリック イベントとインプレッション イベントを渡すことができるように、マッパーはメディエーション対象広告への参照を必要とします。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 値として返されることもあります。ピクセル密度もさまざまに異なる可能性があります。
こういった細かい部分を管理しやすいよう、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
カスタム イベントは、UnifiedNativeAdMapper
の setAdChoicesContent()
メソッドを使用して 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 で入手できます。