1. 用户关联

用户关联是为了对用户进行唯一标识,提高用户行为分析的准确性。目前神策提供了简易用户关联和全域用户关联分为用于支撑不同的业务场景。

2. 用户属性

2.1. 设置用户属性

profileSet() 方法可以设置用户属性,同一个 key 多次设置时,value 值会进行覆盖替换:

SensorsDataAPI.sharedInstance().profileSet("Adsource", "userSource");
CODE

2.2. 记录初次设定的用户属性

对于只在首次设置时有效的属性,我们可以使用 profileSetOnce() 记录这些属性。与 profileSet() 方法不同的是,如果被设置的用户属性已存在,则这条记录会被忽略而不会覆盖已有数据,如果属性不存在则会自动创建。因此,profileSetOnce() 适用于为用户设置首次激活时间、首次注册时间等属性。例如:

try {
    JSONObject properties = new JSONObject();
    properties.put("AdSource", "XXX Store");

    // 设定用户渠道为,"developer@sensorsdata.cn" 的 "AdSource" 属性值为 "XXX Store"
    SensorsDataAPI.sharedInstance().profileSetOnce(properties);

    JSONObject newProperties = new JSONObject();
    newProperties.put("AdSource", "Email");

    // 再次设定用户渠道,设定无效,"developer@sensorsdata.cn" 的 "AdSource" 属性值仍然是 "XXX Store"
    SensorsDataAPI.sharedInstance().profileSetOnce(newProperties);
} catch (JSONException e) {
    e.printStackTrace();
}
CODE

2.3. 数值类型的属性

对于数值型的用户属性,可以使用 profileIncrement() 对属性值进行累加。常用于记录用户付费次数、付费额度、积分等属性。例如:

// 将用户游戏次数属性增加一次
SensorsDataAPI.sharedInstance().profileIncrement("GamePlayed", 1);

// 增加用户付费次数和积分
Map<String, Number> properties = new HashMap<String, Number>();
properties.put("UserPaid", 1);
properties.put("PointEarned", 12.5);

SensorsDataAPI.sharedInstance().profileIncrement(properties);
CODE

2.4. 列表类型的属性

对于用户喜爱的电影、用户点评过的餐厅等属性,可以记录列表型属性,例如:

Set<String> movies = new HashSet<String>();
movies.add("Sicario");
movies.add("Love Letter");

// 设定用户观影列表属性,设定后属性 "Movies" 为: ["Sicario", "Love Letter"]
SensorsDataAPI.sharedInstance().profileAppend("Movies", movies);
CODE

需要注意的是,列表型属性中的元素必须为 String 类型。关于列表型限制请见数据格式

2.5. 属性取消

如果需要取消已设置的某个用户属性,可以调用 profileUnset() 进行取消:

SensorsDataAPI.sharedInstance().profileUnset("age");
CODE

3. 埋点事件采集

在 SDK 初始化完成之后,您可以通过以下接口进行数据埋点。

3.1. 代码埋点追踪事件

SDK 初始化后,可以通过 track() 方法追踪用户行为事件,并为事件添加自定义属性。

try {
    JSONObject properties = new JSONObject();
    properties.put("ProductID", 123456);                    // 设置商品 ID
    properties.put("ProductCatalog", "Laptop Computer");    // 设置商品类别
    SensorsDataAPI.sharedInstance().track("BuyProduct", properties);
} catch (JSONException e) {
    e.printStackTrace();
}
CODE

事件名和事件属性的格式规范,请参考数据格式

3.2. 埋点事件采集时长属性

可以通过计时器统计事件的持续时间。首先,在事件开始时调用(v1.10.6 及以后版本支持) trackTimerStart("Event") ,该方法并不会真正发送事件;在事件结束时,调用 trackTimerEnd("Event", properties),SDK 会触发 "Event" 事件,并自动将事件持续时间记录在事件属性 "$event_duration" 中。例如记录用户浏览商品页面的时间:

// 进入商品页面
// 调用 trackTimerStart("ViewProduct") 标记事件启动时间
SensorsDataAPI.sharedInstance().trackTimerStart("ViewProduct");

// ... 用户浏览商品

// 离开商品页
try {
  // 在属性中记录商品 ID
  JSONObject properties = new JSONObject();
  properties.put("product_id", PRODUCT_ID);
  // 调用 track,记录 ViewProduct 事件,并在属性 event_duration 中记录用户浏览商品的时间
  SensorsDataAPI.sharedInstance().trackTimerEnd("ViewProduct", properties);
} catch (JSONException e) {
  e.printStackTrace();
}
CODE

多次调用 trackTimerStart("Event") 时,事件 "Event" 的开始时间以最后一次调用时为准。注意务必确保 trackTimerStart 和 trackTimerEnd 接口配对使用,多次调用 trackTimerEnd 会触发无时长的埋点事件。

v3.1.5 版本开始,统计事件时长支持暂停和恢复,通过调用 trackTimerPause(String eventName) 和 trackTimerResume(String eventName) 来分别实现暂停和恢复。如果需要清空已记录的时长事件则调用 clearTrackTimer() 接口。

3.2.1. 同名事件交叉的时长统计

默认情况下,时长的统计以事件名作为标识,相同的事件名会自动匹配 start-end,如果两个同名事件在时间上有交叉部分,会造成错误匹配。为了解决此问题,从 v3.2.11 版本开始 SDK 支持同名事件交叉的时长统计,开发者需要保存 trackTimerStart() 的返回值,以便后续针对性地进行暂停、恢复或停止。

注意务必确保 trackTimerStart 和 trackTimerEnd 接口配对使用,多次调用 trackTimerEnd 会触发无时长的埋点事件。该功能请使用 v6.5.5 及以上版本,低版本未成对使用时会出现异常事件。

// 开始第一个事件计时
String timer1 = SensorsDataAPI.sharedInstance().trackTimerStart("testTimer");

// 开始第二个事件计时
String timer2 = SensorsDataAPI.sharedInstance().trackTimerStart("testTimer");

//如果需要暂停第一个事件计时
SensorsDataAPI.sharedInstance().trackTimerPause(timer1);

//如果需要恢复第一个事件计时
SensorsDataAPI.sharedInstance().trackTimerResume(timer1);

// 结束第一个事件计时
SensorsDataAPI.sharedInstance().trackTimerEnd(timer1);

// 结束第二个事件计时
SensorsDataAPI.sharedInstance().trackTimerEnd(timer2);
CODE

3.3. 采集页面浏览时长

版本要求

  • Android  SDK v6.6.6 及以上版本
  • Android 插件 v3.5.2 及以上版本

SDK 支持自动采集在离开页面时发送页面离开事件($AppPageLeave)来采集页面浏览时长,通过 SAConfigOptions  实例的 enableTrackPageLeave(boolean, boolean) 接口开启页面浏览时长事件采集:

  • 第一个参数表示是否采集 Activity 页面离开事件
  • 第二个参数表示是否采集 Fragment 页面离开事件
// 传入 true, true 代表开启 Activity 和 Fragment 页面离开事件采集
saConfigOptions.enableTrackPageLeave(true, true);
// 若想只采集 Activity,单独关闭 fragment 页面离开采集
saConfigOptions.enableTrackPageLeave(true, false)
CODE

如果需要忽略指定页面的浏览时长采集,则通过 SAConfigOptions 实例的 ignorePageLeave(List<Class>) 来进行忽略。

configOptions.ignorePageLeave(Arrays.asList(TestMainActivity.class, FragmentActivity.class));
CODE

开启页面浏览时长采集会采集 $AppPageLeave  事件,并且在该事件中记录页面浏览时长。

对于 v6.4.3 ~ v6.6.5 之间的版本页面浏览时长功能无法与 disableSDK  接口混合使用,必须要升级到 v6.6.6 以上版本使用。

单独关闭 Fragment 的采集版本需要使用 v6.6.6 以上版本

3.4. 物品元数据上报

3.4.1. 设置物品属性

直接设置一个物品,如果已存在则覆盖。除物品 ID 与物品所属类型外,其他物品属性需在 properties 中定义。物品属性中,属性名称与属性值的约束条件与事件属性相同,详细说明请参考 数据格式

// 为物品类型为 itemType 且物品 ID 为 itemId 的物品,设置物品属性 properties
SensorsDataAPI.sharedInstance().itemSet(String itemType, String itemId, JSONObject properties);
CODE

3.4.2. 删除物品属性

如果物品不可被推荐需要下线,删除该物品即可,如不存在则忽略。除物品 ID 与 物品所属类型外,不解析其他物品属性。

// 删除物品,类型为 itemType,ID 为 itemId
SensorsDataAPI.sharedInstance().itemDelete(String itemType, String itemId);
CODE

4. 事件属性

在进行埋点事件追踪时,您可以根据需求对埋点事件进行属性的定义。目前 SDK 中提供了公共属性用于给每个埋点事件添加属性,同时公共属性又分为静态公共属性和动态公共属性。静态公共属性用于设置更新频率较低的属性,动态公共属性用于设置更新频率高的属性。当同一事件中出现相同 Key 的属性时,SDK 覆盖优先级:预置属性 < 静态公共属性 < 动态公共属性 < 自定义属性。

4.1. 获取预置属性

v1.8.17 及以后的版本可以调用 getPresetProperties() 方法获取预置属性。服务端埋点需要 App 端的一些预置属性时,可以通过此方法获取 App 端的预置属性,再传给服务端。

//获取预置属性
JSONObject presetProperties=SensorsDataAPI.sharedInstance().getPresetProperties();
CODE

4.2. 静态公共属性

静态公共属性是指对于所有事件都需要添加的属性,初始化 SDK 后,可以通过 registerSuperProperties() 将属性注册为静态公共属性。设置方法如下:

// 将应用名称作为事件公共属性,后续所有 track 类型的事件都会自动带上 "AppName" 属性
try {
    JSONObject properties = new JSONObject();
    properties.put("AppName", getAppName(this));
    SensorsDataAPI.sharedInstance().registerSuperProperties(properties);
} catch (JSONException e) {
    e.printStackTrace();
}
CODE

可以通过 SensorsDataAPI.sharedInstance().getSuperProperties() 来获取已经设置的公共属性。

  • 注册的静态公共属性可以通过 unregisterSuperProperty(String key) 方法删除指定 key 的静态公共属性。
  • 对于延迟初始化场景,触发的 $AppStart 事件会出现无法带上静态公共属性的问题,需要使用高级功能中的属性插件化设置属性。

4.3. 设置动态公共属性

动态公共属性是指对于所有事件都需要添加的动态属性。Android SDK v2.0.1 及以后的版本可以通过 registerDynamicSuperProperties() 方法设置动态公共属性,设置之后 SDK 会每次触发埋点时自动获取 getDynamicSuperProperties() 中的属性添加到触发的事件中。

// 初始化 SDK 后,设置动态公共属性
SensorsDataAPI.sharedInstance().registerDynamicSuperProperties(new SensorsDataDynamicSuperProperties() {
    @Override
    public JSONObject getDynamicSuperProperties() {
        try {
            // 比如 isLogin() 是用于获取用户当前的登录状态,SDK 会自动获取 getDynamicSuperProperties 中的属性添加到触发的事件中。
            boolean bool = isLogin();
            return new JSONObject().put("isLogin",bool);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
});
CODE

调用 registerDynamicSuperProperties() 方法设置的动态公共属性,不能用 unregisterSuperProperty() 方法删除。

5. 数据存储与发送

需要更精细地控制神策分析 SDK 的数据存储和上报可以通过以下选项设置。

5.1. 数据 flush 上报

在每次调用 track()login()profileSet() 等方法时,神策分析 SDK 会将埋点事件保存在数据库中,并会检查如下条件,以判断是否向服务器上传数据:

  1. 是否是 WIFI/2G/3G/4G/5G 网络条件
  2. 是否满足发送条件之一:
    1. 与上次发送的时间间隔是否大于 flushInterval
    2. 本地缓存日志数目是否大于 flushBulkSize
    3. 事件类型为 login() 方法触发的 $SignUp 事件

默认的 flushBulkSize 为 100 条,默认的 flushInterval 为 15 秒。满足条件后,神策分析 SDK 会将数据 gzip 压缩后,批量发送到神策分析。

如果追求数据采集的时效性,可以调用 flush() 方法,强制将数据发送到神策分析,例如:

// 记录用户登录事件
SensorsDataAPI.sharedInstance().track("UserLogin");

// 强制发送数据
SensorsDataAPI.sharedInstance().flush();
CODE

在 App 进入后台状态或监听到网络切换有网络时,SDK 会调用 flush() 方法,将缓存的数据发送到神策分析。

5.2. 设置发送数据的网络策略

默认情况下,在 WIFI/3G/4G/5G 网络条件下,SDK 都会尝试去同步数据。v1.7.2 及以后的版本支持可以自定义同步数据的网络策略。通过 SAConfigOptions.setNetworkTypePolicy() 或 SensorsDataAPI.setFlushNetworkPolicy() 方法来指定发送数据的网络策略。例如:

//网络模式选项
//SensorsDataAPI.NetworkType.TYPE_2G     2G网络下发送数据
//SensorsDataAPI.NetworkType.TYPE_3G     3G网络下发送数据
//SensorsDataAPI.NetworkType.TYPE_4G     4G网络下发送数据
//SensorsDataAPI.NetworkType.TYPE_5G     5G网络下发送数据
//SensorsDataAPI.NetworkType.TYPE_WIFI   WIFI网络下发送数据
//SensorsDataAPI.NetworkType.TYPE_ALL    2G/3G/4G/5G/WIFI网络下发送数据
//SensorsDataAPI.NetworkType.TYPE_NONE   所有网络下都不发送数据

//指定只在 3G/4G/WIFI 条件下发送数据。
SensorsDataAPI.sharedInstance().setFlushNetworkPolicy(SensorsDataAPI.NetworkType.TYPE_3G|SensorsDataAPI.NetworkType.TYPE_4G|SensorsDataAPI.NetworkType.TYPE_WIFI);
CODE

5.3. 设置本地缓存上限值

SDK 本地数据库默认缓存数据的上限值为 32MB。 v1.7.4 及以后的版本支持通过 setMaxCacheSize() 方法来设定缓存数据的上限值。参数单位 byte

SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
//设置本地数据缓存上限值为16MB
saConfigOptions.setMaxCacheSize(16 * 1024 * 1024);
CODE

v3.1.0 及之前的版本,设置缓存方式: 

//设置本地数据缓存上限值为16MB
SensorsDataAPI.sharedInstance().setMaxCacheSize(16 * 1024 * 1024);
CODE

当存储数量达到上限值,会依次丢弃老数据,保留最新的数据

5.4. 设置事件发送间隔

连续触发埋点事件时,埋点数据发送的间隔默认为 15s。SDK 提供接口 SAConfigOptions.setFlushInterval(int) (v3.1.0 及以上支持)和 SensorsDataAPI.setFlushInterval(int) 用于自定义设置埋点事件发送间隔。 单位毫秒。最小值为 5s。

SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
// 设置每 30 秒发送一次
saConfigOptions.setFlushInterval(30000);
CODE

同时也支持通过 <meta-data> 项设置。

<application>
    <meta-data
        android:name="com.sensorsdata.analytics.android.FlushInterval"
        android:value="30000" />
</application>
CODE

5.5. 设置事件缓存条数

默认本地埋点数据缓存为 100 条。当埋点事件触发时,如果当前本地缓存埋点事件条数不低于设置的缓存条数大小,则会立即触发埋点数据发送,无需等待间隔 15s。

SDK 提供接口 SAConfigOptions.setFlushBulkSize(int) (v3.1.0 及以上支持)和 SensorsDataAPI.setFlushBulkSize(int) 用于自定义设置埋点事件发送间隔。最小值 50 条。

SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
// 设置缓存大小
saConfigOptions.setFlushBulkSize(100);
CODE

同时也支持通过 <meta-data> 项设置。

<application>
    <meta-data
        android:name="com.sensorsdata.analytics.android.FlushBulkSize"
        android:value="100" />
</application>
CODE

5.6. 清空本地缓存事件

v3.1.5 及以后的版本可以通过 deleteAll() 方法,删除 App 本地存储的所有事件。

如果不是特殊要求,请不要调用此方法。

//删除 App 本地存储的所有事件
SensorsDataAPI.sharedInstance().deleteAll();
CODE

5.7. 设置自签证书

v3.1.2 及以后的版本可以通过 setSSLSocketFactory() 方法设置自签证书,设置自签证书后,SDK 内所有的 HTTPS 请求会进行此接口设置的证书校验。以 DER 格式的证书为例:

try {
    //构建 SSLSocketFactory 实例
    SSLSocketFactory sslSocketFactory ;
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    // 其中 R.raw.ca 是您这边自签证书的公钥
    InputStream in = getResources().openRawResource(R.raw.ca);
    Certificate ca = cf.generateCertificate(in);
    try {
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
    keystore.load(null, null);
    keystore.setCertificateEntry("ca", ca);
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keystore);
    // Create an SSLContext that uses our TrustManager
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, tmf.getTrustManagers(), null);
    sslSocketFactory = sslContext.getSocketFactory();    
    //将实例传入神策
    SAConfigOptions configOptions = new SAConfigOptions(SA_SERVER_URL);
    configOptions.setAutoTrackEventType(SensorsAnalyticsAutoTrackEventType.APP_START |
                SensorsAnalyticsAutoTrackEventType.APP_END |
                SensorsAnalyticsAutoTrackEventType.APP_VIEW_SCREEN |
                SensorsAnalyticsAutoTrackEventType.APP_CLICK)
                .setSSLSocketFactory(sslSocketFactory)
   SensorsDataAPI.startWithConfigOptions(this, configOptions); 
 }
 catch (Exception e) {
    e.printStackTrace();
}
CODE

关于 SSL 的更多内容可以参考 Android 使用文档

6. SDK 加密

介绍 SDK 提供的埋点数据加密功能和缓存数据加密功能。埋点数据加密功能指对于采集的埋点数据进行加密,以密文的方式存储在 SQLite 数据库中。缓存数据加密指对于 SDK 存储的标志位等信息进行加密,包含 SharedPreferences、File 存储的信息。

6.1. 缓存数据加密

SDK 提供对缓存中的内容进行加密,要求使用版本:Android SDK v6.8.3 及以上,同时需开发者主动开启。

SDK 中默认使用 AES 加密方式,AES 128 偏移 16 位。在 SDK 初始化时调用 registerStorePlugin 接口注册预置加密插件即可开启。参照如下代码即可开启加密:

SAConfigOptions configOptions = new SAConfigOptions("数据接收地址");
//注册插件
configOptions.registerStorePlugin(new SAEncryptStorePlugin(this));
SensorsDataAPI.startWithConfigOptions(this, configOptions);
CODE

如果对加密方式有要求,神策默认加密无法满足需求,可以实现自定义加密,自定义加密方式可以咨询 SDK 值班同学。

一旦实现合规加密或者自定义加密,加密数据将无法恢复到未加密数据。

6.2. 埋点数据加密

为了加强埋点数据的安全性,神策分析支持对埋点数据进行加密,并以密文的形式对数据进行存储和发送。

注意:

  • 本功能需要服务端的配合,可以联系神策客户成功/项目经理协助开通服务端解密功能。默认使用 RSA 类型的秘钥,可指定使用 EC 类型秘钥。
  • 加密开启后切换到非加密情况时,本地遗留的加密数据后端无法解析入库。

6.2.1. SDK 开启埋点加密

对于 v4.2.0+ 版本 SDK,进行如下配置,即可开启 SDK 的埋点加密功能,埋点加密会将埋点数据加密后进行存储,然后进行上报。

// 开启加密
configOptions.enableEncrypt(true);
CODE

对于 v4.4.0+ 版本的 SDK 开始支持 EC 算法加密。在使用 enableEncrypt() 开启加密的基础上添加如下依赖,即可切换到 EC 算法加密:

dependencies {
   // 添加 EC 算法库依赖
   implementation 'com.sensorsdata.provider:SensorsAnalyticsProvider:0.0.3'
}
CODE

注意

SensorsAnalyticsProvider 封装了支持 Android 系统的 v1.58.0.0 版本的 EC 算法库(您也可以从 GitHub 上集成此库),该库大小为 5MB 左右。同时该仓库中包含众多方法,对于大型项目,可能会遇到方法数超过 64K 的问题,需要参照 Android 官方配置文档开启 multiDexEnabled 配置项

6.2.2. 加密密钥的验证

使用此功能前,确保您的 App 中配置了当前项目的 Scheme,详细操作可参考配置 scheme

在神策分析平台中,进入密钥管理功能,进入路径:更多 > 基本设置 > 数据接入 > 密钥管理。

点击「密钥管理」按钮进入密钥管理页面

点击对应密钥的二维码图标,用浏览器扫描二维码打开 App 进行密钥验证。

  • 验证一致,则 App 端提示 "密钥验证通过,所选密钥与 App 端密钥相同"
  • 验证不一致:则 App 端提示 “密钥验证不通过,所选密钥与 App 端密钥不相同。所选密钥版本:v1,App 端密钥版本:v2”
  • 如果本地密钥为空:则 App 端提示 “密钥验证不通过,App 端密钥为空”
  • 如果扫码密钥为空:则 App 端提示 “密钥验证不通过,所选密钥无效”

7. 全埋点

全埋点是指 $AppStart(App 启动)、$AppEnd(App 退出)、$AppViewScreen(浏览页面) 和 $AppClick(控件点击) 四种事件。针对 App 启动和退出,神策 SDK 为了应对多进程、强杀等场景,在 v2.0.3 版本加入了 30 秒的 session 机制,用户退出 App 到后台 30 秒的时候,才会触发退出事件,之后再启动 App,才会触发启动事件,用户如果在 30 秒内打开了 App,那么是没有对应的退出事件与启动事件的。另外,如果在退出 App 到后台 30 秒内,进程还没有被杀掉,那么此时会触发退出事件并尝试上报,如果进程被杀掉了,那么退出事件会在下一次启动时补发。所以在查看数据时,一般退出事件比启动事件少。

7.1. 开启全埋点

SDK 可以自动采集一些用户行为,如 App 启动、退出、浏览页面、控件点击。通过 enableAutoTrack() 方法可以配置需要开启的全埋点类型:

// 可根据需求,自由组合
List<SensorsDataAPI.AutoTrackEventType> list = new ArrayList<>();
list.add(SensorsDataAPI.AutoTrackEventType.APP_START);
list.add(SensorsDataAPI.AutoTrackEventType.APP_END);
list.add(SensorsDataAPI.AutoTrackEventType.APP_VIEW_SCREEN);
list.add(SensorsDataAPI.AutoTrackEventType.APP_CLICK);
SensorsDataAPI.sharedInstance().enableAutoTrack(list);
CODE

App 启动、App 退出的全埋点事件采集要求系统最低版本为 API 14 (Android 4.0)。

7.1.1. 开启 Fragment 页面浏览事件

v1.7.10 开始,通过 trackFragmentAppViewScreen() 方法可以开启全部 Fragment 页面浏览事件的自动采集功能:

// 开启自动采集 Fragment 页面浏览事件
SensorsDataAPI.sharedInstance().trackFragmentAppViewScreen();
CODE

开启 Fragment 页面浏览事件后,通过 enableAutoTrackFragment() 方法可以指定只采集某些 Fragment 页面的信息:

// 只采集 HomeFragment 页面的浏览事件
SensorsDataAPI.sharedInstance().enableAutoTrackFragment(HomeFragment.class);
CODE

7.2. 全埋点事件采集控制

对于全埋点中的 App 页面浏览和 App 元素点击,在开启全埋点后,SDK 支持通过配置忽略部分页面或控件的采集,并且提供了手动触发全埋点事件的方法。部分特殊的全埋点事件在开启全埋点后,仍需调用额外的方法去打开采集。

7.2.1. 忽略全埋点事件

v2.0.0 开始,通过 disableAutoTrack(AutoTrackEventType) 和 disableAutoTrack(List<AutoTrackEventType>) 方法可以忽略指定类型的全埋点事件。同时对于忽略的全埋点事件可以通过 enableAutoTrack(List<AutoTrackEventType>) 方法重新恢复采集。

// 忽略点击事件
SensorsDataAPI.sharedInstance().disableAutoTrack(SensorsDataAPI.AutoTrackEventType.APP_CLICK);
CODE

7.2.2. 采集指定 Fragment 页面浏览事件

默认情况下,SDK 采集所有的 Fragment 页面浏览事件。从 v3.2.6 开始,通过 enableAutoTrackFragment(Class<?> fragment) 和 enableAutoTrackFragments(List<Class<?>> fragmentsList) 方法可以采集指定的 Fragment 页面浏览事件。

// 采集指定 Fragment
SensorsDataAPI.sharedInstance().enableAutoTrackFragment(Class<?> fragment);
CODE

注意

enableAutoTrackFragment() 方法用于采集指定的 Fragment 页面,ignoreAutoTrackFragment() 方法用于忽略指定的 Fragment 页面。当二者设置同时存在时,以 enableAutoTrackFragment() 方法设置的为准,ignoreAutoTrackFragment() 方法设置的信息不在生效。

7.2.3. 忽略 Fragment 页面浏览事件

v3.2.6 开始,通过 ignoreAutoTrackFragment() 方法可以忽略某些 Fragment 页面的页面浏览事件:

// 忽略单个 Fragment
SensorsDataAPI.sharedInstance().ignoreAutoTrackFragment(Class<?> fragment);
// 忽略多个 Fragment
SensorsDataAPI.sharedInstance().ignoreAutoTrackFragments(List<Class<?>> fragmentList);
CODE

v3.2.6 开始,通过 resumeIgnoredAutoTrackFragment() 方法可以恢复被忽略的 Fragment 页面的页面浏览事件:

// 恢复单个 Fragment
SensorsDataAPI.sharedInstance().resumeIgnoredAutoTrackFragment(Class<?> fragment);
// 恢复多个 Fragment
SensorsDataAPI.sharedInstance().resumeIgnoredAutoTrackFragments(List<Class<?>> fragmentList);
CODE

注意

enableAutoTrackFragment() 方法用于采集指定的 Fragment 页面,ignoreAutoTrackFragment() 方法用于忽略指定的 Fragment 页面。当二者设置同时存在时,以 enableAutoTrackFragment() 方法设置的为准,ignoreAutoTrackFragment() 方法设置的信息不在生效。

7.2.4. 忽略 Activity 的全埋点事件

通过 ignoreAutoTrackActivity() 方法可以忽略某个或某些 Activity 的 App 点击事件与 App 页面浏览事件(包含所属 Fragment)。同时也可以通过 resumeAutoTrackActivities(List<Class<?>>) 和 resumeAutoTrackActivity(Class<?>) 方法恢复被忽略的页面。

// 忽略单个 Activity
SensorsDataAPI.sharedInstance().ignoreAutoTrackActivity(Class<?> activity);
// 忽略多个 Activity
SensorsDataAPI.sharedInstance().ignoreAutoTrackActivities(List<Class<?>> activitiesList);
CODE

7.2.5. 忽略某个 View 的点击事件

通过 ignoreView() 方法可以忽略某个 View 对象的 App 点击事件:

SensorsDataAPI.sharedInstance().ignoreView(View view);
CODE

7.2.6. 忽略某类控件的点击事件

通过 ignoreViewType() 方法可以忽略某种控件类型及其子类型的 App 点击事件:

SensorsDataAPI.sharedInstance().ignoreViewType(Class viewType);
CODE

viewType 可以是 Android 常见的控件类型或自定义类型,如:CheckBox、RadioButton、ToggleButton、Switch、Button、ImageButton、CheckedTextView、TextView、ImageView、RatingBar、SeekBar、Spinner、ListView、ExpandableListView、RecyclerView、TabHost、TabLayout、MenuItem、Dialog、GridView

7.2.7. 忽略页面的浏览事件

通过 @SensorsDataIgnoreTrackAppViewScreen 注解可以忽略某个 Activity(包含所属 Fragment) 或 Fragment 的 App 页面浏览事件。例如:忽略 DemoActivity 的页面浏览事件:

// 忽略 DemoActivity 的页面浏览事件
@SensorsDataIgnoreTrackAppViewScreen
public class DemoActivity extends AppCompatActivity {
}
CODE

7.3. 手动触发全埋点事件

手动触发全埋点事件是指由开发者主动调用 SDK 提供的接口触发 App 页面浏览和 App 元素点击事件,与 SDK 自动触发的全埋点事件的区别是开发者调用接口触发的全埋点事件 lib_method 取值为 code,由 SDK 触发的全埋点事件取值为 autoTrack,注意该功能建议不要与全埋点重复混合使用,防止事件增加。

7.3.1. 手动触发页面的浏览事件

v1.7.9 开始,通过 trackViewScreen() 方法可以手动触发 App 页面浏览事件,并且该接口不受忽略等条件的限制。

//触发 Activity 的浏览页面事件
SensorsDataAPI.sharedInstance().trackViewScreen(Activity activity);
//触发 Fragment 的浏览页面事件
SensorsDataAPI.sharedInstance().trackViewScreen(Fragment fragment);
CODE

7.3.2. 手动触发控件的点击事件

v3.2.6 开始,通过 trackViewAppClick() 方法可以手动触发 App 点击事件,并且该接口不受忽略等条件的限制。

//触发该 View 的点击事件
SensorsDataAPI.sharedInstance().trackViewAppClick(View view);
//触发该 View 的点击事件,并加上自定义属性
SensorsDataAPI.sharedInstance().trackViewAppClick(View view, JSONObject properties);
CODE

7.3.3. 忽略 Activity/Fragment  的页面离开事件

//忽略 API 
ignorePageLeave(List<Class<?>> ignoreList) 
CODE

忽略 Activity 采集不影响所属 Fragment 的页面停留时长采集。

7.3.4. 通过 onClick 属性设置的点击事件

通过布局文件中 android:onClick 属性配置的点击回调方法执行时无法自动触发 App 点击事件。此时可以给 android:onClick 属性对应的方法加上 @SensorsDataTrackViewOnClick 注解,这样在方法执行时,SDK 就可以自动触发 App 点击事件。例如:

布局文件:

<Button
	android:onClick="buttonOnClick"/>
CODE

处理函数:

import com.sensorsdata.analytics.android.sdk.SensorsDataTrackViewOnClick;

@SensorsDataTrackViewOnClick
public void buttonOnClick(View v) {}
CODE

7.3.5. 方法执行时自动触发事件

通过 @SensorsDataTrackEvent 注解可以做到:某个 public 方法被执行时,自动触发一个事件。例如:

// eventName 代表事件名,properties 代表事件属性
@SensorsDataTrackEvent(eventName = "someEventName", properties = "{"provider":"神策数据","number":100,"isLogin":true}")
public void someMethod() {}
CODE

7.4. 全埋点事件属性补充

如果在使用全埋点 App 页面浏览和 App 元素点击时遇到如下问题:

· 需要给 App 点击事件或 App 页面浏览事件添加自定义属性
· 部分预置属性未采集到,如图片按钮采集不到 $element_content 属性,页面未采集到 $title 属性
· 采集的预置属性不符合业务需求

此时可以通过 SDK 提供的方法修改或者补充默认的属性取值。

7.4.1. 页面设置自定义属性

通过 ScreenAutoTracker 接口可以给页面设置自定义属性或修改预置属性的取值,实现该接口的类需要是页面对应的 Activity 类或者 Fragment 类:

public interface ScreenAutoTracker {
	String getScreenUrl();
	JSONObject getTrackProperties() throws JSONException;
}
CODE

页面对应的类实现该接口后,SDK 触发 App 页面浏览或 App 点击时会把 getTrackProperties() 返回值中的属性加入到事件的事件属性中,把 getScreenUrl() 返回的值记录到预置属性 $url 中,预置属性 $referrer 的取值就是上一次触发 App 页面浏览时的 $url

想要覆盖其他全埋点的预置属性的话,就可以在 getTrackProperties() 返回的 JSONObject 对象中加入对应的属性名与属性值。

注意

在 ScreenAutoTracker 接口 getTrackProperties() 方法返回的 JSONObject 中,可以通过设置 $title、$screen_name 属性来替换 SDK 默认采集 Activity 和 Fragment 类页面标题和页面名称。

7.4.2. 设置页面标题 $title

Activity 页面浏览事件 $title 按照如下逻辑读取 Activity 的 title 属性:首先读取 activity.getTitle(),如果使用 actionBar,并且 actionBar.getTitle() 不为空,则 actionBar.getTitle() 覆盖 activity.getTitle(),如果以上两步都没有读到 title,则获取 activity 的 android:label 属性。

如果没有使用到 ActionBar 可以在 Manifest 中给相应的 Activity 设置 label ,这样 $title 字段采集的内容就会是设置的 label 内容:

<activity 
	android:label="商品详情页" 
	android:name=".DemoActivity" 
	android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
...
CODE

Fragment 页面浏览事件 $title 属性默认与所在 Activity 的 $title 采集规则一致。在 SDK 2.0.0 及以上的版本可使用 @SensorsDataFragmentTitle 注解设置 Fragment 的 $title 属性的值:

@SensorsDataFragmentTitle(title = "HomeFragment")
public class HomeFragment extends Fragment {
...
}
CODE

7.4.3. 设置元素 ID

SDK 默认使用 android:id 的值作为 App 点击事件的 $element_id 属性,如果元素没有设置 android:id 属性,或者设置的不符合要求,可以使用如下方法覆盖默认元素 ID:

// 给 View 对象设置元素 ID
SensorsDataAPI.sharedInstance().setViewID(View view, String viewID);
// 给 Dialog 对象设置元素 ID
SensorsDataAPI.sharedInstance().setViewID(Dialog view, String viewID);
// 给 AlertDialog 对象设置元素 ID
SensorsDataAPI.sharedInstance().setViewID(AlertDialog view, String viewID);
CODE

注意setViewID() 设置的值优先级高于 android:id 的值。

7.4.4. 设置元素所在 Activity

SDK 默认会尝试获取 View 元素所在的 Activity 页面,但是当无法获取时可以尝试通过 setViewActivity(View, Activity) 方法指定。

SensorsDataAPI.sharedInstance().setViewActivity(View view, Activity activity);
CODE

7.4.5. 设置元素所在 Fragment 名称

SDK 默认会尝试获取 View 元素所在的 Fragment 页面,但是当无法获取时可以尝试通过 setViewFragmentName(View, Activity) 方法指定 View 所在的 Fragment 全路径名称,SDK 会根据设置的值进行反射创建 Fragment 用于 $screen_name 取值。

SensorsDataAPI.sharedInstance().setViewFragmentName(View view, String fragmentName);
CODE

7.4.6. 控件设置自定义属性

通过 setViewProperties() 方法可以扩展指定 View 对象的 App 点击事件的事件属性。

SensorsDataAPI.sharedInstance().setViewProperties(View view, JSONObject properties);
CODE

对于 ExpandableListView,不仅可以通过 setViewProperties() 来扩展 item 对应 View,也可以通过 Adapter 实现 SensorsExpandableListViewItemTrackProperties 接口来扩展事件属性。

package com.sensorsdata.analytics.android.sdk;

public interface SensorsExpandableListViewItemTrackProperties {
	/**
	 * 点击 groupPosition、childPosition 处 item 的扩展属性
	 */
	JSONObject getSensorsChildItemTrackProperties(int groupPosition, int childPosition) throws JSONException;

	/**
	 * 点击 groupPosition 处 item 的扩展属性
	 */
	JSONObject getSensorsGroupItemTrackProperties(int groupPosition) throws JSONException;
}
CODE

对于 ListViewGridView,同样不仅可以通过 setViewProperties() 来扩展 item 对应 View,也可以通过 Adapter 实现 SensorsAdapterViewItemTrackProperties 接口来扩展事件属性。

package com.sensorsdata.analytics.android.sdk;

public interface SensorsAdapterViewItemTrackProperties {
	/**
	 * 点击 position 处 item 的扩展属性
	 */
	JSONObject getSensorsItemTrackProperties(int position) throws JSONException;
}
CODE

7.5. 全埋点注解说明

注解说明示例
@SensorsDataAutoTrackAppViewScreenUrl通过注解自定义 $AppViewScreen 事件的 $url 属性
@SensorsDataAutoTrackAppViewScreenUrl(url = "主页面")
public class MainActivity extends Activity { }
CODE


@SensorsDataIgnoreTrackAppClick通过注解忽略 Activity 或 Fragment 页面内的所有 View 的点击事件($AppClick)
@SensorsDataIgnoreTrackAppClick
public class MainActivity extends Activity { }
CODE
@SensorsDataIgnoreTrackAppViewScreen通过注解忽略 Activity 或 Fragment 的页面浏览事件($AppViewScreen)
@SensorsDataIgnoreTrackAppViewScreen
public class MainActivity extends Activity { }
CODE
@SensorsDataIgnoreTrackAppViewScreenAndAppClick通过注解忽略 Activity 或 Fragment 的页面浏览事件($AppViewScreen)和页面内所有 View 的点击事件($AppClick)
@SensorsDataIgnoreTrackAppViewScreenAndAppClick
public class MainActivity extends Activity { }
CODE
@SensorsDataIgnoreTrackOnClick通过注解忽略 $AppClick 点击事件
@SensorsDataIgnoreTrackOnClick
public void onClick(View v) {

}
CODE
@SensorsDataTrackEvent通过注解采集一个事件
@SensorsDataTrackEvent(eventName = "TestEvent", properties = "Json 字符串属性")
public void trackEvent() {
	...
}
CODE
@SensorsDataTrackViewOnClick通过注解采集 $AppClick 点击事件,前提页面不能被忽略
@SensorsDataTrackViewOnClick
public void clickShow(View v) {
	
}
CODE

8. 其他功能

8.1. 开启屏幕方向的自动采集

v1.10.1 及以后的版本可以通过 enableTrackScreenOrientation() 方法开启屏幕方向属性的收集,屏幕方向信息记录在事件的 $screen_orientation 属性中。或通过 SensorsDataAPI.enableTrackScreenOrientation(boolean) 接口动态控制该功能的开启和关闭。

注意:该接口开启后会读取手机传感器信息,请根据合规需要进行说明。

SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
//开启屏幕方向属性的收集
saConfigOptions.enableTrackScreenOrientation(true);

SensorsDataAPI.startWithConfigOptions(this, saConfigOptions);

//动态开启和关闭,true 开启,false 关闭。
SensorsDataAPI.sharedInstance().enableTrackScreenOrientation(false);
CODE

8.2. 开启位置信息自动采集

v1.10.1 及以后的版本可以通过 setGPSLocation() 方法,把第三方定位获取到的经纬度信息设置给 SDK,设置之后经纬度信息记录在事件的 $longitude$latitude 属性中。清除位置信息调用 clearGPSLocation() 方法进行清除。

//设置经纬度
SensorsDataAPI.sharedInstance().setGPSLocation(latitude,longitude);

// 清除位置信息
SensorsDataAPI.sharedInstance().clearGPSLocation();
CODE

8.3. 开启推送点击事件自动采集

版本要求

  • Android SDK v5.4.3 及以上版本,v6.6.5 及以上版本兼容极光 4.6.0 及以上版本
  • Android 插件 v3.4.1 及以上版本

通过 SAConfigOptions 实例的 enableTrackPush() 方法开启推送点击事件的采集:

// 传入 true 代表开启推送点击事件自动采集
saConfigOptions.enableTrackPush(true);
CODE

此预置事件的说明请参考 App SDK 预置事件和预置属性

  1. 目前支持极光及极光厂商通道、友盟及友盟厂商通道、个推(不支持个推厂商通道)
  2. 推送采集 hook 了推送的接口,请实现推送点击的相关接口
    1. 极光推送 < 4.6.0
      1. 自建通道:请在 AndroidManifest.xml 配置 JPushMessageReceiver,并实现 JPushMessageReceiver 的 onNotifyMessageOpened 方法 详见
      2. 厂商通道:必须配置 uri_activity 和 uri_action
    2. 极光推送 >= 4.6.0
      1. 自建通道/厂商通道:配置 intent 或者 uri_activity 和 uri_action
      2. 无通知跳转目标地址:请在 AndroidManifest.xml 配置 JPushMessageReceiver,并实现 JPushMessageReceiver 的 onNotifyMessageOpened 方法 详见
    3. 友盟推送
      1. 自建通道:请实现 UmengNotificationClickHandler 类中的 launchApp、openUrl、openActivity、dealWithCustomAction 方法 详见
      2. 厂商通道:请在 AndroidManifest.xml 配置 UmengNotifyClickActivity,并实现 UmengNotifyClickActivity 的 onMessage 方法 详见
    4. 个推,请实现 GTIntentService 的 onReceiveMessageData 和 onNotificationMessageClicked 方法 详见
  3. 版本支持
    1. 兼容极光 SDK 为 jpush:3.9.1+、jcore:2.6.0+,兼容极光封装的厂商 SDK 均为 3.9.1+。 
    2. 个推支持 3.2.2.0,个推核心组件 3.1.2.0+
    3. 友盟支持 6.3.3+

8.4. 可视化全埋点

8.4.1. 开启可视化全埋点

版本要求

  • 神策分析 v1.17.2517+
  • Android SDK v4.0.0+

进行如下配置,即可开启可视化全埋点:

// 开启可视化全埋点
saConfigOptions.enableVisualizedAutoTrack(true);
JAVA

开启可视化全埋点后,该功能默认对所有页面上的点击生效,如果您只是想部分页面进行可视化全埋点,可以通过 addVisualizedAutoTrackActivity()addVisualizedAutoTrackActivities() 方法配置:

//开启某个 Activity 的可视化全埋点
SensorsDataAPI.sharedInstance().addVisualizedAutoTrackActivity(Class<?> activity);
//开启多个 Activity 的可视化全埋点
 SensorsDataAPI.sharedInstance().addVisualizedAutoTrackActivities(List<Class<?>> activitiesList);
CODE

8.4.2. 可视化全埋点自定义属性

如果您需要在 Android SDK v6.0.0+ 使用可视化全埋点自定义属性,需要配置 enableVisualizedProperties

// 开启可视化全埋点自定义属性配置下发
 saConfigOptions.enableVisualizedProperties(true);
JAVA

此属性为 false 的情况下,创建的可视化自定义属性无法采集。开启此开关即可默认开启可视化全埋点。

  • 本功能使用前,请确保您 Android 项目中已完成配置 scheme
  • 可视化全埋点在神策分析中的使用,请参考可视化全埋点部分介绍

8.5. 开启点击分析功能

版本要求

  • 神策分析 v2.2.0.240
  • Android SDK v5.0.0 版本及以上
  • 此功能依赖于全埋点中点击事件采集的开启
  • 使用此功能前,确保您的 App 中配置了当前项目的 Scheme,详细操作可参考配置 scheme

调用 SAConfigOptions 实例的 enableHeatMap() 方法,并且参数传入 true 即可开启 SDK 的点击分析功能:

saConfigOptions.enableHeatMap(true);
CODE

开启 App 点击分析后,该功能默认对所有页面上的点击生效,如果您只是想部分页面进行热力图,可以通过 addHeatMapActivity()addHeatMapActivities() 方法配置:

//开启某个 Activity 的点击图
SensorsDataAPI.sharedInstance().addHeatMapActivity(Class<?> activity);
//开启多个 Activity 的点击图
SensorsDataAPI.sharedInstance().addHeatMapActivities(List<Class<?>> activitiesList);
CODE

8.6. 开启调试模式

在神策 Android SDK (3.0.3+) 中,可以通过扫描网页二维码的方式,开启该设备的「调试模式」。具体使用方法请参考 Debug 实时数据查询

8.7. 开启 Crash 信息的自动采集

SDK 默认关闭 Crash 信息采集,开启采集后,App Crash 时,会触发 AppCrashed 事件,堆栈信息记录在 app_crashed_reason 属性中。

SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);
//SAConfigOptions 对象开启 crash 信息采集 
saConfigOptions.enableTrackAppCrash();
SensorsDataAPI.startWithConfigOptions(this, saConfigOptions);
CODE

v3.1.0 及之前的版本,开启 Crash 采集: 

//开启 crash 信息收集
SensorsDataAPI.sharedInstance().trackAppCrash();
CODE

8.8. SDK 网络请求开关

SDK 提供 enableNetworkRequest(boolean isRequest) 的接口用于控制 SDK 的网络请求,参数为 true 表示允许 SDK 发起网络请求,参数为 false 表示禁止 SDK 发起网络请求。注意使用时一定要注意调用时机,防止 SDK 处于禁用网络状态,导致事件无法及时上报。

// 开启网络请求
SensorsDataAPI.sharedInstance().enableNetworkRequest(true);
// 禁用网络请求
SensorsDataAPI.sharedInstance().enableNetworkRequest(false);
CODE

8.9. 即时事件采集

SDK 提供 setInstantEvents(List<String> listInstantEvents) 接口用于设置即时事件,用于即时营销的业务场景。

List list = new ArrayList();
list.add("instant_event1");
list.add("instant_event2");
SAConfigOptions configOptions = new SAConfigOptions(SA_SERVER_URL);
//设置实时上报数据事件名称列表
configOptions.setInstantEvents(list);
CODE

该接口适用于即时营销的业务场景,其它业务调用该接口无实际意义。

8.10. 远程配置

Android SDK 从 v6.7.9 版本开始,默认不开启远程配置功能,需要开发者手动调用 enableRemoteConfig(boolean) 接口进行开启/关闭。

// 开启远程配置
SensorsDataAPI.sharedInstance().enableRemoteConfig(true);

// 关闭远程配置
SensorsDataAPI.sharedInstance().enableRemoteConfig(false);
CODE