プログラミングノート

一からものを作ることが好きなエンジニアの開発ブログです。

Cocos2d-xにAdMob (インタースティシャル) を導入する方法 - Android編

前回のバナー導入に引き続き今度はインタースティシャル編。AdMobバナーが表示出来ていれば、AndroidManifest.xmlの変更は不要なので、コードを追記していくだけで対応できる。

まずは検証として、起動したらインタースティシャル広告がでるようにしてみるコードはこちら。(バナー関連のコードは削除してインタースティシャルで必要となるコードのみ記載)

package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;

public class AppActivity extends Cocos2dxActivity {

  private static final String LOG_TAG = "interstitial";
  private InterstitialAd interstitial;

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    interstitial = new InterstitialAd(this);
    interstitial.setAdUnitId("ca-app-pub-xxxxx/xxxxx");

    interstitial.setAdListener(new AdListener() {
      @Override
      public void onAdLoaded() {
        if (interstitial.isLoaded()) {
          interstitial.show();
        } else {
          Log.d(LOG_TAG, "interstitial isn't loaded.");
        }
      }
      @Override
      public void onAdFailedToLoad(int errorCode) {
        Log.d(LOG_TAG, getErrorReason(errorCode));
      }
    });

    AdRequest interRequest = new AdRequest.Builder().build();
    interstitial.loadAd(interRequest);
  }

  private String getErrorReason(int errorCode) {
    String errorReason = "";
    switch (errorCode) {
    case AdRequest.ERROR_CODE_INTERNAL_ERROR:
      errorReason = "Internal error";
      break;
    case AdRequest.ERROR_CODE_INVALID_REQUEST:
      errorReason = "Invalid request";
      break;
    case AdRequest.ERROR_CODE_NETWORK_ERROR:
      errorReason = "Network Error";
      break;
    case AdRequest.ERROR_CODE_NO_FILL:
      errorReason = "No fill";
      break;
    }
    return errorReason;
  }
}

任意のタイミングで広告表示

cocos2d-x側 (C++) からJavaのコードを呼び出すと、任意のタイミングでインタースティシャルを表示することができる。まずは下記の2ファイルを追加。

AdMobHelper.h

#ifndef __ADMOBHELPER_H__
#define __ADMOBHELPER_H__

class AdMobHelper {
public:
  static void launchInterstitial();
};
#endif

AdMobHelper.cpp

#include "AdMobHelper.h"
#include <jni.h>
#include "platform/android/jni/JniHelper.h"

#define CLASS_NAME "org/cocos2dx/cpp/AppActivity"

void AdMobHelper::launchInterstitial() {
  cocos2d::JniMethodInfo t;
  if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "launchInterstitial", "()V")) {
    t.env->CallStaticVoidMethod(t.classID, t.methodID);
    t.env->DeleteLocalRef(t.classID);
  }
}

Android.mk

追加したファイルを追記しておく。

LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp \
                   ../../Classes/AdMobHelper.cpp

AppActivityを修正

複数回表示できるよう、呼び出されるメソッド内部で広告のロードを行う。UIスレッドで広告を表示しないと例外で落ちてしまうのでrunOnUiThreadを利用している。

public class AppActivity extends Cocos2dxActivity {
  private static final String LOG_TAG = "interstitial";
  private static InterstitialAd interstitial;
  private static Context context = null;

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    interstitial = new InterstitialAd(this);
    interstitial.setAdUnitId("ca-app-pub-xxxxx/xxxxx");
  }

  public static void launchInterstitial() {
    final Activity activity = (Activity) context;
    activity.runOnUiThread(new Runnable() {
      public void run() {
        interstitial.setAdListener(new AdListener() {
          @Override
          public void onAdLoaded() {
            if (interstitial.isLoaded()) {
              interstitial.show();
            } else {
              Log.d(LOG_TAG, "interstitial isn't loaded.");
            }
          }
          @Override
          public void onAdFailedToLoad(int errorCode) {
            Log.d(LOG_TAG, getErrorReason(errorCode));
          }
        });
        AdRequest interRequest = new AdRequest.Builder().build();
        interstitial.loadAd(interRequest);
      }
    });
  }
  ...
}

最後に、サンプルにあるHelloWorldSceneのクローズボタンを押したタイミングでこのメソッドを実行するようにする。

void HelloWorld::menuCloseCallback(Ref* pSender){
  AdMobHelper::launchInterstitial();
}

各アドネットワークによって配布されているcocos2d-xモジュールについても、基本的にはこれと同じことをしているだろうし、基本的にはこの流れだけ抑えておけばC++とJavaの連携もそこまで難しくはなさそう。

参考

ntaku.hateblo.jp