Android SDK (Cocos2d-x)

1. はじめに

本ドキュメントは、Android向けSmartBeatをCocos2d-xに導入するための手順を記述します。
動作検証済みのCocos2d-x(C/C++)のバージョンは、2.1.4, 2.1.5, 2.2, 2.2.3, 3.1.1, 3.2、Cocos2d-JSのバージョンは3.7, 3.8, 3.13.1となります。

本SDKが対応しているCocos2d-x上の言語はC/C++およびJavaScriptです。動作対象のAndroidOSは、2.3以降となります。
※通常Android版は2.2以降ですが、2.2はJavaのみのため、対象外として記述しております。

2. AndroidのProjectへのSDKの取り込み方法

Step1:ライブラリの取り込み

下記からSmartBeatのSDKをダウンロードして、unzipしてください。


他形式のSDKは こちら からダウンロードしてください。

  • Android Studio
  • Eclipse + ADT
「smartbeat-android-<version>.jar」を「libcocos2dx」のProjectのlibsフォルダ(cocos2d/cocos/platform/android/java/libs)にコピーする
(libsフォルダが存在しない場合は、srcフォルダと同じ階層に新規作成する)

libcocos2dx」のProjectのbuild.gradleを開き、dependenciesのところに以下の記述を追加する

dependencies {
    compile fileTree(dir: '../java/libs', include: ['*.jar'])
}
「smartbeat-android-<version>.jar」を「libcocos2dx」のProjectのlibsフォルダにコピーする
(libsフォルダが存在しない場合は、srcフォルダと同じ階層に新規作成する)

coco2dx_and_1

Step2:Applicationクラスの作成とAPIキーの設定

Cocos2d-xで新規Android AndroidProjectを作成時に生成される<project-name>.javaと同じ階層にApplicationクラスを新規で作成する。
Cocos2d-xにサンプルで入っているSimpleGameの場合では、下記画像のようにSimpleGame.javaと同じフォルダになる。(MyApplication.javaを新規作成)

cocos2dx_and_2

追加したMyApplication.javaに下記のように実装する。

package org.cocos2dx.simplegame;

import com.smrtbeat.SmartBeat;

import android.app.Application;

public class MyApplication extends Application{
    public void onCreate() {
        SmartBeat.initAndStartSession(this, "APIキー");
    }
}

1行目のパッケージ名は対象となるアプリのパッケージ名、「APIキー」はコンソールよりProject新規作成時に発行されるキーを設定する。

Step3:AndroidManifest.xmlの変更

AndroidManifest.xmlを開き、applicationの要素を探すと「android:name」の属性が無いので、下記のようにStep2で追加したクラス名を記述する。

cocos2dx_and_3

また、Internetのパーミッション(android.permission.INTERNET)を追加する。(既に追加してある場合は不要)

cocos2dx_and_4

これは、アプリ内で発生したクラッシュデータをSmartBeatサーバへ送信するため最低限必要なPermissionとなります。

Step4:重複ユーザカウントの抑止設定

SDKバージョン1.12以降

ユーザ数の集計に広告IDを使用することで、同一ユーザの重複カウントを抑止します。これにより、アプリの再インストールを繰り返す行為(俗に言う「リセマラ」)があった場合でも、不要なMAU(Monthly Active Users)数の増加を抑えることができます。

※ 重複ユーザカウントの抑止設定を有効にすることでオーディエンス機能も有効となります。
※ 本機能はGoogle Play services 4.0以降がイントールされた端末を使用するユーザカウントにのみ有効です(それ以外のユーザは従来通りカウントされます)。

本機能を有効にするためには、以下の手順でアプリにGoogle Play servicesを組み込んでください。本機能を有効にしない場合には、以下の手順は不要です。

  • Android Studio
  • Eclipse + ADT
Google Repositoryのダウンロード

Android SDK ManagerでGoogle Repositoryをインストールしてください。
install_google_repository

build.gradleの編集

アプリのモジュールのbuild.gradleを開き、以下のようにdependenciesにplay-servicesを追加してください。追加するplay-servicesのバージョンは最新バージョン(https://developers.google.com/android/guides/releases を参照)を指定してください。

dependencies {
    compile fileTree(dir: '../java/libs', include: ['*.jar'])
    compile 'com.google.android.gms:play-services:8.4.0'
}

build.gradle編集後はAndroid Studioのツールバーの「Sync Project with Gradle Files」ボタンで編集結果をプロジェクトに同期してください。

Google Play servicesのダウンロード

Android SDK ManagerでGoogle Play servicesをインストールしてください。
install_google_play_services

プロジェクトの追加

Eclipseで「File」 -> 「Import」から「Existing Android Code into Workspace」を選び、google-play-services_libをプロジェクトにインポートしてください。google-play-services_libはAndroid SDKのインストールディレクトリ配下の以下のディレクトリにあります。

<android-sdk>/extras/google/google_play_services/libproject/google-play-services_lib

「Copy projects into workspace」のチェックはオンにしてください。
import_google_play_services

ライブラリの追加

アプリのプロジェクトのプロパティを開き、「Android」の設定の「Library」の項目にある「Add...」ボタンをクリックしてgoogle-play-services_libを追加してください。
library_google_play_services

マニフェストファイルの編集

アプリのマニフェストファイルを開き、要素に以下を追加してください。

<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />

Step5:onResume, onPauseの登録(Android4.0より前(APIレベル13以前)も対象とする場合のみ)

各ActivityのonResume()、onPause()に以下のコードを追加してください。

import com.smrtbeat.SmartBeat;

@Override
protected void onResume(){
    super.onResume();
    SmartBeat.notifyOnResume(this);
    //your code
}

@Override
protected void onPause(){
    super.onPause();
    SmartBeat.notifyOnPause(this);
    //your code
}

Cocos2d-xでは、Cocos2dxActivityを継承したクラスが1つあるので、そこに実装してください。(SimpleGameの場合は、SimpleGame.java)

cocos2dx_and_5

Step6:Proguardの設定(Proguard有効時のみ)

Proguardを有効にしている場合、Proguardの設定に以下を追加してください。

-dontwarn com.smrtbeat.**
-keep class com.smrtbeat.** { *; }

通常は、プロジェクトのルートにある、proguard-project.txtまたはproguard-rules.proを編集してください。

Step4の重複ユーザカウントの抑止設定を有効にした場合は以下の設定も追加してください。

-dontwarn com.google.android.gms.**

3. Cocos2d-JSのエラー取得

SDKバージョン1.17以降

以下の手順でJavaScriptバインディングを有効にすることで、Cocos2d-JSのJavaScript側のエラーを取得することができます。
※第2章の内容に従ってプロジェクトにSDKを取り込んだ後で以下の手順を行ってください。
※JavaScriptエラーの取得はCocos2d-x v3.7以上で対応しています。
※JavaScriptを使わないアプリでは以下の手順は必要ありません。

SmartBeat JavaScriptバインディングライブラリのコピー

プロジェクトフォルダのframeworks/cocos2d-x/external以下にsmartbeatフォルダをコピーする。

<プロジェクト>
└ frameworks
  └ cocos2d-x
    └ external
      └ smartbeat
        ├ include
        │ └ SmartBeatJSBinding.h
        └ prebuilt
          └ android
            ├ armeabi
            │ └ libSmartBeatJSBinding.a
            
            └ Android.mk

ビルド設定の変更

プロジェクトフォルダのframeworks/runtime-src/proj.android/jni/Android.mkを開いて、LOCAL_STATIC_LIBRARIESの項目追加とimport-moduleの追加を行う。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := cocos2djs_shared

LOCAL_MODULE_FILENAME := libcocos2djs

LOCAL_SRC_FILES := hellojavascript/main.cpp \
                   ../../Classes/AppDelegate.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes

LOCAL_STATIC_LIBRARIES := cocos2d_js_static \
                          SmartBeatJSBinding #ここを追加

LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT

include $(BUILD_SHARED_LIBRARY)


$(call import-module, scripting/js-bindings/proj.android)
$(call import-module, external/smartbeat/prebuilt/android) #ここを追加

SmartBeat JavaScriptバインディングの登録

プロジェクトフォルダのframeworks/runtime-src/Classes/AppDelegate.cppを開いて、以下のinclude文を追加する。

#include <SmartBeatJSBinding.h>

AppDelegate::applicationDidFinishLaunching()の中で、sc->start()の呼び出しよりも前に以下の1行を追加する。

bool AppDelegate::applicationDidFinishLaunching()
{
    ...
    sc->addRegisterCallback(...);
    sc->addRegisterCallback(...);
    ...
    sc->addRegisterCallback(SmartBeat::registerSmartBeatJSBinding); //ここを追加
    sc->start();
    ...
}

4. オプション機能

4.1 画面キャプチャ機能(OpenGL ES)

本機能を有効にすることで、OpenGL ESで描画された画面のキャプチャ機能を有効にすることができます。
SDKでは、アプリケーション表示中の最新画面を定期的キャプチャし、クラッシュ時に最新の1枚をSmartBeatサーバへ送信します。
※1 本機能はAndroid4.0以上でのみ機能します。(4.0未満の場合は実装しても問題ありませんが、機能は動作しません)
※2 機能はOpenGL ES 2.0以上利用の場合でのみ機能します。(1.x利用の場合に実装しても問題ありませんが、機能は動作しません)
※3 本機能はWhitelistに登録されたプラットフォームのみで動作します。第6章参照。

有効化方法

本機能を有効にするには、後述の通り3つAPIの呼出を実装していただく必要があります。

OpenGL ESのバージョンの設定

Cocos2dxRenderer.javaを開き、onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig)の関数に下記のように追加してください。
第1引数の値はCocos2dxGLSurfaceView.javaのsetEGLContextClientVersionに渡している値と同じ値を設定してください。
第2引数の値はStencilBufferの利用の有無を設定してください。Cocos2d-xの、CCClippingNode/ClippingNodeを利用する場合はtrueです。また、trueが設定された場合、画面キャプチャはAndroid4.3以降のみで有効になります。

また、同ファイルに下記import文も追加してください。

import com.smrtbeat.SmartBeat;

<2.xの場合>
Cocos2dxRender.javaへのパスは「/cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java」です。
<3.xの場合>
Cocos2dxRender.javaへのパスは「/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java」です。

OpenGL描画前後でのAPIの呼出

Cocos2dxRenderer.javaを開き、onDrawFrame(final GL10 gl)に下記のようにCocos2dxRenderer.nativeRender()を挟むように、実装を追加してください。
<2.xの場合>
Cocos2dxRender.javaへのパスは「/cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java」です。
<3.xの場合>
Cocos2dxRender.javaへのパスは「/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java」です。

cocos2dx_and_7

追加API

また、任意のデバイスをwhitelistに追加する場合、以下のAPIを利用して追加可能です。

SmartBeat.whiteListModelForOpenGLES(モデル名);

「モデル名」はAndroidのAPI(Build.MODEL)から取得した値が設定できます。
whitelistに追加した場合でも初期化に失敗した場合、AndroidのOSバージョンが非サポートの場合などは動作しません。
正常に動作を開始することができたか、否かはbeginOnDrawFrame()の戻り値で確認することができます。

4.2 ログ出力

SDKバージョン1.16以降

端末のログに出力すること無く、ログの収集をすることができます。
※64KBに満たない場合は最大500行、それ以外は64KBに収まる範囲で最新のログを取得します。
※4.3章のLogCat出力機能を有効にした場合、本機能によるログはクラッシュデータに含まれず、
 LogCatのログのみがクラッシュデータに含まれます。

有効化方法

以下のAPI呼び出しを実装することで、ログを保存できます。

■ Java
SmartBeat.log("message");
■ C/C++

NDK(C/C++)からログ出力する場合は以下のような関数を用意してJNIの機能を使って上のAPIを呼び出してください。SDKに以下の実装を含んだcppファイルが含まれています。

void SmartBeat_log(JNIEnv* env, const char* msg)
{
    jclass cls = env->FindClass("com/smrtbeat/SmartBeat");
    if (cls == NULL)
        return;
    jmethodID method = env->GetStaticMethodID(cls, "log", "(Ljava/lang/String;)V");
    if (method == NULL) {
        env->DeleteLocalRef(cls);
        return;
    }
    jstring str = env->NewStringUTF(msg);
    if (str == NULL) {
        env->DeleteLocalRef(cls);
        return;
    }
    env->CallStaticVoidMethod(cls, method, str);
    env->DeleteLocalRef(str);
    env->DeleteLocalRef(cls);
}
■ JavaScript
SmartBeat.log('message');

4.3 LogCat出力

LogCatの出力をクラッシュデータに含める場合は、LogCat出力機能を有効にしてください。
※第2章 Step2で作成したApplicationクラスに実装してください。
※64KBに満たない場合は最大500行、それ以外は64KBに収まる範囲で最新のログを取得します。
※本機能を有効にした場合、4.2章のログ出力APIによるログはクラッシュデータに含まれず、
 LogCatのログのみがクラッシュデータに含まれます。

有効化方法
■ Java
SmartBeat.enableLogCat();

また、下記のようにフィルタを引数として与えるとフィルタされたログのみを取得できます。

SmartBeat.enableLogCat(“*:W”);

フィルタの詳細に関してはAndroidのサイトをご参照ください。
http://developer.android.com/tools/debugging/debugging-log.html#filteringOutput

なお、Android4.1より前(APIレベル15以前)においては、LogCatの出力のため、下記Permissionが必要となります。
Android4.1以降においては、Permissionの設定は不要ですが、自身のアプリが出力したLogのみが取得可能です。

<uses-permission android:name="android.permission.READ_LOGS"/>
■ JavaScript

JavaScriptで該当する関数はありません。

4.4 ユーザID設定

対象のアプリケーションが管理するユーザを識別するIDが既にある場合、それを設定することができます。
設定されたユーザIDはクラッシュとともにSmartBeatサーバへ送信されます。どのユーザでクラッシュが発生したかなど管理コンソール上で確認が可能です。

有効化方法

以下のAPI呼び出しを実装することで、設定可能です。

■ Java
SmartBeat.setUserId("user001");
■ JavaScript
SmartBeat.setUserId('user001');

4.5 拡張情報

クラッシュ情報に拡張情報を付与することができます。アプリケーションによっては、ユーザが設定した情報や、アプリケーションが内部に保持している情報が、クラッシュ解析に役立ちます。

有効化方法

以下のAPI呼び出しを実装することで、任意のキー名と値のセットをクラッシュデータと共に保存することが可能です。
値を変更したい場合は、同じキー名で追加すると、新しい値で上書きされます。

■ Java
SmartBeat.addExtraData("key1", "value1");
SmartBeat.addExtraData("area", "Tokyo");

また、拡張情報をHasMapを使って複数同時に設定することも可能です。

HashMap<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("area", "Tokyo");
SmartBeat.addExtraData(map);
■ JavaScript
SmartBeat.addExtraData('key1', 'value1');
SmartBeat.addExtraData('area', 'Tokyo');

4.6 パンくず(breadcrumb)機能

任意のポイントでパンくずを残すことにより、エラー発生までにユーザが行った操作や画面遷移などを収集することができます。

有効化方法

パンくずを落とす(記録を残したい)場所で以下のAPIを呼び出して下さい。
パンくずは最後に記録されたものから最大16個保存されます。
例えば、「マップ画面」→「ゲーム画面」→「設定画面」などと、キーとなる画面の遷移時に残した場合、エラー直前にユーザがどのような画面遷移を行ったかを知ることができます。

■ Java
SmartBeat.leaveBreadcrumbs("game scene 1");
■ JavaScript
SmartBeat.leaveBreadcrumb('game scene 1');

4.7 エラー収集有効・無効切り替え

SDKバージョン1.6以降

初期状態をエラー収集無効とし、途中からエラーの収集を有効にしたい場合に利用できます。

有効化方法

Ste3:APIキーの設定で記述したAPIの代わりに以下のAPIで起動時に有効とするか、無効とするか設定してください。

public class MyApplication extends Application {
    @Override
    public void onCreate () {
        boolean enable = false; //無効状態で起動する場合は、false
        SmartBeat.initAndStartSession(this, "APIキー", enable);
    }
}

その後、有効にしたい場合は、任意の箇所で以下のコードを呼び出してください。呼び出された以降に発生したエラーの収集を行います。
なお、有効・無効の設定は毎起動時に initAndStartSession(Application app, String appKey, boolean enabled) で設定してください。

■ Java

有効化

SmartBeat.enable();

無効化

SmartBeat.disable();

状態取得

boolean enabled = SmartBeat.isEnabled();
■ JavaScript

有効化

SmartBeat.enable();

無効化

SmartBeat.disable();

状態取得

var enabled = SmartBeat.isEnabled();

4.8 CatchしたJavaScriptエラーの保存

SDKバージョン1.17以降

Cocos2d-JSでアプリケーションがCatchしたJavaScriptエラーを記録することができます。

有効化方法
try {
    throw new Error();
} catch (e) {
    SmartBeat.logException(e);
}

4.9 シンボルファイル自動アップロード

.so Upload script」または「.so Upload Jenkins plugin」をビルド環境に組み込むことで、毎ビルド時に自動でC/C++のシンボルファイルをアップロードすることができます。

詳しくは、各提供スクリプト内のreadmeファイルをご確認ください。

アップロード対象

アップロード対象のフォルダは、アプリケーションのAndroidプロジェクトのlibsフォルダを指定してください。

4.10 オーディエンス機能

対ユーザ識別子として Advertising ID for Android もしくは IDFA for iOS を使用することで、アプリケーションを利用するユーザの男女比や年齢分布を確認できるようになります。

有効方法

重複ユーザカウントの抑止設定を有効にすることでオーディエンス機能も有効となります。重複ユーザカウントの抑止設定についてはこちらを参照ください。

5. その他Permission

SmartBeatは、クラッシュログ収集時に解析に必要な端末の状態など周辺情報も一緒に記録します。
それら情報の中にはPermissionの付与が必要な物があります。SmartBeatはPermissionがなく、情報の取得ができない場合、”no permission”と記録しますが、Permissionを付与することで以下の情報も取得することができます。

Permission名 取得可能情報
android.permission.GET_TASKS 起動アプリ数
android.permission.ACCESS_NETWORK_STATE NW接続状態

6. リソース消費

SDK組込みによるリソースの消費計測結果を以下に示す。

端末 項目 SDK組込み時 通常画面
キャプチャ有効
OpenGL ES画面
キャプチャ有効
Nexus7 (2012)
Android 4.4.2
メモリ消費量
CPU負荷
約1.7MB増加
増減なし
約4.3MB増加
平均 約6.4%増加
約5.3MB増加
平均 約4.4%増加
Xperia AX
Android 4.1.2
メモリ消費量
CPU負荷
約0.6MB増加
増減なし
約5.0MB増加
平均 約3.0%増加
約5.9MB増加
平均 約4.1%増加
Xperia Ray
Android 2.3.4
メモリ消費量
CPU負荷
約1.1MB増加
増減なし
約3.4MB増加
平均 約9.0%増加
非サポート

※画面キャプチャを有効にした場合は、画面の画素数に応じてメモリ消費量が増加
※画面キャプチャを有効にした場合は、画面取得、エンコード処理、保存処理が入るため、CPU負荷が増加

7. OpenGL ES画面キャプチャ対象端末

OpenGL ES画面キャプチャ機能のサポート対象を記述する

デバイス名 Build.MODEL 検証OS
バージョン
SDK
バージョン
NEXUS 5 Nexus 5 4.4 1.8 -
AQUOS PAD SH-06F SH-06F 4.4.2 1.8 -
AQUOS ZETA SH-04F SH-04F 4.4.2 1.8 -
Xperia ZL2 SOL25 SOL25 4.4.2 1.8 -
Xperia Z1 SOL23 SOL23 4.4.2 1.13 -
Xperia Z1 f SO-02F SO-02F 4.4.2 1.13 -
HTC J butterfly HTL23 HTL23 4.4.4 1.13 -
isai LGL22 4.4.2 1.13 -
Galaxy S5 SM-G900K 5.0 1.14 -

8. 改版履歴

2014年11月20日Cocos2d-x 3.xでの実装方法の注釈を追記

改版日 変更内容
2014年6月2日 初版リリース
2014年10月23日 「4.2 画面キャプチャ機能」の有効化方法を変更
「7. OpenGL ES画面キャプチャ対象端末」の対象端末を更新
2016年1月6日 「Step4:重複ユーザカウントの抑止設定」を追加(SDKバージョン1.12以降)
「Step6:Proguardの設定(Proguard有効時のみ)」を更新
2016年3月14日 「7. OpenGL ES画面キャプチャ対象端末」の対象端末を更新
2016年4月8日 「7. OpenGL ES画面キャプチャ対象端末」の対象端末を更新
2016年4月20日 「4.10 オーディエンス機能」を追加
2016年11月21日 「4.2 ログ出力」を追加(SDKバージョン1.16以降)
「4.3 LogCat出力」の補足説明を追加
2016年12月22日 「1. はじめに」でCocos2d-xの動作検証済みバージョンと対応言語を更新
「3. Cocos2d-JSのエラー取得」を追加(SDKバージョン1.17以降)
「4. オプション機能」の各章にJavaScriptのAPIを追加
「4.6 パンくず(breadcrumb)機能」を追加
「4.7 エラー収集有効・無効切り替え」を追加
「4.8 CatchしたJavaScriptエラーの保存」を追加
2017年3月27日 「2. Cocos2d-x(Android)のProjectへのSDKの取り込み方法」にAndroid Studioでの手順を追加
「4.9 シンボルファイル自動アップロード」を追加