Android SDK (Cocos2d-x)

1. Introduction

This document describes the steps to install SmartBeat for Android on Cocos2d-x.
The tested Cocos2d-x (C/C++) versions are 2.1.4, 2.1.5, 2.2, 2.2.3, 3.1.1, 3.2, and Cocos2d-JS versions are 3.7, 3.8, 3.13.1.

The languages supported by this SDK on Cocos2d-x are C/C++ and JavaScript.
The target AndroidOS version is 2.3 or later.
*The normal Android version is 2.2 or later, but since 2.2 is Java-only, it is described as not applicable.

2. Initialize

Step1:SDK Installation

Download SmartBeat SDK from below and unzip it.


Download SDKs in other formats here .

Copy the smartbeat-android-<version>.jar to libcocos2dx of your Project's libs folder(cocos2d/cocos/platform/android/java/libs).
(If the libs folder does not exist, create a new one at the same level as the src folder.)

Open build.gradle in your libcocos2dx project, and add the following line to the dependencies section.

dependencies {
    implementation fileTree(dir: '../java/libs', include: ['*.jar'])
}

Step2:Create Application class and Set API Key

Create a new Application class in the same folder as <project-name>.java that is generated when you create a new Android AndroidProject in Cocos2d-x.
In the case of SimpleGame which is included in Cocos2d-x, it will be in the same folder as SimpleGame.java as shown in the image below. (Create a new class "MyApplication.java")
cocos2dx_and_2

Add the following code to the 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 key");
    }
}

In the first line, the package name is the package name of the target application, and the "API key" is the key issued when creating a new Project from the SmartBeat console.

Step3:Update AndroidManifest.xml

Open AndroidManifest.xml and look for the application element. There is no "android:name" attribute, so write the class name you added in Step2 as shown below.

cocos2dx_and_3

Also, add the Internet permissions (android.permission.INTERNET). (If you have already done so, it is not necessary)

cocos2dx_and_4

SmartBeat uses this permission to send the crash reports and performance metrics.

Step4:Duplicate user count prevention

SDK Version 1.12 and up

By enabling this feature, it is possible to identify a single user even if the user repeatedly uninstalls and re-installs (a.k.a "reset marathon"). That means it is possible to avoid unexpected increases of MAU.

The Audience feature is enabled by using the "Duplicate User Count Prevention" functionality.
※ This only works for the users whose device is using Google Play services 4.0 and above (Otherwise, users are counted as before).

In order to enable this feature, add Google Play services in the following way. If you don't enable this feature, you can skip the following steps.

Step4.1: Migrate to AndroidX (Android Gradle Plugin 3.6 or later)

If you are using Android Gradle Plugin 3.6 or later for your build, please follow the steps below to migrate your project to AndroidX and make play-services-ads-identifier available.

If you do not migrate, a build error may occur in Step 2.

[Android Developers: Migration to AndroidX]
https://developer.android.com/jetpack/androidx/migrate

Step4.2:Add build dependencies

Open build.gradle of the app module and add play-services-ads-identifier to dependencies as shown below. The version of play-services-ads-identifier to be added must be the latest version(https://developers.google.com/android/guides/releases to know the latest version.)

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.google.android.gms:play-services-ads-identifier:17.+'
}

If you are using Android Gradle Plugin 2.3 or earlier for building, use the following dependency instead of the above.

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

After editing build.gradle, please use the "Sync Project with Gradle Files" button on the Android Studio toolbar to synchronize the edited result with the project.

Step5:Audience feature settings

By using Advertising ID, it's possible to understand the gender and age distribution of your users.
The Audience feature is enabled by using the "Duplicate User Prevention" functionality. Please see details regarding the settings for Duplicate User prevention here.

Step6:Set the SmartBeatHandler in your each activity(you can skip this step if your target is only for Android4.0(API level 13) and above)

Add the following code in onResume(), onPause() in your each activity.

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
}

In Cocos2d-x, there is one class that inherits from Cocos2dxActivity, so you can implement it there. (In the case of SimpleGame, it is SimpleGame.java)

cocos2dx_and_5

Step7:ProGuard Symbolication(only for users who use ProGuard)

If you use ProGuard, add the following lines to your ProGuard configuration file.

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

Typically this is the proguard-project.txt or proguard-rules.pro file in your project's root directory.

Add the following if you enabled duplicate user count prevention as described in Step4.

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

3. How to get errors in Cocos2d-JS

SDK Version 1.17 and up

You can get the JavaScript errors in Cocos2d-JS by enabling JavaScript binding in the following steps.
*Please follow the steps below after importing the SDK into your project according to the contents of Section 2.
*This function is supported in Cocos2d-x v3.7 and up.
*The following steps are not necessary for applications that do not use JavaScript.

Copying the SmartBeat JavaScript Binding Library

Copy the smartbeat folder into your project folder under frameworks/cocos2d-x/external.

<Project>
└ frameworks
  └ cocos2d-x
    └ external
      └ smartbeat
        ├ include
        │ └ SmartBeatJSBinding.h
        └ prebuilt
          └ android
            ├ armeabi
            │ └ libSmartBeatJSBinding.a
            
            └ Android.mk

Change build settings

Open the project folder frameworks/runtime-src/proj.android/jni/Android.mk and add an entry for LOCAL_STATIC_LIBRARIES and add 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) #Add here

Register SmartBeatJSBinding

Open the project folder frameworks/runtime-src/Classes/AppDelegate.cpp and add the following include statement.

#include <SmartBeatJSBinding.h>

In AppDelegate::applicationDidFinishLaunching(), add the following line before the sc->start() call.

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

4. Extra functions

4.1 Screenshots function (OpenGL ES)

When this function is activated, you can get some application’s screenshots rendered by OpenGL ES just before the crash. SmartBeat SDK keeps latest screenshot and send them to SmartBeat Server when a crash occurs.
*1 Android 4.0 and above are supported. (Nothing is happen if it is implemented in your application run on less android os version.)
*2 OpenGL ES2.0 and above are supported.
*3 This feature works on supported hardware platforms that are listed in whitelist. See section 6 as reference.

How to activate

You can activate this feature after implementing 3 APIs as following;

Set OpenGL ES version.

Set OpenGL ES version as 1st argument. This must be the same as the version initialized by GLSurfaceView.setEGLContextClientVersion(). It must be called from Renderer.onDrawFrame(GL10 gl) that is subclass of GLSurfaceView.Renderer.
Also set true as 2nd argument if StencilBuffer is used. If it is true, capture function is available on Android 4.3 and above.

Also, add the following import statement to the same file.

import com.smrtbeat.SmartBeat;

<In Version 2.x>
The path to Cocos2dxRenderer.java is 「/cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java".
<In Version 3.x>
The path to Cocos2dxRenderer.java is "/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java".

Call APIs before/after drawing frame.

Open Cocos2dxRenderer.java and add the following implementation to onDrawFrame(final GL10 gl), sandwiching Cocos2dxRenderer.nativeRender() as shown below.
<In Version 2.x>
The path to Cocos2dxRenderer.java is "/cocos2dx/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java".
<In Version 3.x>
The path to Cocos2dxRenderer.java is "/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxRenderer.java".

cocos2dx_and_7

Additional API

Also you can add board name into whitelist. Call following API to enable this feature on additional device. Board names can be acquired by using Build.BOARD.

SmartBeat.whiteListBoardForOpenGLES(board name);

If board name is added, sdk will try to take OpenGL ES screenshot. It means it might fail by some reasons. You can also check by return value of beginOnDrawFrame() whether if it can be started successfully.

4.2 Logging

SDK Version 1.16 and up

Logs will be gathered internally, and not output to the device log.
*The most recent 64KB or 500 lines of log will be included in crash reports.
*If the Section 4.3 LogCat support feature is enabled, the data from this feature will not be used, and LogCat data will be included in the crash report.

How to activate

Output logs using the following API calls.

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

To output logs from NDK(C/C++)use the following code to send logs to the API using JNI. An example cpp file is included in the SDK.

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 support

SmartBeat can also include LogCat with crash/exception data.
*Add the code to the Application class that you created in Section 2, Step 2.
*The most recent 64KB or 500 lines of log will be included in crash reports.
*If the this feature is enabled, the data from section 4.2 Logging will not be used, and only LogCat data will be included in the crash report.

How to activate
■ Java
SmartBeat.enableLogCat();

If you set argument, you can get filtered log.

SmartBeat.enableLogCat(“*:W”);

You can find the detail of filtering rule in the following android site.
http://developer.android.com/tools/debugging/debugging-log.html#filteringOutput

If you want to support LogCat feature with Android prior to version 4.1, add this line:

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

There is no corresponding function in JavaScript.

4.4 Set User Identifier

If your application provides a user ID for each user, you can include it with crash/exception data. That help you find specific user’s errors by using this user ID on the SmartBeat web console.

How to activate

In order to set user ID, call the API below:

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

4.5 Add Extra data

You have another option to add extra custom information into the crash/expection reports. This will help you reproduce and fix errors. (e.g. user’s entering parameters, API return values etc.)

How to activate

In order to set a couple of a key and a value with crash data, call the API below.
The values will be overwritten by new one which has the same key.

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

If you want to add your custom map data, you can use HashMap class:

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 function

Use of the breadcrumb feature makes it possible to know what status changes and operations occured leading up to an error.
Typical operations and status change events are automatically recorded Also, using an API from the app side allows recording of app specific status changes and operations.
Additionally, breadcrumb text can be up to 140 characters in length, with additional metadata, and the most recent 128 will be retained.
*In the event more than 140 characters are supplied, only the leading 140 characters will be retained.
*In the event the total size of the breadcrumb exceeds 1KB, it will be recorded without the specified meta-data.

How to activate

To drop an additional breadcrumb (Leave a record of it) location, call the API shown below.

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

Alternatively, metadata may also be attached using the API shown below.

Map<String, String> meta = new HashMap<String, String>();
meta.put("key", "value");
SmartBeat.leaveBreadcrumbs("game scene 1", meta);
■ JavaScript
SmartBeat.leaveBreadcrumb('game scene 1');

*Attaching metadata is not supported in JavaScript.

4.7 Disabling crash/exception report by default

SDK Version 1.6 and up

You can disable reporting crash/exception by default using following API.

How to activate

Initialize using following api instead.

public class MyApplication extends Application {
    @Override
    public void onCreate () {
        boolean enable = false; //false if it should be disabled by default, true otherwise.
        SmartBeat.initAndStartSession(this, "API key", enable);
    }
}

Use following API to enable reporting crash/exception anytime it should be enabled.
Because this setting is not persistent, you will need to set this flag every time the application is launched.

■ Java

To enable

SmartBeat.enable();

To disable

SmartBeat.disable();

To get the status

boolean enabled = SmartBeat.isEnabled();
■ JavaScript

To enable

SmartBeat.enable();

To disable

SmartBeat.disable();

To get the status

var enabled = SmartBeat.isEnabled();

4.8 JavaScript Exceptions

SDK Version 1.17 and up

SmartBeat supports JavaScript errors that your application catches on Cocos2d-JS.

How to activate
try {
    throw new Error();
} catch (e) {
    SmartBeat.logException(e);
}

4.9 Auto upload symbol files

By embedding the provided “.so Upload script” or “.so Upload Jenkins plugin” in your build environment, a symbol file for C/C++ will be automatically uploaded for every build.

For more details, please check the provided readme file.

What to upload

Upload the libs folder in your application's project.

4. Other Permissions

Some of the data which the SmartBeat SDK collects requires extra permissions.
If there is no permission to access this data, it will be displayed as “no permission” in Device Information in the SmartBeat console.

Permission Data
android.permission.GET_TASKS Number of running apps
android.permission.ACCESS_NETWORK_STATE Status of network

5. Resource usage

The resource usage of SmartBeat SDK is as follows:

Device Items Resource usage
w/o Screenshot function
Resource usage
w/ non-OpenGL
Screenshot function
Resource usage
w/ OpenGL
Screenshot function
Nexus7 (2012)
Android 4.4.2
Mem. usage
CPU usage
about 1.7MB up
no change
about 4.3MB up
ave. 6.4% up
about 5.3MB up
ave. 4.4% up
Xperia AX
Android 4.1.2
Mem. usage
CPU usage
about 0.6MB up
no change
about 5.0MB up
ave. 3.0% up
about 5.9MB up
ave. 4.1% up
Xperia Ray
Android 2.3.4
Mem. usage
CPU usage
about 1.1MB up
no change
about 3.4MB up
ave. 9.0% up
not supported

When screenshots function is active,
- memory usage increases based on pixels of screenshots.
- CPU usage increases due to processes of getting, encoding and sending screenshots.

7. Supports devices for OpenGL ES screenshot

Following devices/platforms are supported to take screenshot for OpenGL ES

Device name Build.MODEL Tested OS
Version
SDK
Version
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 -