Cocos2d-xでGoogleAnalyticsを使用する

Cocos2d-x上からGoogleAnalyticsのトラッキングを試してみました。

Analyticsの機能はたくさんありますが、今回はスクリーンとイベントトラッキングを試してみました。
他のトラッキングをしたい場合も、同じようにできると思います。

今回使用したバージョン

  • cocos2d-2.0-x-2.0.4

準備
AnalyticsのWebサイトでプロパティ作成時に「アプリ」を選択し、トラッキングIDを控えておきます。

iOSAndroidそれぞれで、必要なライブラリを設定しておきます。
Google Analytics SDK for iOS v2 (Legacy) - Overview  |  Analytics for iOS v2 (Legacy)  |  Google Developers
Google Analytics SDK for Android v2 (Legacy) - Overview  |  Analytics for Android v2 (Legacy)  |  Google Developers

また、コードへのトラッキングIDの設定がそれぞれ必要です。

iOS
AppController.mm

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

	// Override point for customization after application launch.
	[[GAI sharedInstance] trackerWithTrackingId:@"UA-XXXXXXXX-X"];	// 追加

	// Add the view controller's view to the window and display.
	window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
	...

Android
analytics.xml

<?xml version="1.0" encoding="utf-8" ?>

<resources>
  <!--Replace placeholder ID with your tracking ID-->
  <string name="ga_trackingId">UA-XXXXXXXX-X</string>

  <!--Enable Activity tracking-->
  <bool name="ga_autoActivityTracking">false</bool>

  <!--Enable automatic exception tracking-->
  <bool name="ga_reportUncaughtExceptions">true</bool>
</resources>


今回もtks2.net - このウェブサイトは販売用です! - 講演 依頼 開発 イラスト ウェブ 作成 ソフトウェア デザイン リソースおよび情報で公開されているBrowserLauncherをベースにしました。

  • NativeCodeLauncherという名前に変えていますが、BrowserLauncherという名前でも問題なく動きます。
  • Android側のJavaコードはCocos2dxActivityを継承したOkahiroCocos2dXクラスに置いています。

実装
NativeCodeLauncher.h

namespace Cocos2dExt {
    class NativeCodeLauncher
    {
    public:
		static void trackView(char const *view);
		static void trackEvent(char const *category,char const *action,char const *label,int value);
    };
}

NativeCodeLauncher.mm

static void static_trackView(const char* view)
{
	[NativeCodeLauncher trackView:[NSString stringWithUTF8String:view]];
}

static void static_trackEvent(const char *category, const char *action, const char *label, int value)
{
	[NativeCodeLauncher trackEvent:[NSString stringWithUTF8String:category]
						 action:[NSString stringWithUTF8String:action]
						  label:[NSString stringWithUTF8String:label]
						  value:[NSNumber numberWithInt:value]];
}

namespace Cocos2dExt
{
	void NativeCodeLauncher::trackView(const char *view)
	{
		static_trackView(view);
	}
	
	void NativeCodeLauncher::trackEvent(const char *category, const char *action, const char *label, int value)
	{
		static_trackEvent(category, action, label, value);
	}
}

NativeCodeLauncher_objc.h

@interface NativeCodeLauncher : NSObject

+(void)trackView:(NSString *)view;
+(void)trackEvent:(NSString *)category action:(NSString *)action label:(NSString *)label value:(NSNumber *)value;

@end

NativeCodeLauncher_objc.m

@implementation NativeCodeLauncher

+(void)trackView:(NSString *)view
{
	[[[GAI sharedInstance] defaultTracker] trackView:view];
}

+(void)trackEvent:(NSString *)category action:(NSString *)action label:(NSString *)label value:(NSNumber *)value
{
	[[[GAI sharedInstance] defaultTracker] trackEventWithCategory:category withAction:action withLabel:label withValue:value];
}

@end

NativeCodeLauncher.cpp

namespace Cocos2dExt
{
	void NativeCodeLauncher::trackView(char const *view)
	{
		trackViewJNI(view);
	}
	
	void NativeCodeLauncher::trackEvent(char const *category,char const *action,char const *label,int value)
	{
		trackEventJNI(category,action,label,value);
	}
}

NativeCodeLauncherJni.h

extern "C"
{
	extern void trackViewJNI(char const *view);
	extern void trackEventJNI(char const *category,char const *action,char const *label,int value);
}

NativeCodeLauncherJni.cpp

...

//#define  CLASS_NAME "org/cocos2dx/lib/Cocos2dxActivity"
#define CLASS_NAME "jp/milt/okahiro/OkahiroCocos2dX"

...

extern "C"
{

...

	void trackViewJNI(char const *view)
	{
		JniMethodInfo methodInfo;
        
		if (!getStaticMethodInfo(methodInfo, "trackView", "(Ljava/lang/String;)V"))
		{
			return;
		}
        
		jstring stringArg = methodInfo.env->NewStringUTF(view);
		methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg);
		methodInfo.env->DeleteLocalRef(stringArg);
		methodInfo.env->DeleteLocalRef(methodInfo.classID);
	}
	
	void trackEventJNI(char const *category,char const *action,char const *label,int value)
	{
		JniMethodInfo methodInfo;
        
		if (!getStaticMethodInfo(methodInfo, "trackEvent", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V"))
		{
			return;
		}
        
		jstring categoryArg = methodInfo.env->NewStringUTF(category);
		jstring actionArg = methodInfo.env->NewStringUTF(action);
		jstring labelArg = methodInfo.env->NewStringUTF(label);
		
		methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, categoryArg,actionArg,labelArg,value);
		methodInfo.env->DeleteLocalRef(categoryArg);
		methodInfo.env->DeleteLocalRef(actionArg);
		methodInfo.env->DeleteLocalRef(labelArg);
		methodInfo.env->DeleteLocalRef(methodInfo.classID);
	}
}

OkahiroCocos2dX.java

public class OkahiroCocos2dX extends Cocos2dxActivity{

	
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		
		EasyTracker.getInstance().setContext(this); // 追加
	}
	
    static {
         System.loadLibrary("game");
    }
    
    // JNIから呼び出すメソッド
    public static void trackView(String view)
    {
    	EasyTracker.getTracker().trackView(view);
    }
    
    public static void trackEvent(String category,String action,String label,int value)
    {
    	EasyTracker.getTracker().trackEvent(category, action, label, Long.valueOf(value));
    }
}

ここまででOKです。


呼び出し
Cocos2d-Xのコードから呼び出す場合はそれぞれ1行でOKです。

// スクリーントラッキング
Cocos2dExt::NativeCodeLauncher::trackView("HelloWorldScene");
// イベントトラッキング
Cocos2dExt::NativeCodeLauncher::trackEvent("TestCategory", "TestAction", "TestLabel", 100);

結果

スクリーン

イベント


ラッキングIDはiOSAndroidそれぞれで設定するので、プロパティを同じにすることも別にすることも可能です。