カスタム ネイティブ広告フォーマット

カスタム ネイティブ広告フォーマット

アド マネージャーをご利用の場合、システム定義のネイティブ広告フォーマットに加えて、アセットのカスタムリストを定義することで独自のネイティブ広告フォーマットを作成することも可能です。これらはカスタム ネイティブ広告フォーマットと呼ばれ、予約広告で使用できます。これにより、パブリッシャーは任意の構造化データをアプリに渡すことができるようになります。これらの広告は NativeCustomFormatAd オブジェクトで表されます。

カスタム ネイティブ広告フォーマットを読み込む

このガイドでは、カスタム ネイティブ広告フォーマットを読み込んで表示する方法について説明します。

AdLoader を作成する

ネイティブ広告と同様に、カスタム ネイティブ広告フォーマットは AdLoader クラスを使って読み込みます。

Java

AdLoader adLoader = new AdLoader.Builder(context, "/6499/example/native")
    .forCustomFormatAd("10063170",
      new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
          @Override
          public void onCustomFormatAdLoaded(NativeCustomFormatAd ad) {
              // Show the custom format and record an impression.
          }
      },
      new NativeCustomFormatAd.OnCustomClickListener() {
          @Override
          public void onCustomClick(NativeCustomFormatAd ad, String s) {
              // Handle the click action
          }
      })
    .withAdListener( ... )
    .withNativeAdOptions( ... )
    .build();

Kotlin

val adLoader = AdLoader.Builder(this, "/6499/example/native")
        .forCustomFormatAd("10063170",
            { ad ->
                // Show the custom format and record an impression.
            },
            { ad, s ->
            // Handle the click action
            })
        .withAdListener( ... )
        .withNativeAdOptions( ... )
        .build()

forCustomFormatAd メソッドは、カスタムのネイティブ広告フォーマットをリクエストするように AdLoader を設定します。このメソッドに渡されるパラメータは次の 3 つです。

  • AdLoader でリクエストされるカスタム ネイティブ広告フォーマットの ID。各ネイティブ広告フォーマットには、それぞれ ID が関連付けられています。このパラメータは、アプリが AdLoader にリクエストする形式を示します。
  • 広告が正常に読み込まれたときに呼び出される OnCustomFormatAdLoadedListener
  • ユーザーが広告をタップまたはクリックしたときに呼び出される OnCustomClickListener(省略可)。このリスナーについて詳しくは、後述の「クリックとインプレッションの処理」をご覧ください。

1 つの広告ユニットを、複数のクリエイティブ フォーマットを配信するように設定できるため、forCustomFormatAd を固有のフォーマット ID で複数回呼び出して、広告ローダーを複数のカスタム ネイティブ広告フォーマットに対応させることも可能です。

カスタム ネイティブ広告フォーマット ID

カスタム ネイティブ広告フォーマットの確認に使用するフォーマット ID は、アド マネージャーの管理画面の [配信] プルダウンにある [ネイティブ] セクションで確認できます。

各カスタムネイティブ広告フォーマット ID は、名前の横に表示されます。いずれかの名前をクリックすると、形式のフィールドに関する情報を示す詳細画面が表示されます。

ここで、項目の追加、編集、削除ができます。各アセットの名前をメモします。この名前は、カスタム ネイティブ広告フォーマットを表示する際に各アセットのデータを取得するために使用されるキーです。

カスタム ネイティブ広告フォーマットを表示する

カスタムのネイティブ広告フォーマットは、システム定義のフォーマットとは異なります。パブリッシャーは、広告を構成するアセットのリストを自分で定義できます。そのため、表示するプロセスは、システム定義の形式とは次の点で異なります。

  1. NativeCustomFormatAd クラスはアド マネージャーで定義したカスタム ネイティブ広告フォーマットを処理するものであり、アセットの「ゲッター」という名前はありません。代わりに、フィールド名をパラメータとして受け取る getTextgetImage などのメソッドが用意されています。
  2. NativeCustomFormatAd で使用する NativeAdView のような専用の広告ビュークラスはありません。ユーザー エクスペリエンスに適したレイアウトを自由に使用できます。
  3. 専用の ViewGroup クラスがないため、広告のアセットの表示に使用するビューを登録する必要はありません。これにより、広告を表示する際に数行のコードを削減できますが、後でクリックを処理するには、追加の作業が必要になります。

NativeCustomFormatAd を表示する関数の例を次に示します。

Java

public void displayCustomFormatAd (ViewGroup parent,
                                     NativeCustomFormatAd customFormatAd) {
    // Inflate a layout and add it to the parent ViewGroup.
    LayoutInflater inflater = (LayoutInflater) parent.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View adView = inflater.inflate(R.layout.custom_format_ad, parent);

    // Locate the TextView that will hold the value for "Headline" and
    // set its text.
    TextView myHeadlineView = (TextView) adView.findViewById(R.id.headline);
    myHeadlineView.setText(customFormatAd.getText("Headline"));

    // Locate the ImageView that will hold the value for "MainImage" and
    // set its drawable.
    Button myMainImageView = (ImageView) adView.findViewById(R.id.main_image);
    myMainImageView.setImageDrawable(
            customFormatAd.getImage("MainImage").getDrawable());

    ...
    // Continue locating views and displaying assets until finished.
    ...
}

Kotlin

public fun displayCustomFormatAd (parent: ViewGroup,
                                customFormatAd: NativeCustomFormatAd) {
    val adView = layoutInflater
            .inflate(R.layout.ad_simple_custom_format, null)

    val myHeadlineView = adView.findViewById<TextView>(R.id.headline)
    myHeadlineView.setText(customFormatAd.getText("Headline"));

    // Locate the ImageView that will hold the value for "MainImage" and
    // set its drawable.
    val myMainImageView = adView.findViewById(R.id.main_image);
    myMainImageView.setImageDrawable(
            customFormatAd.getImage("MainImage").drawable;

    ...
    // Continue locating views and displaying assets until finished.
    ...
}

カスタム ネイティブ広告フォーマット用のネイティブ動画

カスタム フォーマットを作成する際に、フォーマットを動画対応にするオプションが用意されています。

アプリの実装では、NativeCustomFormatAd.getMediaContent() を使用してメディア コンテンツを取得できます。次に、setMediaContent() を呼び出して、メディアビューにメディア コンテンツを設定します。広告に動画コンテンツがない場合は、動画のない別の広告を表示するよう計画します。

下記の例では、広告に動画コンテンツがあるかどうかを確認し、動画がない場合はその場所に画像を表示します。

Java

// Called when a custom native ad loads.
@Override
public void onCustomFormatAdLoaded(final NativeCustomFormatAd ad) {

  MediaContent mediaContent = ad.getMediaContent();

  // Assumes you have a FrameLayout in your view hierarchy with the id media_placeholder.
  FrameLayout mediaPlaceholder = (FrameLayout) findViewById(R.id.media_placeholder);

  // Apps can check the MediaContent's hasVideoContent property to determine if the
  // NativeCustomFormatAd has a video asset.
  if (mediaContent != null && mediaContent.hasVideoContent()) {
    MediaView mediaView = new MediaView(mediaPlaceholder.getContext());
    mediaView.setMediaContent(mediaContent);
    mediaPlaceholder.addView(mediaView);

    // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
    // VideoController will call methods on this object when events occur in the video
    // lifecycle.
    VideoController vc = mediaContent.getVideoController();
    vc.setVideoLifecycleCallbacks(
        new VideoController.VideoLifecycleCallbacks() {
          @Override
          public void onVideoEnd() {
            // Publishers should allow native ads to complete video playback before
            // refreshing or replacing them with another ad in the same UI location.
            super.onVideoEnd();
          }
        });
  } else {
    ImageView mainImage = new ImageView(this);
    mainImage.setAdjustViewBounds(true);
    mainImage.setImageDrawable(ad.getImage("MainImage").getDrawable());
    mediaPlaceholder.addView(mainImage);
    mainImage.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View view) {
            ad.performClick("MainImage");
          }
        });
  }
}

Kotlin

// Called when a custom native ad loads.
NativeCustomFormatAd.OnCustomFormatAdLoadedListener { ad ->

  val mediaContent = ad.mediaContent

  // Apps can check the MediaContent's hasVideoContent property to determine if the
  // NativeCustomFormatAd has a video asset.
  if (mediaContent != null && mediaContent.hasVideoContent()) {
    val mediaView = MediaView(mediaPlaceholder.getContest())
    mediaView.mediaContent = mediaContent

    val videoController = mediaContent.videoController

    // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
    // VideoController will call methods on this object when events occur in the video
    // lifecycle.
    if (videoController != null) {
      videoController.videoLifecycleCallbacks =
        object : VideoController.VideoLifecycleCallbacks() {
          override fun onVideoEnd() {
            // Publishers should allow native ads to complete video playback before refreshing
            // or replacing them with another ad in the same UI location.
            super.onVideoEnd()
          }
        }
    }
  } else {
    val mainImage = ImageView(this)
    mainImage.adjustViewBounds = true
    mainImage.setImageDrawable(ad.getImage("MainImage")?.drawable)

    mainImage.setOnClickListener { ad.performClick("MainImage") }
    customTemplateBinding.simplecustomMediaPlaceholder.addView(mainImage)
  }
}

カスタム ネイティブ広告で動画のエクスペリエンスをカスタマイズする方法について詳しくは、MediaContent をご覧ください。

アド マネージャーのカスタム レンダリングの例をダウンロードして、ネイティブ動画の実際の動作例をご確認ください。

カスタム ネイティブ広告フォーマットのクリック数とインプレッション数

カスタム ネイティブ広告フォーマットでは、アプリでインプレッションを記録し、クリック イベントを Google Mobile Ads SDK に報告する必要があります。

インプレッションを記録する

カスタム フォーマット広告のインプレッションを記録するには、対応する NativeCustomFormatAdrecordImpression メソッドを呼び出します。

myCustomFormatAd.recordImpression();

アプリが誤って同じ広告のメソッドを 2 回呼び出すと、1 回のリクエストで SDK によって重複インプレッションが記録されなくなります。

クリックを報告する

アセットビューでクリックが発生したことを SDK に報告するには、対応する NativeCustomFormatAdperformClick メソッドを呼び出して、クリックされたアセットの名前を渡します。たとえば、「MainImage」というカスタム形式のアセットがあり、そのアセットに対応する ImageView のクリックを報告する場合、コードは次のようになります。

myCustomFormatAd.performClick("MainImage");

広告に関連付けられているすべてのビューについて、このメソッドを呼び出す必要はありません。表示されるが、ユーザーがクリックしたりタップしたりしないようにする「Caption」という別のフィールドがある場合、アプリはそのアセットのビューに対して performClick を呼び出す必要はありません。

カスタム クリック アクションに対応する

カスタム フォーマット広告でクリックが行われると、SDK から返される可能性のある次の 3 つのレスポンスが次の順序で試行されます。

  1. OnCustomClickListener が提供された場合は、AdLoader から呼び出します。
  2. その広告のディープリンク URL ごとに、コンテンツ リゾルバを特定し、解決する最初のリゾルバを開始する。
  3. ブラウザを開き、広告の従来のリンク先 URL に移動する。

forCustomFormatAd メソッドは OnCustomClickListener を受け入れます。リスナー オブジェクトを渡すと、SDK は代わりにその onCustomClick メソッドを呼び出し、それ以上のアクションは行いません。ただし、リスナーとして null 値を渡すと、SDK は広告に登録されたディープリンク URL またはリンク先 URL にフォールバックします。

カスタム クリック リスナーを使用すると、UI の更新、新しいアクティビティの起動、クリックの記録のみなど、クリックに応答して最適なアクションを決定できます。クリックが行われたことだけをログに記録する例を次に示します。

Java

AdLoader adLoader = new AdLoader.Builder(context, "/6499/example/native")
    .forCustomFormatAd("10063170",
      new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
        // Display the ad.
      },
      new NativeCustomFormatAd.OnCustomClickListener() {
          @Override
          public void onCustomClick(NativeCustomFormatAd ad, String assetName) {
            Log.i("MyApp", "A custom click just happened for " + assetName + "!");
          }
      }).build();

Kotlin

val adLoader = AdLoader.Builder(this, "/6499/example/native")
    .forCustomFormatAd("10063170",
        { ad ->
            // Display the ad.
        },
        { ad, assetName ->
                Log.i("MyApp", "A custom click just happened for $assetName!")
    }).build()

最初は、カスタム クリック リスナーが存在するのは奇妙に思えるかもしれません。クリックが発生したことを SDK がアプリに説明したばかりなので、なぜ SDK はそれを処理してアプリに報告するべきでしょうか。

この情報フローはいくつかの理由から有用ですが、最も重要な点として、SDK がクリックへの応答を管理できることが挙げられます。たとえば、クリエイティブ用に設定したサードパーティのトラッキング URL に自動的に ping して、バックグラウンドで他のタスクを処理できます。コードを追加する必要はありません。