SDK 接入概要

初始化接口
void init ( ... );

确保在调用其他接口之前正确调用 AppLogger::init 接口,仅在第一次调用时有效;

Android 下通常在 第一个 Activity 的 onCreate() 中调用初始化接口;

事件接口调用结构
						
onStart // 应用启动
    onSubStart // 关卡或页面的开始
        // 关卡中发生的事件
        onBuy, onUse, onEvent … 等事件接口
        onPassFail 关卡成功或失败
    onSubEnd // 关卡或页面的结束
    
    // 关卡外发生的事件
onEnd // 应用退出,Back按键强制退出调用onExit
					

onStart, onEnd 通常在 Activity::onResume, Activity::onPause 中由开发者调用。

onSubStart, onSubEnd 表示一个关卡/页面的开始与结束,可以嵌套,但不能交叉

onSubStart 的第一个参数stage是关卡名称,用版本号的形式,例如 “1”, “2”, “2.1”, “2.2”, … 。如果是字母开始,作为页面。

如果通过 System.KillProcess 函数退出应用(例如Android下双击Back按键退出应用),确保调用 onExit 接口。

获取 APPKEY

1,登录 天梯游戏统计 后台,进入我的应用界面,在应用汇总窗口点击 “创建新应用”。如图:

创建新应用截图

2,输入应用的相关信息后,点击 “提交应用”,即可。如图:

提交应用截图

3,得到唯一的 APPKEY,接入 SDK 时使用。如图:

APPKEY截图

Android SDK 导入

下载 SDK 压缩包后解压至本地目录,需要将 logger/sdk/libs/android 目录下的 applogger.jar,applogger.so 和 AppLogger.h 添加到应用工程中。

1,开发环境配置
Android Studio 导入

(1) 将 applogger.jar 和包含 .so 文件的目录(armeabi, armeabi-v7a, x86, ...)复制到工程的 libs 目录下,复制目录时,只选择当前工程所支持的架构。

(2) 在 Module 的 buid.gradle 文件中添加 .so 库目录配置:

						
android {
    sourceSets {
    	main.jniLibs.srcDirs = ['libs']
    }
}
					

完成后点击 Sync,同步配置。

Eclipse 导入
(1) applogger.jar 的导入

1.1) 将 logger/sdk/libs/android 目录下的 applogger.jar 复制到工程根目录的 libs 文件夹中(若没有 libs 目录,则选中工程右键“New” -> Folder -> 命名为 “libs”)。

1.2) 右键单击工程,选择 Build Path 中的 Configure Build Path...,选中Libraries,并通过 Add Jars... 导入工程 libs 目录下的 applogger.jar 文件(最新的 ADT工具会自动导入 libs 目录下的 jar 包,故该步骤可以省略)。

(2) applogger.so 的导入

纯 Java 的 Android 项目,将 libs/android 目录下的所有子目录 (armeabi, armeabi-v7a, x86, ...) 复制到工程目录下的 libs 目录中。复制目录时,只选择当前工程所支持的架构。

2,编译配置

(1) 在 Android 工程加载自己项目 .so 的地方,添加对 liblogger.so 的引用。注意,liblogger.so 的加载顺序,需要在自己的 .so 之前:

						
static {
    System.loadLibrary("logger"); //liblogger.so的加载,在demo lib前面
    System.loadLibrary("your_app_lib"); //demo lib
}
					

(2) 如果使用 AppLogger 的 C++ 接口,需修改 Android.mk 文件

注意:如果使用 NDK 编译,则 sdk 不要放在 libs 目录中,因为 NDK 编译时,会删除 libs 目录下所有的文件夹。例子中的 logger/sdk 放在了工程目录下。

						
LOCAL_PATH := $(call my-dir)
#——— 开始添加,加载 liblogger.so ———
include $(CLEAR_VARS)
LOCAL_MODULE:=liblogger

#如果使用 Android Studio 环境
LOCAL_SRC_FILES:=$(TARGET_ARCH_ABI)/liblogger.so

#如果使用 NDK 环境
#LOCAL_SRC_FILES:=../logger/sdk/libs/android/$(TARGET_ARCH_ABI)/liblogger.so
include $(PREBUILT_SHARED_LIBRARY)
#——— 结束添加 ———

include $(CLEAR_VARS)
LOCAL_MODULE := your_app_lib
……
LOCAL_SRC_FILES := xxx.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../xxx

#——— 开始添加,引入 Applogger.h 路径 ———
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../logger/sdk
#——— 结束添加 ———
……

#——— 开始添加,引用 liblogger.so ———
#放在 BUILD_SHARED_LIBRARY 前
LOCAL_SHARED_LIBRARIES := liblogger
#——— 结束添加 ———
					
3,AndroidManifest.xml 配置

Android 应用的可以通过 AndroidManifest.xml 修改一些参数定义。包括应用ID与渠道定义,以及 SDK 基本权限定义。

(1) Meta-Data
						
<meta-data android:name="TT_APPID" android:value="XXXXXXXXXXXXXXXX" />
<meta-data android:name="TT_CHANNEL" android:value="渠道名称" />
					

TT_APPID:32字符串,用来定位该应用程序的唯一性

TT_CHANNEL:字符串,用来标注应用的推广渠道

<meta-data ... /> 标签需放在 <application> 标签内

(2) 权限
						
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
					

INTERNET:允许程序联网来发送统计数据

READ_PHONE_STATE:用来获取手机设备的通信运营商信息

ACCESS_NETWORK_STATE:用来获取设备的网络类型(2G/3G/4G/WiFi等)

ACCESS_WIFI_STATE:用来获取设备的MAC地址

WRITE_EXTERNAL_STORAGE:用来保存唯一信息

<uses-permission ... /> 标签需放在 <application> 标签外

Android SDK 初始化

定义
void init (Context context, String appId, String appChannel);

Android 下通常在 第一个 Activity 的 onCreate() 中调用初始化接口:


import com.tianti.AppLogger;

public class MainActivity extends Activity {
    ...
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	...
    	AppLogger.init(this, appId, appChannel);
    	...
    }
    ...
}
					

context: 当前的 Activity

appId: 应用的唯一标识,在天梯游戏统计后台创建应用时自动生成。具体详见:获取 APPKEY

appChannel: 应用分发渠道名 (iOS 版本通常指定为 "AppStore")

功能

初始化数据统计服务

用法

appId 和 appChannel 通常在 AndroidManifest.xml 中指定,特殊情况下也可以直接通过 init 接口指定。init 接口优先于 AndroidManifest.xml 中的定义。

						
<manifest …… >
……
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application …… >
……
<meta-data android:name="TT_APPID" android:value="XXXXXXXXXXXXXXXX" />
<meta-data android:name="TT_CHANNEL" android:value="渠道名称" />
</application>
</manifest>
					

确保在程序启动的时候调用初始化接口,仅在第一次调用时有效。

通常在 第一个 Activity 的 onCreate() 中调用初始化接口。

如果需要临时禁用天梯游戏统计相关服务,不需要逐一注释相关代码,只需要注释掉 init 函数调用,天梯游戏统计 将不会记录,保存,传输任何数据,所有接口调用直接忽略

基本事件

启动应用 onStart
定义
void onStart ();
功能

应用启动事件

用法

用于当应用启动或从后台切换到前台时

通常在 Activity::onResume 事件中调用

通过 onStart 接口可以获得应用的 新增,活跃,启动,安装,升级 等等各种基本数据。如图:

onStart 接口实例图
如果没有正确调用 onStart 接口,本次启动之后的所有事件接口都无效,必须先正确调用 onStart 接口
退出应用 onEnd
定义
void onEnd ();
功能

应用退出事件

用法

用于当应用退出或退到后台时

通常在 Activity::onPause 事件中调用

通过 onEnd 接口,可以统计应用的使用时长等各种数据。如图:

onEnd 接口实例图

如果是彻底退出应用(双击 Back 按键退出),请使用 onExit 事件接口

如果退出时没有正确调用onEnd(或onExit) 接口,下次启动时,会发现一次异常(退出)

彻底退出应用 onExit
定义
void onExit ();
功能

彻底退出应用的事件

用法

Back 按键退出应用(System.exit, Process.Kill),用 onExit 强制声明退出整个应用。

onExit 与 onEnd 的区别在于不会根据间隔时间参数判断是否与下次启动事件合并,并且会自动关闭本次启动中所有没有关闭的关卡和页面。

现在可以登录 天梯游戏统计 后台,然后运行您的游戏,即可实时看到当前启动游戏的记录。实时心跳数据,如图:

运行游戏测试

恭喜,基本的统计 SDK 已经接入完成!

如果您的项目是关卡类型游戏或者需要统计分析移动应用的具体页面数据,您可以继续接入 “关卡与页面”。

初次接入天梯游戏统计 SDK 建议开启调试信息输出接口 “setDebugLog

关卡与页面

关卡或页面开始 onSubStart
定义
void onSubStart (const char* name);
功能

进入一个关卡或页面

用法

在进入一个关卡或页面时,调用 onSubStart 接口

onSubStart 事件接口可以帮助统计系统获得关卡 新增用户,活跃用户,启动次数,进入次数,离开次数,滞留人数,最大关卡,最后关卡 等各种指标数据。如图:

onSubStart 实例图

页面可以嵌套,但不可以交叉

onSubStart 的第一个参数 stage 是关卡的名称,用版本号的形式,例如 “1”, “2”, “2.1”, “2.2”, … 。如果是字母开始的名称(例如:“MainScene”),将作为页面统计。

关卡或页面结束 onSubEnd
定义
void onSubEnd (const char* name);
功能

退出指定关卡或页面

用法

在退出一个关卡或页面时,调用 onSubEnd 接口

onSubEnd 必须与 onSubStart 匹配

onSubEnd 不能用 STAGE_LAST 参数,必须指定和对应 onSubStart 一样的关卡名称

关卡过关或失败 onPassFail
定义
void onPassFail (bool bPass);
功能

过关或失败

用法

关卡过关或失败时,立即调用 onPassFail 接口

onPassFail 在 onSubStart 与 onSubEnd 之间调用

onPassFail 事件接口可以帮助统计系统获得关卡的难度等各种细节信息,例如,过关时间,失败时间,难度 等数据

关卡过关失败数据对于分析关卡数据非常有意义,强烈建议开发者及时并正确调用 onPassFail 接口

关卡与页面子事件

所有子事件缺省都算在最后关卡中(STAGE_LAST)

如果需要把子事件计算到特定关卡或页面,请指定子事件中的 stage 参数

现金购买 onBuy
定义
void onBuy (const char* payService, const char* item, int count, float value, const char* stage = STAGE_LAST);
功能

现金购买虚拟币, onBuy 事件接口提交的数据,将作为收入数据,在后端报表中用各种收入图表展现。

用法

当用现金进行购买时,请调用 onBuy 事件接口

onBuy 事件缺省统计到最后关卡中,所以你可以看到各个关卡的各种与收入相关的数据,如,收入,新增付费用户,活跃付费用户,当天购买用户

payService: 支付服务类型,例如:支付宝, paypal, appstore, …

item: 购买的项目

count: 购买数量,通常是1

value: 购买总价

stage: 发生事件时的关卡位置,缺省为最后关卡(STAGE_LAST)

虚拟货币交易 onExchange
定义
void onExchange (const char* item, int count, const char* stage = STAGE_LAST);
功能

虚拟币兑换为道具

用法

数据分析人员可以观察到各个关卡的兑换次数,兑换项目等详细数据,以及各个数据的分布状况

item: 兑换的项目

count: 兑换数量,通常是1

stage: 发生事件时的关卡位置,缺省为最后关卡(STAGE_LAST)

道具使用 onUse
定义
void onUse (const char* item, int count, const char* stage = STAGE_LAST);
功能

使用道具或点数

item: 使用的物品(或点数)名称,例如道具名称

count: 使用的物品的数量

stage: 使用的位置,关卡或页面名称

收集 onCollect
定义
void onCollect (const char* item, int count, const char* stage = STAGE_LAST);
功能

收集点数/道具

item: 收集的物品(或点数)名称,例如道具名称

count: 收集的物品的数量

stage: 收集的位置,关卡或页面名称

奖励 onReward
定义
void onReward (const char* item, int count, const char* stage = STAGE_LAST);
功能

奖励虚拟币或道具

用法

发生奖励行为时,立即调用 onReward 接口

item: 奖励的物品(或点数)名称,例如道具名称

count: 奖励的物品的数量

stage: 奖励的位置,关卡或页面名称

分享 onShare
定义
void onShare (const char* service, const char* item, const char* stage = STAGE_LAST);
功能

分享到社交服务上

用法

当用户进行分享操作时,立即调用 onShare 事件接口

service: 分享服务的名称,例如,weibo, qq, weixin, …

item: 分享的项目名称

stage: 分享的位置,关卡或页面名称

产出与消耗(游戏平衡) onBalance
定义
void onBalance (const char* name, const char* item, int value, const char* stage = STAGE_LAST);
功能

游戏内虚拟货币的产出与消耗数据分析,通过产出与消耗可以观察游戏平衡情况。

用法

name 用 +,- 符号前缀,声明是产出或消耗。

玩家分享奖励: onBalance ("+宝石", "奖励", 100);

玩家购买时装: onBalance ("-宝石", "时装A", 200);

升级事件(玩家/角色/宠物) onLevelUp
定义
void onLevelUp (const char* name, const char* oldLevel, const char* newLevel, const char* stage = STAGE_LAST);
功能

玩家/角色/宠物的等级变化事件,统计玩家等级分布

用法

级别(oldLevel, newLevel)建议用版本号形式

自定义事件 onEvent
定义
void onEvent (const char* name, const char* stage = STAGE_LAST);
功能

用户自定义事件

用法

自定义事件将以列表形式罗列出来,并显示最近几天的自定义事件变化

自定义事件可以是一个简单的名称,例如 dm_show,也可以是包含 / 的多级名称,例如 main/dm_show, main/dm_close, …

对于 main/dm_show 形式的事件,在统计报表中将把所有 main/ 开头的时间一起对比显示。

所以如果想对比观察一组事件,可以给这些事件一个一样的分组名称作为前缀,并用 / 分隔。

事件列表:

onEvent 实例图

相同前缀的事件之间对比:

onEvent 实例图

在线参数

启用在线参数
定义
void enableOnlineConfig ();
功能

启用在线参数同步功能,缺省不启用在线参数功能

用法

在 init 接口后调用 enableOnlineConfig

在线参数在应用统计的后台管理,添加参数时可以指定当前参数的有效期。

客户端每次启动或者从后台切换到前台时自动更新在线参数,并且最小更新间隔为15分钟。

获取在线参数
定义
string getOnlineConfig (string key, string defaultValue="");
功能

获得某个在线参数的具体数据,如果没有指定,返回 defaultValue

用法

先调用 enableOnlineConfig,然后可以任意多次调用 getOnlineConfig

服务器可以指定在线参数的 key 和 数据,类型由客户端自己处理

服务器端可以指定在线参数的有效期,如果在有效期之外,相当于服务器没有定义该参数,返回缺省值

存量数据统计

清除存量数据
定义
void clearStatus();
功能

清除所有存量数据

在需要清除所有存量数据时调用
设置存量数据
定义
void setStatus(const char* key, int value, bool bAutoConvert = true);
功能

设置存量数据,服务器端将对存量数据自动分区间统计,或根据指定的区间统计

例如:玩家当前有多少宝石,用了多少宝石,收集了多少宝石等等这类长期累积的数据可以通过 setStatus 的接口统计。

用法

通常在 init 之后尽快调用 setStatus 接口,把客户端的累计存量数据汇报给服务器

存量数据每天第一次启动的时候提交到服务器

存量数据设置后会保存下来,下次启动如果没有更新,自动使用之前设置的数据,除非重新设置或clearStatus

通常在应用启动后,客户端持续存量数据加载后立即调用 AppLogger::setStatus 接口

持续状态变更时也立即调用 AppLogger::setStatus 接口

SDK 在每天第一次启动时自动同步数据到服务器,不会导致数据重复统计

开发者

启用错误统计
定义
void enableCrashReport();
功能

启用错误统计,捕捉应用中发生崩溃时的堆栈信息,用于定位程序中引起错误的代码,缺省为不启用崩溃统计

用法

在 init 接口之后调用 enableCrashReport

需要把其他统计服务的错误收集功能关闭,例如:

友盟:setCrashReportEnabled

TalkingData:setExceptionReportEnabled

日志输出设置
定义
void setDebugLog (int mode, int level);
功能

调试信息输出控制

用法

mode 与 level 具体定义:

							
#define DEBUG_OFF       0    //不输出调试信息
#define DEBUG_LOGCAT    1    //输出到 logcat(用于联机调试)
#define DEBUG_LOGFILE   2    //输出到 文件(applogger.log), 用于脱机调试
#define DEBUG_LOGALL    3    //输出到 logcat 和 文件(applogger.log)

#define DEBUG_LEVEL_VERBOSE    0    //输出所有级别调试信息
#define DEBUG_LEVEL_INFO       1    //输出INFO级别以上调试信息
#define DEBUG_LEVEL_WARN       2    //输出WARN级别以上调试信息
#define DEBUG_LEVEL_ERROR      3    //输出ERROR级别以上调试信息
					
开发者可以使用 AppDebug::info, AppDebug::warn, AppDebug::error 等接口输出调试信息到指定输出上

其他

启动间隔控制参数
定义
void setSessionInterval (int v);
功能

设置合并间隔,当上次退出时间与本次启动时间间隔小于该参数所指定的值时,合并上次与本次启动

为与其他统计工具保持一致,缺省情况下,在iOS 下间隔时间为0(不合并),Android 下间隔时间为30秒
联网控制
定义
void setOnline (bool online);
功能

一般仅用于小范围测试时(如,玩家输入邀请码才能进入游戏)。邀请码验证通过后,才算正常初始化 SDK

setOnline 接口应在初始化(init)之前调用。

启动时,调用 setOnline 接口设为 false,邀请码验证通过后,setOnline 设为 true。

玩家/用户参数
定义
void setUser (const char* level, int age = -1, const char* gender = NULL, const char* userId = NULL, const char* userService = NULL);
功能

设置用户信息,包括用户级别,年龄,性别, …

SDK 接口调用检查

						
onStart // 应用启动
    onSubStart // 关卡或页面的开始
        // 关卡中发生的事件
        onBuy, onUse, onEvent … 等事件接口
        onPassFail 关卡成功或失败
    onSubEnd // 关卡或页面的结束
    
    // 关卡外发生的事件
onEnd // 应用退出,Back按键强制退出调用onExit
					

onStart 通常在 Activity::onResume 中由开发者调用。

onEnd 通常在 Activity::onPause 中由开发者调用。

onSubStart, onSubEnd 表示一个关卡/页面的开始与结束,可以嵌套,但不能交叉

onSubStart 的第一个参数stage是关卡名称,用版本号的形式,例如 “1”, “2”, “2.1”, “2.2”, … 。如果是字母开始,作为页面。

如果通过 System.KillProcess 函数退出应用(双击Back按键退出应用),确保调用 onExit 接口。