Android 向けの AFS ネイティブ実装

Google Mobile Ads SDK は、カスタム検索スタイルもサポートしています。アプリですでに Google Mobile Ads SDK を使用している場合は、代わりに AFSMA SDK バージョンを使用することをおすすめします。

18.1.0 以前からバージョン 19.0.0 以降にアップグレードする場合は、移行ガイドをご覧ください。

前提条件

この実装ガイドは、次の内容を理解していることを前提としています。

AFS ネイティブ SDK をインポートする

SDK を追加する

AFS ネイティブ SDK をアプリに追加する手順は次のとおりです。

アプリケーション モジュールのディレクトリにある build.gradle ファイルを開きます。最新バージョンの SDK 用の新しいビルドルールを dependencies に追加します。

dependencies {
  implementation 'com.google.android.gms:play-services-afs-native:19.1.0'
}

トップレベルの build.gradle に、google() リポジトリまたは maven { url "https://maven.google.com" } への参照が含まれていることを確認します。

こちらの手順に沿って、Google Play スタンドアロン バージョン マッチャー プラグインをプロジェクトに含めます。このプラグインを適用すると、AFS ネイティブ SDK が互換性のないバージョンの Google Play 開発者サービスで使用されている場合、アプリのビルドが許可される代わりに Gradle ビルドエラーが発生し、ランタイム クラッシュが発生する可能性があります。または、プロジェクトに failOnVersionConflict() ResolutionStrategy を適用して、プロジェクトで互換性のないバージョンの Google Play 開発者サービスが使用されている場合にビルドエラーが発生するようにします。変更を保存し、ツールバーの [Sync Project with Gradle Files] をクリックします。

Android サポート ライブラリの代わりに AndroidX を使用する

SDK バージョン 17.0.0 以降では、アプリで Android サポート ライブラリではなく Jetpack(AndroidX)ライブラリを使用する必要があります。互換性要件:

  • com.android.tools.build:gradle を v3.2.1 以降に設定します。
  • compileSdkVersion を 28 以降に設定します。
  • Jetpack(AndroidX)を使用するようにアプリを更新します。AndroidX への移行の手順に沿って操作します。

クラス

アプリで AFS ネイティブ広告を配信するには、次のクラスを実装します。

SearchAdController

  • このクラスは、広告の非同期リクエスト、広告のキャッシュ保存と取得、広告のレンダリングを担当します。
  • 各広告コンテキストには個別の SearchAdController が必要です。たとえば、検索結果のリストとともに広告を表示する画面と、特定の商品の詳細とともに広告を表示する画面がある場合は、ケースごとに 2 つの個別の SearchAdController インスタンスを作成する必要があります。
  • コンストラクタには、ウェブ プロパティ コード(パブリッシャー ID)、返された広告に適用するスタイル IDSearchAdOptions を指定する必要があります。コンストラクタで指定する Context は、SearchAdController を含む Activity で、広告 View を配置する場所である必要があります。
  • loadAds を呼び出して、新しいユーザー検索を通知し、非同期広告リクエストを開始します。loadAds への以前の呼び出しから読み込まれた広告は、新しい呼び出しが行われると内部広告キャッシュから削除されます。
  • createAdView を使用して View を作成し、広告クリエイティブを表示します。
  • 広告が読み込まれたら、createAdView で生成した View を指定して populateAdView を呼び出し、キャッシュに保存された広告をその View にレンダリングします。入力する View に加えて、広告を一意に識別する任意の文字列である adKey を指定します。これにより、キャッシュから返された特定の広告クリエイティブがその adKey に関連付けられるため、同じ adKeypopulateAdView への今後の呼び出しに渡されると、同じ広告が返されます。たとえば、adKey="keyA"populateAdView が初めて呼び出され、ハイキング シューズの広告がレンダリングされた場合、adKey="keyA"populateAdView が呼び出されるたびに、同じハイキング シューズの広告が入力されます。(loadAds を新たに呼び出すと、キャッシュに保存されているすべての広告と関連する広告キーが消去されます)。

SearchAdOptions

  • このオブジェクトを SearchAdController コンストラクタに渡して、広告のリクエストと表示方法をカスタマイズします。SearchAdOptions.Builderbuild() を呼び出して、SearchAdOptions オブジェクトを作成します。

View

  • SearchAdControllercreateAdView() を呼び出して、広告を保持する View オブジェクトを作成します。一度に表示される広告は 1 つまでですが、同じ View を再利用して、時間の経過とともに異なる広告を表示できます。

SearchAdRequest

  • SearchAdRequest を指定して SearchAdControllerloadAds メソッドを呼び出し、非同期広告リクエストを開始します。SearchAdRequest.Builderbuild() を呼び出して、SearchAdRequest オブジェクトを作成します。

AdListener

  • このインターフェースを実装して SearchAdController コンストラクタに渡し、複数の状態のコールバックを登録します。
  • 注: AdListener コールバックは、キャンセルされたリクエスト(最初の呼び出しが解決する前に loadAds への別の呼び出しによってプリエンプトされた loadAds への呼び出し)では呼び出されません。

実装例

次の例は、サンプル ActivitySearchAdController を作成する方法を示しています。

//  MainActivity.java implementation
//  (MainActivity is a subclass of Activity)

SearchAdController adController;
// adContainer where we will place our ads in this example.
ViewGroup adContainer;

protected void onCreate(Bundle bundle){
  super.onCreate(bundle);
  adContainer = (ViewGroup) findViewById(...);
  // Specify ad options (not required).
  SearchAdOptions.Builder adOptionsBuilder = new SearchAdOptions.Builder();
  adOptionsBuilder.setAdType(SearchAdOptions.AD_TYPE_TEXT);
  adOptionsBuilder.setPrefetch(true);
  adOptionsBuilder.setNumAdsRequested(3);
  // Provide a callback to trigger when ads are loaded.
  AdListener adListener = new AdListener() {
    public void onAdLoaded() {
      createAndShowAd();
    }
  };
  // Instantiate the SearchAdController.
  adController = new SearchAdController(this, "your-client-id", "your-style-id",
                                        adOptionsBuilder.build(), adListener);
}

ユーザーがクエリを開始したら、SearchAdRequest を作成し、SearchAdControllerloadAds を呼び出して非同期広告リクエストを開始します。

// Create the request.
SearchAdRequest.Builder requestBuilder = new SearchAdRequest.Builder();
requestBuilder.setQuery("user query here");
// Load the ads.
adController.loadAds(requestBuilder.build());

onAdLoaded コールバックを実装して、読み込んだ広告を広告ビューに入力します。

private void createAndShowAd() {
  // Create a new view that will contain the ad.
  View adView = adController.createAdView();
  // Attach the new view to the view hierarchy.
  adContainer.addView(adView);
  // Display the ad inside the adView. We need to provide an adKey to
  // indicate which ad is to be displayed in the adView. In this example, 
  // since we only have one ad, we can provide any constant string. However, 
  // if you intend to display multiple ads, each ad you wish to display
  // should be given a unique adKey of your choosing.
  adController.populateAdView(adView, "demoAd");
}

指定したクエリに関連する広告が adView に表示されます。

エラーの調査

SearchAdController には、広告を表示する準備ができていることをアプリに通知する onAdLoaded() メソッドを含む AdListener オブジェクトが必要です。また、エラーを検出して修正できるように、onAdFailedToLoad() メソッドを実装する必要があります。たとえば、次の AdListener を使用して実装をデバッグできます。

AdListener adListener = new AdListener() {
    public void onAdLoaded() {
        // Called when an ad is loaded.
        Toast.makeText(MainActivity.this, "Ad Loaded",
                Toast.LENGTH_SHORT).show();
        Log.d(MainActivity.class.getSimpleName(), "Ad Loaded");
    }

    public void onAdLeftApplication() {
        // Called when an ad leaves the application
        // (to go to the browser for example).
        Toast.makeText(MainActivity.this, "Ad Left Application",
                Toast.LENGTH_SHORT).show();
        Log.d(MainActivity.class.getSimpleName(), "Ad Left Application");
    }

    @Override
    public void onAdFailedToLoad(int errorCode) {
        // Called when an ad request failed.
        Toast.makeText(MainActivity.this, "Ad Failed to Load: " + errorCode,
                Toast.LENGTH_SHORT).show();
        Log.e(MainActivity.class.getSimpleName(), "Ad Failed to Load: " +
                errorCode);
    }
};

onAdFailedToLoad() コールバック メソッドで使用される定数は、AdListener で定義されています。