Android SDK使用指南

本指南将会为您介绍如何使用 Android SDK 接入您的项目,您可以在访问 GitHub 获取 Android SDK 的源代码。

最新版本为: 2.6.0

更新时间为: 2020-08-24

1.初始化 SDK

1.1 自动集成 Android SDK

a) 使用 Gradle 集成

使用 Android Studio,在 App 工程目录下的 build.gradle 文件中添加依赖项,将会自动完成 SDK 集成:

注意:v2.1.0 版本更换了包名,老的包名同时可以使用,但后续不会又新特性的更新,请从老版本升级至新版本时注意调整包名

dependencies {
    implementation 'cn.thinkingdata.android:ThinkingAnalyticsSDK:2.6.0'
}

b) 使用集成自动采集功能(可选)

如果需要使用完整的自动采集功能(控件点击事件和 Fragment 浏览事件),请添加自动采集插件(可选):

apply plugin: 'cn.thinkingdata.android'

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'cn.thinkingdata.android:android-gradle-plugin:2.0.2'
    }
}

注意: 除控件点击事件和 Fragment 浏览事件之外,其他的自动采集事件不需要使用此插件

1.2 初始化SDK

在 v1.3.0 版本中,新增多 APP ID 实例的特性,添加了一种新的初始化方式,关于多 APP ID 的使用指南,请参考 Android SDK 多APPID指南一节

在应用程序的 Application 类的 onCreate 方法中调用


ThinkingAnalyticsSDK instance = ThinkingAnalyticsSDK.sharedInstance(mContext, TA_APP_ID, TA_SERVER_URL);

// 后续可以通过如下两种方法使用 SDK
instance.track("someevent");
ThinkingAnalyticsSDK.sharedInstance(this, TA_APP_ID).track("some_event");


// 1.3.0之前,或者单实例可使用下列方法初始化与使用 SDK
// ThinkingAnalyticsSDK.sharedInstance(this, TA_APP_ID);
// ThinkingAnalyticsSDK.sharedInstance(this).track("some_event");

参数 TA_APP_ID 是您的项目的 APP_ID,在您申请项目时会给出,请在此处填入

参数 TA_SERVER_URL 为数据上传的 URL

由于 Android 9.0+ 默认限制 HTTP 请求,因此请务必使用 HTTPS 协议

如果您使用的是云服务,请输入以下 URL:

https://receiver.ta.thinkingdata.cn

如果您使用的是私有化部署的版本,请为数据采集地址配置 HTTPS 证书,并使用以下 URL:

https://数据采集地址绑定域名

从 v2.3.0 开始,支持使用配置类 TDConfig 完成初始化。使用 TDConfig 可以对 SDK 的功能进行更多的个性化配置。

// 获取 TDConfig 实例
TDConfig config = TDConfig.getInstance(mContext, TA_APP_ID, TA_SERVER_URL);

// 初始化 SDK
ThinkingAnalyticsSDK instance = ThinkingAnalyticsSDK.sharedInstance(config);

a) 开启与 H5 页面的打通(可选)

如果需要与采集 H5 页面数据的 JavaScript SDK 进行打通,在初始化 WebView 时调用如下接口,详情请参考H5 与 APP SDK 打通一节

// 打通 H5 页面数据
instance.setJsBridge(webView);
// ThinkingAnalyticsSDK.sharedInstance(this, TA_APP_ID).setJsBridge(webView);

// 单实例的调用方法
// ThinkingAnalyticsSDK.sharedInstance(this).setJsBridge(webView);

2.设置用户ID

SDK 实例会使用随机 UUID 作为每个用户的默认访客 ID,该 ID 将会作为用户在未登录状态下身份识别 ID。需要注意的是,访客 ID 在用户重新安装 App 以及更换设备时将会变更。

a) 设置访客ID(可选)

如果您的 App 对每个用户有自己的访客 ID 管理体系,则您可以调用 identify 来设置访客 ID:

instance.identify("123456789ABCabc");
如果您需要替换访客 ID,则应当在初始化 SDK 结束之后立即进行调用,请勿多次调用,以免产生无用的账号

如果需要获得当前访客 ID,可以调用 getDistinctId 获取:

//返回访客 ID,多实例的情况下,返回的是调用实例的访客 ID
String distinctId = instance.getDistinctId();

b) 设置账号 ID

在用户进行登录时,可调用 login 来设置用户的账号 ID,在设置完账号 ID 后,将会以账号 ID 作为身份识别 ID,并且设置的账号 ID 将会在调用 logout 之前一直保留:

instance.login("1234567@thinkinggame.cn");

login 可以多次调用,每次调用会判断传入的账号 ID 与先前保存的 ID 是否一致,一致则忽略调用,不一致则会覆盖先前的 ID。

请注意,该方法不会上传用户登录的事件

c) 清除账号 ID

在用户产生登出行为之后,可调用 logout 来清除账号 ID,在下次调用 login 之前,将会以访客 ID 作为身份识别 ID:

instance.logout();

我们推荐您在显性的登出事件时调用 logout,比如用户产生了注销账号这一行为时才调用,而不需要在关闭 App 时调用。

请注意,该方法不会上传用户登出的事件

3.发送事件

在 SDK 初始化完成之后,您就可以调用 track 来上传事件,一般情况下,您可能需要上传十几到上百个不同的事件,如果您是第一次使用 TA 后台,我们推荐您先上传几个关键事件。

a)发送事件

您可以调用 track 来上传事件,建议您根据先前梳理的文档来设置事件的属性以及发送信息的条件,此处以用户购买某商品作为范例:

//商店购买事件
try {
    JSONObject properties = new JSONObject();
    properties.put("product_name","商品名");
    properties.put("product_num",1); 
    properties.put("Cost",100);  
    properties.put("isFirstBuy",true);
    instance.track("product_buy",properties);
} catch (JSONException e) {
    e.printStackTrace();
}

事件的名称是 String 类型,只能以字母开头,可包含数字,字母和下划线 "_",长度最大为50个字符,对字母大小写不敏感。

  • 事件的属性是一个 JSONObject 对象,其中每个元素代表一个属性。
  • Key的值为属性的名称,为 String 类型,规定只能以字母开头,包含数字,字母和下划线 "_",长度最大为 50 个字符,对字母大小写不敏感。
  • Value 为该属性的值,支持 StringNumberBooleanDateJSONArray. 对于 JSONArray 的元素,只支持字符串类型,对于其他类型都将强制转为字符串存储。

注意: JSONArray 类型在 v2.4.0 版本开始支持,需配合 TA 后台 v2.5 及后续版本使用.

在 v2.2.0 版本中加入了设置事件触发时间及时间偏移的方法重载,支持传入 Date 类型的参数来设置事件触发时间,以TimeZone 类型的参数来设置时间偏移。不传入该参数,则取 track 被调用时的本机时间以及偏移作为事件触发时间以及时区偏移:

try {
    JSONObject properties = new JSONObject();
    properties.put("product_name","商品名");
    properties.put("product_num",1);
    properties.put("Cost",100);
    properties.put("isFirstBuy",true);
    instance.track("product_buy", properties, new Date(), TimeZone.getDefault());
} catch (JSONException e) {
    e.printStackTrace();
}

注意: 尽管事件可以设置触发时间,但是接收端会做如下的限制,只接收相对服务器时间在前 10 天至后 3 天的数据,超过时限的数据将会被视为异常数据,整条数据无法入库。

自 v2.3.1 版本开始,您可以通过设置 SDK 默认时区的方式,对齐多个时区下的事件时间,请参考设置默认时区小节。自 v2.5.0 开始,您可以通过校准 SDK 时间接口来统一使用服务端时间完成数据采集,请参考校准时间小节

b)设置公共事件属性

对于一些重要的属性,譬如用户的会员等级、来源渠道等,这些属性需要设置在每个事件中,此时您可以将这些属性设置为公共事件属性。公共事件属性指的就是每个事件都会带有的属性,您可以调用 setSuperProperties 来设置公共事件属性,我们推荐您在发送事件前,先设置公共事件属性。

公共事件属性的格式要求与事件属性一致。

//设置公共事件属性
try {
    JSONObject superProperties = new JSONObject();
    superProperties.put("vip_level",2);
    superProperties.put("Channel","A1");
    instance.setSuperProperties(superProperties);
} catch (JSONException e) {
    e.printStackTrace();
}

//使用track上传事件,此时事件中会带有公共事件属性
try {
    JSONObject properties = new JSONObject();
    properties.put("product_id","A1354");
    instance.track("product_pay",properties);      
} catch (JSONException e) {
    e.printStackTrace();
}

//相当于在每个事件中加入这些属性
try {
    JSONObject properties = new JSONObject();
    properties.put("vip_level",2);
    properties.put("Channel","A1");
    properties.put("product_id","A1354");
    instance.track("product_pay",properties);      
} catch (JSONException e) {
    e.printStackTrace();
}

公共事件属性将会被保存到缓存中,无需每次启动 App 时调用。如果调用 setSuperProperties 上传了先前已设置过的公共事件属性,则会覆盖之前的属性。如果公共事件属性和 track 上传的某个属性的 Key 重复,则该事件的属性会覆盖公共事件属性:

//承接上个例子,此时的公共事件属性有 "Channel" 与 "vip_level"
try {
    JSONObject superProperties = new JSONObject();
    superProperties.put("Channel","B1");        //"Channel"被覆盖
    instance.setSuperProperties(superProperties);
} catch (JSONException e) {
    e.printStackTrace();
}

try {
    JSONObject properties = new JSONObject();
    properties.put("product_id","A1354");
    properties.put("vip_level",3);            //"vip_level"被覆盖
    instance.track("product_pay",properties);      
} catch (JSONException e) {
    e.printStackTrace();
}

//收到的数据中属性 "Channel" 的值为 "B1","vip_level" 的值为3

如果您需要删除某个公共事件属性,您可以调用 unsetSuperProperty 清除其中一个公共事件属性;如果您想要清空所有公共事件属性,则可以调用 clearSuperProperties

//清除一条公共事件属性,比如将之前设置 "Channel" 属性清除,之后的数据将不会该属性
instance.unsetSuperProperty("Channel");

//清除所有公共事件属性
instance.clearSuperProperties();

c) 设置动态公共属性

在 v1.3.0 版本中,新增了动态公共属性的特性,即公共属性可以上报时获取当时的值,使得诸如会员等级之类的可变公共属性可以被便捷地上报。通过 setDynamicSuperPropertiesTracker 设置动态公共属性类之后,SDK 将会在事件上报时自动获取 getDynamicSuperProperties 中的属性,并添加到触发的事件中。以下例子是每次上报时将时间加入到事件中,当事件触发时,就会将 getDynamicSuperProperties 的返回值加入到事件属性中。

// 设置动态公共属性,在事件上报时动态获取事件发生时刻
instance.setDynamicSuperPropertiesTracker(
    new ThinkingAnalyticsSDK.DynamicSuperPropertiesTracker() {   

        // 复写 getDynamicSuperProperties 来设置动态公共属性的属性值获取方法
        @Override
        public JSONObject getDynamicSuperProperties() {
            JSONObject dynamicSuperProperties = new JSONObject();
            String pattern = "yyyy-MM-dd HH:mm:ss.SSS";
            SimpleDateFormat sDateFormat = new SimpleDateFormat(pattern,Locale.CHINA);
            String timeString = sDateFormat.format(new Date());
            try {
                dynamicSuperProperties.put("dynamicTime", timeString);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return dynamicSuperProperties;
        }
    });

d) 记录事件时长

如果您需要记录某个事件的持续时长,可以调用 timeEvent 来开始计时,配置您想要计时的事件名称,当您上传该事件时,将会自动在您的事件属性中加入 #duration 这一属性来表示记录的时长,单位为秒。需要注意的是,同一个事件名只能有一个在计时的任务。

try {
    //用户进入商品页面,开始计时,记录的事件为 "Enter_Shop"
    instance.timeEvent("Enter_Shop");

    //设置事件属性,用户浏览的商品ID
    JSONObject properties = new JSONObject();
    properties.put("product_id","A1354");

    //上传事件,计时结束,"Enter_Shop" 这一事件中将会带有表示事件时长的属性 #duration
    instance.track("Enter_Shop",properties);
} catch (JSONException e) {
    e.printStackTrace();
}

4.用户属性

TA 平台目前支持的用户属性设置接口为 user_setuser_setOnceuser_adduser_unsetuser_deleteuser_append.

a) user_set

对于一般的用户属性,您可以调用 user_set 来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与传入属性的类型一致,此处以设置用户名为例:

try {
    JSONObject properties = new JSONObject();
    properties.put("UserName","ABC");
    instance.user_set(properties);
    //此时"UserName"为"ABC"

    JSONObject newProperties = new JSONObject();
    newProperties.put("UserName","abc");
    instance.user_set(newProperties);    
    //此时"UserName"为"abc"    

} catch (JSONException e) {
    e.printStackTrace();
}

user_set 设置的用户属性格式要求与事件属性保持一致。

b) user_setOnce

如果您要上传的用户属性只要设置一次,则可以调用 user_setOnce 来进行设置,当该属性之前已经有值的时候,将会忽略这条信息,以设置首次付费时间来为例:

try {
    JSONObject properties = new JSONObject();
    properties.put("FirstPaidTime","2018-01-01 01:23:45.678");
    instance.user_setOnce(properties);
    //此时"FirstPaidTime"为"2018-01-01 01:23:45.678"

    JSONObject newProperties = new JSONObject();
    newProperties.put("FirstPaidTime","2018-12-31 01:23:45.678");
    instance.user_setOnce(newProperties);    
    //此时"FirstPaidTime"仍然为"2018-01-01 01:23:45.678"   

} catch (JSONException e) {
    e.printStackTrace();
}

user_setOnce 设置的用户属性格式要求与事件属性保持一致。

c) user_add

当您要上传数值型的属性时,您可以调用 user_add 来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值,等同于相减操作。此处以累计付费金额为例:

try {
    JSONObject properties = new JSONObject();
    properties.put("TotalRevenue",30);
    instance.user_add(properties);
    //此时"TotalRevenue"为30

    JSONObject newProperties = new JSONObject();
    newProperties.put("TotalRevenue",648);
    instance.user_add(newProperties);    
    //此时"TotalRevenue"为678 

} catch (JSONException e) {
    e.printStackTrace();
}

user_add 设置的属性类型以及 Key 值的限制与 user_set 一致,但 Value 只允许 Number 类型。

d) user_unset

当您要清空用户的用户属性值时,您可以调用 user_unset 来对指定属性进行清空操作,如果该属性还未在集群中被创建,则 user_unset 不会创建该属性

// 重置单个用户属性
instance.user_unset("key1");

// 重置多个用户属性
instance.user_unset("key1", "key2", "key3");

// 重置多个用户属性,传入字符串数组
String[] keys = {"key1", "key2"};
instance.user_unset(keys);

user_unset 传入的参数是用户属性的属性名,类型是字符串或字符串数组,支持可变长参数的形式。

e) user_delete

如果您要删除某个用户,可以调用 user_delete 将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到。

instance.user_delete();

f) user_append

从 v2.4.0 开始,您可以调用 user_append 对 JSONArray 类型的用户属性进行追加操作。

try {
    // list 为用户属性 user_list 的值,JSONArray 类型
    JSONArray list = new JSONArray("[\"apple\", \"ball\"]");
    JSONObject properties = new JSONObject();
    properties.put("user_list", list);

    // 调用 user_append 为用户属性 user_list 追加元素。如果不存在,会新建该元素
    mInstance.user_append(properties);
} catch (JSONException e) {
    e.printStackTrace();
}

5. 自动采集事件(手动集成暂不支持此功能)

请注意,如需使用自动采集功能,请集成自动采集功能的相关依赖项,点此查看添加依赖代码

关于自动采集事件的具体使用方法,请参考 Android SDK 自动采集指南一章。

6. SDK 配置

本节描述与 SDK 配置有关的一些接口和选项。由于 SDK 本身是支持多个实例的,因此关于 SDK 的配置有些是针对所有实例的全局配置,有些是针对单个实例的配置,在使用时需要留意一下:

  • 全局配置:一般是通过 AndroidManifest.xml 进行配置,或者通过静态方法调用
  • 单个实例配置:通过调用该实例方法来配置

a) 设置上传的网络条件

在默认情况下,SDK 实例将会网络条件为在 3G, 4G 及 Wifi 时上传数据,您可以通过下列方法修改允许上传的网络条件:

//只在 Wifi 环境下上报数据
instance.setNetworkType(NETWORKTYPE_WIFI);

//在 3G, 4G, 5G 及 Wifi 时上传数据, 默认设置
instance.setNetworkType(NETWORKTYPE_DEFAULT);

//在 2G, 3G, 4G, 5G 及 Wifi 时上传数据
instance.setNetworkType(NETWORKTYPE_ALL);

b) 打印上传数据 Log

在 v1.1.7 版本,加入了打印 Log 的功能,您可以在 AndroidManifest.xml 中的 application 标签中添加以下代码开启打印 Log 功能(默认是关闭的):

<application...>
    .....
    <meta-data
        android:name="cn.thinkingdata.android.EnableTrackLogging"
        android:value="true" />
</application>

在 v2.0.0 版本,加入了打印 Log 的接口,您可以调用 enableTrackLog 来开启(默认是关闭的):

ThinkingAnalyticsSDK.enableTrackLog(true);

打开日志后,可以过滤 ThinkingAnalytics 相关的日志来观察 SDK 的数据上报。

c) 获取设备 ID

在 v2.0.0 版本,加入了获取设备 ID(也就是预置属性#device_id)的接口,您可以通过调用 getDeviceId 来获取设备ID:

 instance.getDeviceId();

 //如果需要将设备ID设置成访客ID可以如下调用
 //instance.identify(instance.getDeviceId());

d) 暂停/停止数据上报

在 v2.1.0 版本中,新增了停止 SDK 实例上报数据的功能,一共有两类停止 SDK 实例上报的接口:

1. 暂停 SDK 上报(enableTracking)

您可能希望在一些场景下,暂时停止数据采集以及上报,比如用户处于测试环境中、或者用户登录了一个测试账号,此时您可以调用下列接口,暂时停止 SDK 实例的上报。

您可以通过某一实例(包括主要实例以及轻实例)调用 enableTracking,传入 false 来暂停 SDK 实例的上报,该实例已经设置的 #distinct_id#account_id、公共属性等将保留;该实例已经采集但还未上报成功的数据将继续尝试上报;后续该实例不能采集以及上报任何新数据、不能设置访客 ID、账户 ID 以及公共属性等,但是可以读取该实例已经设置的公共属性和设备 ID、访客 ID、账号 ID 等信息。

实例的停止状态将会被保存在本地缓存,直到调用 enableTracking,传入 true,SDK 实例将会重新恢复数据采集以及上报,需要注意轻实例因为不进行缓存,因此每次打开 App 后,轻实例的暂停状态不会被保留,将重新开启上报。

// 暂停上报
instance.enableTracking(false);

// 恢复上报
instance.enableTracking(true);

2. 停止SDK上报(optOutTracking)

在一些特殊场景下,您可能需要完全停止 SDK 实例的功能,比如在适用 GDPR 的地区,用户选择不提供数据采集权限,则您可以调用如下接口完全关闭 SDK 实例的功能。

optOutTracking 只能通过主要实例调用,与 enableTracking 的最大区别在于,其将会清空该实例的本地缓存,包括本实例的访客 ID,账号 ID,公共属性,以及未上报的数据队列。之后再关闭该实例的采集和上报功能。

// 停止上报,并重置本地缓存
instance.optOutTracking();

如果您希望关闭SDK功能的同时,删除该用户在TA集群中的用户数据,可以调用 optOutTrackingAndDeleteUser,这将会在停止SDK实例的功能前,上报一条 user_del 数据,以删除该用户的用户数据。

// 停止上报,并发送删除用户请求
instance.optOutTrackingAndDeleteUser();

实例的停止状态也将保存在本地缓存,直到调用 optInTracking,后续可以继续上报,但此时相当于一个全新的实例

// 重新开启上报
instance.optInTracking();

e) 设置自签证书

从 v2.3.0 开始,SDK 允许传入自定义的 SSLSocketFactory 自定义证书验证。为了设置自签证书,需要在初始化的时候首先获取 TDConfig 实例,然后用 TDConfig 完成初始化。自签证书对该实例下的所有网络请求生效。

// 获取 TDConfig 实例
TDConfig config = TDConfig.getInstance(mContext, TA_APP_ID, TA_SERVER_URL);
// 设置自定义的 SSLSocketFactory
config.setSSLSocketFactory(sslSocketFactory);
// 初始化 SDK
instance = ThinkingAnalyticsSDK.sharedInstance(config);

f) 开启 Debug 模式

从 v2.3.0 开始,客户端 SDK 支持 Debug 模式,需要配合 TA 平台 2.5 之后的版本使用。

Debug 模式可能会影响数据采集质量和 App 的稳定性,只用于集成阶段数据验证,不要在线上环境使用。

当前 SDK 实例支持三种运行模式,在 TDConfig 中定义:

/**
 * 实例运行模式, 默认为 NORMAL 模式.
 */
public enum ModeEnum {
    /* 正常模式,数据会存入缓存,并依据一定的缓存策略上报 */
    NORMAL,
    /* Debug 模式,数据逐条上报。当出现问题时会以日志和异常的方式提示用户 */
    DEBUG,
    /* Debug Only 模式,只对数据做校验,不会入库 */
    DEBUG_ONLY
}

为了设置 SDK 实例运行模式,请使用 TDConfig 来完成 SDK 初始化:

// 获取 TDConfig 实例
TDConfig config = TDConfig.getInstance(mContext, TA_APP_ID, TA_SERVER_URL);
// 设置运行模式为 Debug 模式
config.setMode(TDConfig.ModeEnum.DEBUG);
// 初始化 SDK
instance = ThinkingAnalyticsSDK.sharedInstance(config);

为了避免 Debug 模式在生产环境上线,规定只有指定的设备才能开启 Debug 模式。只有在客户端开启了 Debug 模式,并且设备 ID 在 TA 后台的"埋点管理"页的"Debug数据"板块中配置了的设备才能开启 Debug 模式。

设备 ID 可以通过以下三种方式获取:

  • TA 平台中事件数据中的 #device_id 属性
  • 客户端日志:SDK 初始化完成后会打印设备 DeviceId
  • 通过实例接口调用:获取设备 ID

g) 设置默认时区

默认情况下,如果用户不指定事件发生时间,SDK 默认会使用接口调用时的本机时间作为事件发生时间上报。自 v2.3.1 开始,您也可以通过设置默认时区接口,指定默认的时区,这样所有的事件(包括自动采集事件)都将按照您设置的时区来对齐事件时间:

// 获取 TDConfig 实例
TDConfig config = TDConfig.getInstance(mContext, TA_APP_ID, TA_SERVER_URL);
// 设置默认时区为 UTC
config.setDefaultTimeZone(TimeZone.getTimeZone("UTC"));
// 初始化 SDK
instance = ThinkingAnalyticsSDK.sharedInstance(config);

注意:用指定时区对齐事件时间,会丢掉设备本机时区信息。如果需要保留设备本机时区信息,目前需要您自己为事件添加相关属性。

h) 校准时间

SDK 默认会使用本机时间作为事件发生时间上报,如果用户手动修改设备时间会影响到您的业务分析,自 v2.5.0 版本开始,您可以使用从服务端获取的当前时间戳对 SDK 的时间进行校准。此后,所有未指定时间的调用,包括事件数据和用户属性设置操作,都会使用校准后的时间作为发生时间。

// 1585633785954 为当前 unix 时间戳,单位为毫秒,对应北京时间 2020-03-31 13:49:45
ThinkingAnalyticsSDK.calibrateTime(1585633785954);

我们也提供了从 NTP 获取时间对 SDK 校准的功能。您需要传入您的用户可以访问的 NTP 服务器地址。之后 SDK 会尝试从传入的 NTP 服务地址中获取当前时间,并对 SDK 时间进行校准。如果在默认的超时时间(3 秒)之内,未获取正确的返回结果,后续将使用本地时间上报数据。

// 使用苹果公司 NTP 服务对时间进行校准
ThinkingAnalyticsSDK.calibrateTimeWithNtp("time.apple.com");

注意:

  • 您需要谨慎地选择您的 NTP 服务器地址,以保证网络状况良好的情况下,用户设备可以很快的获取到服务器时间。
  • 使用 NTP 服务进行时间校准存在一定的不确定性,建议您优先考虑用时间戳校准的方式。

除了以上校准时间接口外,在 v2.5.0 提供了所有用户属性接口的时间函数重载,您可以在调用用户属性相关接口时,传入 Date 对象,则系统会使用传入的 Date 对象来设定数据的 #time 字段。

i) 其他全局设置

SDK 可以通过 AndroidManifest.xml 修改部分全局设置,一般情况下,使用默认设置即可。

<!-- 打开调试日志 -->
 <meta-data
     android:name="cn.thinkingdata.android.EnableTrackLogging"
     android:value="true" />

 <!-- 设置数据库大小下限(默认 32 M) -->
 <meta-data
     android:name="cn.thinkingdata.android.MinimumDatabaseLimit"
     android:value="16" />

 <!-- 设置缓存数据保留天数(默认 15 天) -->
 <meta-data
     android:name="cn.thinkingdata.android.RetentionDays"
     android:value="7" />

 <!-- 允许安全退出服务(默认为 false) -->
 <meta-data
     android:name="cn.thinkingdata.android.EnableQuitSafely"
     android:value="true" />

 <!-- 开启安全退出服务时,等待每个线程(缓存, 网络)退出超时时长,默认 2000 ms -->
 <meta-data
     android:name="cn.thinkingdata.android.QuitSafelyTimeout"
     android:value="1000" />

7. 相关预置属性

7.1 所有事件带有的预置属性

以下预置属性,是Android SDK中所有事件(包括自动采集事件)都会带有的预置属性

属性名 中文名 说明
#ip IP地址 用户的IP地址,TA将以此获取用户的地理位置信息
#country 国家 用户所在国家,根据IP地址生成
#country_code 国家代码 用户所在国家的国家代码(ISO 3166-1 alpha-2,即两位大写英文字母),根据IP地址生成
#province 省份 用户所在省份,根据IP地址生成
#city 城市 用户所在城市,根据IP地址生成
#os_version 操作系统版本 iOS 11.2.2、Android 8.0.0等
#manufacturer 设备制造商 用户设备的制造商,如Apple,vivo等
#os 操作系统 如Android、iOS等
#device_id 设备ID 用户的设备ID,iOS取用户的IDFV或UUID,Android取androidID
#screen_height 屏幕高度 用户设备的屏幕高度,如1920等
#screen_width 屏幕宽度 用户设备的屏幕高度,如1080等
#device_model 设备型号 用户设备的型号,如iPhone 8等
#app_version APP版本 您的APP的版本
#lib SDK类型 您接入SDK的类型,如Android,iOS等
#lib_version SDK版本 您接入SDK的版本
#network_type 网络状态 上传事件时的网络状态,如WIFI、3G、4G等
#carrier 网络运营商 用户设备的网络运营商,如中国移动,中国电信等
#zone_offset 时区偏移 数据时间相对UTC时间的偏移小时数

7.2 自动采集事件的预置属性

以下预置属性,是各个自动采集事件中所特有的预置属性

  • APP启动事件(ta_app_start)的预置属性
属性名 中文名 说明
#resume_from_background 是否从后台唤醒 表示APP是被开启还是从后台唤醒,取值为true表示从后台唤醒,false为直接开启
  • APP关闭事件(ta_app_end)的预置属性
属性名 中文名 说明
#duration 事件时长 表示该次APP访问(自启动至结束)的时长,单位是秒
  • APP浏览页面事件(ta_app_view)的预置属性
属性名 中文名 说明
#title 页面标题 为控件所属Activity的标题,取值为Activitytitle属性的值
#screen_name 页面名称 为控件所属Activity的包名.类名
#url 页面地址 当前页面的地址,需要调用getScreenUrl进行url的设置
#referrer 前向地址 跳转前页面的地址,跳转前页面需要调用getScreenUrl进行url的设置
  • APP控件点击事件(ta_app_click)的预置属性
属性名 中文名 说明
#title 页面标题 为控件所属Activity的标题,取值为Activitytitle属性的值
#screen_name 页面名称 为控件所属Activity的包名.类名
#element_id 元素ID 控件的ID,默认使用android:id,可调用setViewID进行设置
#element_type 元素类型 控件的类型
#element_selector 元素选择器 为控件的viewPath的拼接
#element_position 元素位置 控件的位置信息,当控件存在position属性时才会上传
#element_content 元素内容 控件上的内容
  • APP崩溃事件(ta_app_crash)的预置属性
属性名 中文名 说明
#app_crashed_reason 异常信息 字符型,记录崩溃时的堆栈轨迹

7.3 其他预置属性

除了上述提到预置属性,还有部分预置属性需要调用对应接口才会被记录:

属性名 中文名 说明
#duration 事件时长 需要调用计时功能接口timeEvent,记录事件发生时长,单位是秒

8. 进阶功能

从 v2.6.0 开始,SDK 支持上报三种特殊类型事件: 首次事件、可更新事件、可重写事件。这三种事件需要配合 TA 系统 2.8 及之后的版本使用。由于特殊事件只在某些特定场景下适用,所以请在数数科技的客户成功和分析师的帮助下使用特殊事件上报数据。

8.1 首次事件

首次事件是指针对某个设备或者其他维度的 ID,只会记录一次的事件。例如在一些场景下,您可能希望记录在某个设备上第一次发生的事件,则可以用首次事件来上报数据。

// 示例:上报设备首次事件, 假设事件名为 DEVICE_FIRST
JSONObject properties = new JSONObject();
try {
    properties.put("INT_PROPERTY", 0);
} catch (JSONException e) {
    e.printStackTrace();
}


instance.track(new TDFirstEvent("DEVICE_FIRST", properties));

如果您希望以设备以外的其他维度来判断是否首次,则可以为首次事件设置 FIRST_CHECK_ID. 例如您需要记录某个账号的首次事件,可以将账号 ID 设置为首次事件的 FIRST_CHECK_ID:

// 示例:上报用户账号的首次事件, 假设事件名为 USER_FIRST
JSONObject properties = new JSONObject();
try {
    properties.put("INT_PROPERTY", 0);
} catch (JSONException e) {
    e.printStackTrace();
}

TDFirstEvent firstEvent = new TDFirstEvent("USER_FIRST", properties);
// 将用户 ID 设置为首次事件的 FIRST_CHECK_ID
firstEvent.setFirstCheckId("YOUR_ACCOUNT_ID");

instance.track(firstEvent);

注意:由于在服务端完成对是否首次的校验,首次事件默认会延时 1 小时入库。

8.2 可更新事件

您可以通过可更新事件实现特定场景下需要修改事件数据的需求。可更新事件需要指定标识该事件的 ID,并在创建可更新事件对象时传入。TA 后台将根据事件名和事件 ID 来确定需要更新的数据。

// 示例: 上报可被更新的事件,假设事件名为 UPDATABLE_EVENT
JSONObject properties = new JSONObject();
try {
    properties.put("status", 3);
    properties.put("price", 100);
} catch (JSONException e) {
    e.printStackTrace();
}

// 上报后事件属性 status 为 3, price 为 100
mInstance.track(new TDUpdatableEvent("UPDATABLE_EVENT", properties, "test_event_id"));


JSONObject properties_new = new JSONObject();
try {
    properties_new.put("status", 5);
} catch (JSONException e) {
    e.printStackTrace();
}

// 上报后事件属性 status 被更新为 5, price 不变
mInstance.track(new TDUpdatableEvent("UPDATABLE_EVENT", properties_new, "test_event_id"));

可更新事件默认会使用设备当前时间更新历史数据的事件时间,如果您希望指定事件时间,可以在上报可更新事件的时候,指定事件时间:

TDUpdatableEvent tdEvent = new TDUpdatableEvent("OVERWRITE_EVENT", properties, "test_event_id");

tdEvent.setEventTime(date, timeZone);
mInstance.track(tdEvent);

8.3 可重写事件

可重写事件与可更新事件类似,区别在于可重写事件会用最新的数据完全覆盖历史数据,从效果上看相当于删除前一条数据,并入库最新的数据。TA 后台将根据事件名和事件 ID 来确定需要更新的数据。

// 示例: 上报可被重写的事件,假设事件名为 OVERWRITE_EVENT
JSONObject properties = new JSONObject();
try {
    properties.put("status", 3);
    properties.put("price", 100);
} catch (JSONException e) {
    e.printStackTrace();
}

// 上报后事件属性 status 为 3, price 为 100
mInstance.track(new TDOverWritableEvent("OVERWRITE_EVENT", properties, "test_event_id"));


JSONObject properties_new = new JSONObject();
try {
    properties_new.put("status", 5);
} catch (JSONException e) {
    e.printStackTrace();
}

// 上报后事件属性 status 被更新为 5, price 属性被删除
mInstance.track(new TDOverWritableEvent("OVERWRITE_EVENT", properties_new, "test_event_id"));

可重写事件默认会使用设备当前时间重写历史数据的事件时间,如果您希望指定事件时间,可以在上报可重写事件的时候,指定事件时间:

TDOverWritableEvent tdEvent = new TDOverWritableEvent("OVERWRITE_EVENT", properties, "test_event_id"

tdEvent.setEventTime(date, timeZone);
mInstance.track(tdEvent);

ChangeLog

v2.6.0 2020/08/24

  • 支持首次事件, 允许传入自定义的 ID 校验是否首次上报
  • 支持可更新、可重写的事件

v2.5.6 2020/06/28

  • 优化代码: 避免极端情况下,在开启自动采集时出现的空指针异常

v2.5.5 2020/06/22

  • 修复部分情况下延迟初始化造成首次启动事件无法采集的问题
  • 新增预置属性 #system_language
  • 优化部分预置属性取值逻辑,无值时不传
  • 优化部分代码和日志打印

v2.5.4 2020/05/19

  • 为适配 Unity 2018.04 增加接口

v2.5.3 2020/05/14

  • 适配TA 后台 2.7 版本屏蔽事件配置接口
  • 调整 DEBUG 模式,去除客户端抛异常逻辑
  • 默认关闭 QuitSafelyService

v2.5.2 2020/04/29

  • 修复用户属性中时间类型格式化的问题.

v2.5.1 2020/04/14

  • 修复 DEBUG 模式下事件上报的 BUG.

v2.5.0 2020/04/03

  • 支持客户端 SDK 的时间校准功能
  • 新增指定时间的用户属性设置接口

v2.4.3 2020/03/06

  • 优化启动事件,在延迟初始化的情形下,保证安装事件先于启动事件发生

v2.4.2 2020/03/06

  • 解决在第一个 Activity 展示之前初始化 SDK 时 ta_app_start 不准确

v2.4.1 2020/03/04

  • 解决在第一个 Activity 停止之后初始化 SDK 引发的前后台判断错误问题

v2.4.0 2020/02/10

  • 支持 JSONArray 类型
  • 支持 user_append 接口
  • 去除客户端的属性格式检查

v2.3.1 2020/01/07

  • 支持设置数据的默认时区

v2.3.0 2019/12/31

  • 支持 Debug 模式: 需配合后台 Debug 设备白名单一起开启(v2.5 版本开始支持)
  • H5 与原生 SDK 打通支持多实例
  • 优化 SDK 配置: 增加全局设置;上报策略允许针对不同项目配置;支持向多个集群发送数据
  • 支持自签证书: 允许传入 SSLSocketFactory 自定义认证过程
  • 其他优化:
    • 优化安全退出逻辑,避免出现 ANR
    • 去除对字符串类型的数据的长度限制

v2.2.2 2019/11/04

  • 修复当API level小于18(Android 4.3)时,退出异常

v2.2.0 2019/10/22

  • 支持重置用户属性接口user_unset
  • 新增track接口重载,支持按照指定时区上传事件数据
  • 新增预制属性#zone_offset,单位为小时。 默认情况下会将本地时区的偏移上报到服务端,该时间偏移会受夏令时影响。满足如下公式:
    utc_time + #zone_offset = #event_time
    

v2.1.0 2019/08/31

  • 支持轻量级实例, 便于上报被动事件等需求
  • 新增 enableTracking 接口, 可以打开或关闭实例上报功能
  • 新增 optOutTracking/optInTracking 接口
  • 优化上报逻辑,改进上报的频率和时效性
  • 其他一些小的改进点

v2.0.1 2019/07/12

  • 支持 H5 与自动采集事件新增APP安装事件

v2.0.0 2019/07/10

  • 重构自动采集逻辑(需要配合 2.0 版本的插件编译):
    • 去除 SDK 的第三方库依赖
    • Fragment 浏览事件不再需要继承 BaseFragment, 并加注解
    • 新增 TimePickerDatePicker 等控件的点击事件采集
  • 新增 getDeviceId() 接口
  • 自动采集事件新增APP安装事件
  • 优化属性检测逻辑:当字符串类型的数据超出2048字节时,会自动截断并上传
  • 优化日志打印,更方便集成阶段的埋点测试
  • 针对提升SDK稳定性和运行效率的其他代码优化
  • minSdkVersion 升到 14

v1.3.0 2019/06/18

  • 新增多APPID实例功能
  • 新增动态公共属性特性
  • 自动采集事件新增APP崩溃事件
  • 稳定性提升:适配 Android Q、去除非必须的权限申请、优化运营商获取逻辑、支持 5G 等

v1.2.0 2019/05/23

  • 支持 H5 与 APP 打通
  • 支持 androidx (需配合自动采集插件 1.2.0 之后的版本)
  • 优化部分代码逻辑

v1.1.7 2019/01/08

  • 增加了上报数据的Log打印功能

results matching ""

    No results matching ""