欢迎使用神策分析 Android SDK!

新书推荐《Android 全埋点解决方案》


在使用前,请先阅读 数据模型 的介绍

SDK 的更新日志,可参阅 Release Notes

插件 的更新日志,可参阅 Release Notes

1. 集成神策分析 SDK

1.1. 引入插件

project 级别的 build.gradle 文件中添加 Sensors Analytics android-gradle-plugin 依赖:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
        //添加神策分析 android-gradle-plugin 依赖
        classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:3.2.0'
    }
}
allprojects {
    repositories {
        jcenter()
    }
}
GROOVY

Sensors Analytics android-gradle-plugin 的最新版本号请参考 GitHub 更新日志

如下示例图:

1.2. 引入 SDK

 module build.gradle 文件中添加 com.sensorsdata.analytics.android 插件、神策分析 SDK 依赖:

apply plugin: 'com.android.application'
//添加 com.sensorsdata.analytics.android 插件
apply plugin: 'com.sensorsdata.analytics.android'

dependencies {
   //添加 Sensors Analytics SDK 依赖
   implementation 'com.sensorsdata.analytics.android:SensorsAnalyticsSDK:4.0.0'
}
GROOVY

SensorsAnalyticsSDK 的最新版本号请参考 GitHub 更新日志

如下示例图:

Android SDK 要求最低系统版本为 API 9(Android 2.3)。AutoTrack 功能要求系统最低版本为 API 14 (Android 4.0)如果 API 低于 14 开启 AutoTrack 后 将不能采集 $AppStart$AppViewScreen$AppEnd 事件

目前,Android SDK ( aar 格式) 大小约为 300 KB。

1.3. 权限配置说明

SDK 共需要四个权限

权限

用途

INTERNET允许应用发送统计数据
ACCESS_NETWORK_STATE允许应用检测网络状态
READ_PHONE_STATE允许应用获取设备 IMEI
ACCESS_WIFI_STATE允许应用获取 MAC 地址

各个权限详细说明:

  • INTERNET

必须权限,SDK 发送埋点数据需要此权限

  • ACCESS_NETWORK_STATE

必须权限,SDK 会根据网络状态选择是否发送数据

  • READ_PHONE_STATE

可选权限,采用 App 内推广 和采集 $carrier 属性时会用到此权限

  • ACCESS_WIFI_STATE

可选权限,采用 App 内推广 时会用到此权限

如何删除在 AndroidManifest.xml 中已注册权限?

神策 SDK 为简化开发者集成步骤,默认在 AndroidManifest.xml 中注册了以上四个权限,如果开发者不需要其中某个权限,可以使用 tools:node="remove" 属性删除,打包后的 AndroidManifest.xml 文件将不再包含此权限,关于 tools:node="remove" 的详细说明可参考谷歌 官方文档,配置参考代码如下:

如果不是特殊要求,可不配置此代码

<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />
CODE

注意: 如果使用了 MultiDex ,请确保神策 Android SDK 的代码都指定到主 DEX 中。可以通过在 multiDexKeepProguard 里添加如下配置:

-keep class com.sensorsdata.analytics.android.** { *; }
CODE

2. 获取数据接收地址

数据接收地址是 SDK 上报数据的目标地址,需要使用管理员账户进行获取。

3. 初始化 SDK 并开启全埋点

一定需要在程序的入口 Application  onCreate() 中调用 SensorsDataAPI.startWithConfigOptions(SAConfigOptions) 并且在 主线程 中初始化 SDK


// 引入神策分析 SDK
import com.sensorsdata.analytics.android.sdk.SensorsDataAPI;
import com.sensorsdata.analytics.android.sdk.SAConfigOptions;
import com.sensorsdata.analytics.android.sdk.SensorsAnalyticsAutoTrackEventType;


// 数据接收的 URL
final String SA_SERVER_URL = "YOUR_SERVER_URL";

//设置 SAConfigOptions,传入数据接收地址 SA_SERVER_URL
SAConfigOptions saConfigOptions = new SAConfigOptions(SA_SERVER_URL);

//通过 SAConfigOptions 设置神策 SDK,每个条件都非必须,开发者可根据自己实际情况设置,更多设置可参考 SAConfigOptions 类中方法注释
saConfigOptions.setAutoTrackEventType(SensorsAnalyticsAutoTrackEventType.APP_CLICK | // 开启全埋点点击事件
                SensorsAnalyticsAutoTrackEventType.APP_START |      //开启全埋点启动事件
                SensorsAnalyticsAutoTrackEventType.APP_END |        //开启全埋点退出事件
                SensorsAnalyticsAutoTrackEventType.APP_VIEW_SCREEN)     //开启全埋点浏览事件
                .enableLog(true)        //开启神策调试日志,默认关闭(调试时,可开启日志)。
                .enableTrackAppCrash();     //开启 crash 采集
//需要在主线程初始化神策 SDK
SensorsDataAPI.startWithConfigOptions(this, saConfigOptions);
JAVA

其中 YOUR_SERVER_URL 是前文中从神策分析获取的数据接收的 URL。一旦成功初始化后,则可以通过 sharedInstance 获取 SDK 实例,进行用户行为事件或属性的追踪。

注意:利用 SAConfigOptions 设置全埋点类型、开启 crash 采集时等操作时,只有 SDK 第一次初始化时有效。请勿对多个 SAConfigOptions 对象进行相关设置

4. 代码埋点

第一次接入神策分析时,建议先追踪 3~5 个关键的事件,只需要几行代码,便能体验神策分析的分析功能。例如:

  • 图片社交产品,可以追踪用户浏览图片和评论事件
  • 电商产品,可以追踪用户浏览商品和下订单等事件

神策分析 SDK 成功初始化后,可以通过 track() 方法追踪用户行为事件,并为事件添加自定义属性。以电商产品为例,可以这样追踪一次购物行为:

// 在用户浏览商品页面时...

try {
    JSONObject properties = new JSONObject();
    properties.put("ProductID", 123456);                    // 设置商品ID
    properties.put("ProductCatalog", "Laptop Computer");    // 设置商品类别
    properties.put("IsAddedToFav", false);                  // 是否被添加到收藏夹

    SensorsDataAPI.sharedInstance().track("ViewProduct", properties);
} catch (JSONException e) {
    e.printStackTrace();
}

// 在用户结账付款时...

try {
    JSONArray orderList = new JSONArray();
    orderList.put("Apple iPhone6s");
    orderList.put("Nexus 6");

    JSONObject properties = new JSONObject();
    properties.put("OrderPaid", 50.10);                     // 订单支付金额
    properties.put("OrderList", orderList);                 // 产品列表
    properties.put("OrderDate", new Date());                // 订单时间
    SensorsDataAPI.sharedInstance().track("PaidOrder", properties);
} catch (JSONException e) {
    e.printStackTrace();
}
JAVA

触发事件后,在神策分析中稍等片刻,便能看到追踪结果。

5. 事件属性

每个事件可以设置多个事件属性,例如浏览商品事件中,将商品 ID、商品分类等信息作为事件属性。在后续的分析工作中,事件属性可以作为统计过滤条件使用,也可以作为维度进行多维分析。对于事件属性,神策分析有一些约束:

  • 事件属性是一个 JSONObject 对象
  • JSONObject 中每个元素描述一个属性,Key 为属性名称,必需是 String 类型
  • JSONObject 中,每个元素的 Value 是属性的值,支持 StringNumberBooleanJSONArray 和 Date,对于 JSONArray,其中所有元素必须是 String 类型

5.1. 设置静态公共属性

特别地,如果某个事件的属性,在所有事件中都会出现,可以通过 registerSuperProperties() 将该属性设置为事件静态公共属性。例如添加应用程序名称为事件的公共属性,设置方法如下:

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

成功设置事件公共属性后,再通过 track() 追踪事件时,事件公共属性会被添加进每个事件中,例如:

// 记录收藏商品事件
try {
    JSONObject properties = new JSONObject();
    properties.put("ProductID", 123456);
    SensorsDataAPI.sharedInstance().track("AddToFav", properties);
} catch (JSONException e) {
    e.printStackTrace();
}
JAVA

在设置事件公共属性后,实际发送的事件中会被加入 AppName 属性,等价于

// 记录收藏商品事件
try {
    JSONObject properties = new JSONObject();
    properties.put("ProductID", 123456);
    properties.put("AppName", getAppName(this));
    SensorsDataAPI.sharedInstance().track("AddToFav", properties);
} catch (JSONException e) {
    e.printStackTrace();
}
JAVA

重复调用 registerSuperProperties() 会覆盖之前已设置的公共属性,公共属性会保存在 App 本地 SharedPreferences 中。可以通过 unregisterSuperProperty() 删除一个静态公共属性,使用 clearSuperProperties() 会删除所有已设置的事件公共属性。

当事件公共属性和事件属性的 Key 冲突时,事件属性优先级最高,它会覆盖事件公共属性。

  1. 请在初始化 SDK 后立即调用 registerSuperProperties() 方法,确保每个事件都会添加已设置的公共属性。
  2. 神策事件属性大小写敏感( 详见 数据格式 ),设置公共属性前需确保事件表中不存在仅大小写不同的同名属性,否则会导致所有事件因存在同名属性而不能入库。

5.2. 设置动态公共属性

Android SDK 2.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;
    }
});
JAVA

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

6. 记录激活事件

可以调用 trackInstallation 方法记录激活事件,多次调用此方法只会触发一次激活事件(触发激活事件时会自动保存 $first_visit_time 首次访问时间属性到用户表)。
触发激活事件时会尝试获取 IMEI 号,请动态申请 android.permission.READ_PHONE_STATE 权限后再调用 trackInstallation 

例如,在 Activity 的 onCreate 方法中申请权限:

if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.M){
    if (ActivityCompat.checkSelfPermission(this, "android.permission.READ_PHONE_STATE") != PackageManager.PERMISSION_GRANTED) {
        // 6.0 以上,无权限时,先申请 READ_PHONE_STATE 权限。
        ActivityCompat.requestPermissions(this, new String[]{"android.permission.READ_PHONE_STATE"}, 100);
    } else {
        // 6.0 以上,有权限时,调用 trackInstallation() 触发激活事件。
        trackInstallation();
    }
} else {
    // 6.0 以下,直接调用 trackInstallation() 触发激活事件。
    trackInstallation();
}
JAVA

在权限回调的 onRequestPermissionsResult 方法中,调用 trackInstallation

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 100) {
        //申请权限结果回调时(无论申请权限成功失败),都要调用 trackInstallation() 触发激活事件。
        trackInstallation();
    }
}


/**
 * 记录激活事件
 */
private void trackInstallation() {
    try {
        JSONObject properties = new JSONObject();
        properties.put("DownloadChannel", "XXX");//这里的 DownloadChannel 负责记录下载商店的渠道。这里传入具体应用商店包的标记。
        //记录 AppInstall 激活事件
        SensorsDataAPI.sharedInstance().trackInstallation("AppInstall", properties);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
JAVA

7. 匿名 ID 和登录 ID 关联

用户在登录前 ,SDK 会分配一个匿名 ID 来标识游客。当用户注册成功或登录成功时调用 login 方法,传入对应的登录 ID ;匿名 ID 会与对应的登录 ID 进行关联,关联成功之后视为同一个用户。

调用时机:注册成功、登录成功 、初始化 SDK(如果能获取到登录 ID)都需要调用 login 方法传入登录 ID

登录 ID 是指可以唯一标识一个用户的 ID,通常是业务数据库里的主键或其它唯一标识。

//注册成功、登录成功、初始化SDK后  调用 login 传入登录 ID
SensorsDataAPI.sharedInstance().login("你们服务端分配给用户具体的登录 ID");
JAVA

注意:对同一个用户,login() 可调用多次,多次调用 login() 时,如果新设置的 登录 ID 与之前缓存的 登录 ID 相同,神策分析会忽略该次调用。

8. 设置用户属性

8.1. 记录设定的用户属性

为了更准确地提供针对人群的分析服务,可以使用神策分析 SDKprofileSet() 等方法设置用户属性,如年龄、性别等。用户可以在留存分析、分布分析等功能中,使用用户属性作为过滤条件,精确分析特定人群的指标。

使用 profileSet(),可以设定用户属性,例如:

try {
    JSONObject properties = new JSONObject();
    // 设定用户性别属性 "Sex" 为 "Male"
    properties.put("Sex", "Male");
    // 设定用户年龄属性 "Age" 为 18
    properties.put("Age", 18);

    // 设定用户属性
    SensorsDataAPI.sharedInstance().profileSet(properties);
} catch (JSONException e) {
    e.printStackTrace();
}
JAVA

使用 profileUnset() 可以删除特定用户的属性值。

用户属性中,属性名称与属性值的约束条件与事件属性相同,详细说明请参考 数据格式

8.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();
}
JAVA

8.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);
JAVA

8.4. 列表类型的属性

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

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

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

// 再次设定该属性,属性 "Movies" 为: ["Sicario", "Love Letter", "Dead Poets Society"]
SensorsDataAPI.sharedInstance().profileAppend("Movies", "Dead Poets Society");
JAVA

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

9. 打通 AppH5

Android SDK 需要使用 v1.7.10 及之后的版本支持 App 与 H5 打通,详细技术实现请参考 打通 App 与 H5

10. 获取 scheme

使用 admin 账号,登录到神策分析相应的项目,点击右上角的账号,从「数据接入」页面获取 scheme 的值。

11. 可视化全埋点

本功能需要 Android SDK 版本为 v3.1.0+ 

如果使用 Android SDK 版本是 v4.0.0+,需要对应神策分析 v1.15.2420+、v1.16.2386+、v1.17.2517+

可视化全埋点在神策分析中的使用,请参考 可视化全埋点

11.1. 配置 scheme

使用 admin 账号,登录到神策分析相应的项目,从【数据接入】页面获取 scheme 的值,详情可参考 获取 scheme

AndroidManifest.xmlMainActivity 的标签内,配置 scheme

<activity android:name=".SplashActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>
​​
<activity android:name=".MainActivity">
    <!-- 在主 Activity 中配置 scheme-->
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data
            android:host="visualized"
            android:scheme="您项目的 scheme 值"/>
    </intent-filter>
</activity>
XML

在配置 <intent-filter> 的时候需要注意确保只有一个 <data> 字段,不要随意修改或者合并神策 SDK 相关的 <intent-filter> ,关于 <intent-filter> 的解释,可以参考 Google 官方文档

11.2. 开启可视化全埋点

SDK 初始化前设置 SAConfigOptions 配置时,调用 enableVisualizedAutoTrack(true) 方法开启可视化全埋点:

//初始化 SDK 时开启可视化全埋点, 在采集 $AppClick 事件时会记录 View 的 ViewPath
saConfigOptions.enableVisualizedAutoTrack(true);
JAVA

11.3. 开启部分页面的可视化全埋点

如果只想开启部分页面的可视化全埋点,需要首先调用 enableVisualizedAutoTrack 方法开启可视化全埋点,然后通过 addVisualizedAutoTrackActivitiesaddVisualizedAutoTrackActivity 方法开启。

例如,开启 MainActivity 页面的可视化全埋点:

//开启 MainActivity 页面的可视化全埋点
SensorsDataAPI.sharedInstance().addVisualizedAutoTrackActivity(MainActivity.class);
JAVA

注意:开启了可视化全埋点功能后,扫描二维码打开 App 时(使用手机自带浏览器扫描),默认情况下会弹出 AlertDialog 提示框,来提示用户是否继续连接进行可视化全埋点。

如果想关闭此提示框,可以调用 enableVisualizedAutoTrackConfirmDialog 关闭,关闭提示后,扫描二维码打开 App 时,会自动连接进行可视化全埋点。

//关闭点击可视化全埋点的提示框
SensorsDataAPI.sharedInstance().enableVisualizedAutoTrackConfirmDialog(false);
JAVA

12. 调试查看数据

初始化 SDK 后调用 enableLog(true打开 SDK 的日志输出功能,如果相应事件触发,SDK 会自动进行采集并定时发送到神策分析后台。

//打开 SDK 的日志输出功能
SensorsDataAPI.sharedInstance().enableLog(true); 
JAVA

12.1. IDE 控制台查看数据

可以通过 Logcat 查看日志进行数据校验和验证, 在 Logcat 中筛选 SA. 关键词:

埋点事件触发成功时,SDK 会输出 track event 开头的事件数据;
埋点事件触发失败时,SDK 会输出相应的错误原因;
事件数据上报成功时,SDK 会输出 valid message 字段开头的事件数据;
事件数据上报失败时,SDK 会输出 invalid message 字段开头的事件数据并输出错误原因。

12.2. 神策分析中查看已入库数据

SDK 默认本地存储的数据超过 100 条或间隔 15S 后将本地触发的事件上报到服务端进行入库,已入库的数据,可以在神策分析中进行筛选和查看。

13. 所有事件公共预置属性

神策分析 SDK 会自动收集 App 版本、网络状态、IP、设备型号等一系列系统信息作为所有事件都有的公共属性,详细的默认属性列表可以参考 App SDK 预置事件和预置属性