小米统计服务Android客户端SDK使用指南

 

1. 客户端SDK功能概述

在使用小米统计服务前,开发者需要先登录小米开发者网站http://dev.xiaomi.com ,注册app,申请AppId,
AppKey。其中AppId和AppKey是客户端的身份标识,在客户端SDK初始化时使用。然后下载最新的SDK压缩包,其中包括了Android SDK和Android
Demo。Android版SDK以jar形式提供, 第三方APP只需要添加少量代码和配置,即可完成接入小米统计服务。

统计服务Android
SDK所有的接口都封装在MiStatInterface抽象类的静态方法中,主要功能接口请参考第3节API说明。应用在启动时,需要调用initialize方法来初始化统计服务,之后便可按照统计的业务需求,调用统计数据上报接口上报统计打点。
SDK提供了接口给开发者来设置向小米统计服务器上报统计数据的策略,开发者可以在任意时候调用修改策略。客户端SDK上报的数据包括默认事件统计、session统计(用于统计app的活跃度、打开频率、使用时长等)、页面访问统计和自定义事件统计。

小米统计SDK提供app的崩溃日志收集功能。功能开启后,对于app在使用过程中的崩溃,SDK将自动采集崩溃日志,并上传到统计后台;统计后台会根据app版本,对崩溃进行聚合、展示。开发者可以根据app实际情况情况,将该崩溃标记成已处理或者忽略状态。

2. SDK使用配置

本节主要介绍使用小米统计SDK前的准备工作,开发者也可以参照SDK中的demo来配置。

2.1.  配置AndroidManifest.xml文件

  1. SDK支持的最低安卓版本为2.2。
    <uses-sdk  android:minSdkVersion="8"/>
  2. 统计服务需要的权限列表
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    对应的4种权限,用途如下:

    • 网络访问权限,需要联网以便于向小米统计服务端上报统计数据。
    • 查看网络状态,用于根据不同的网络环境,选择相应的上报策略。同时也需要上报当前的网络环境用于后台统计展示。
    • 读取手机状态和身份,用于获取设备的唯一标识,为当前设备生成一个唯一设备ID。
    • 查看Wifi状态权限,用于获取mac地址,生成设备唯一标示。

2.2. 初始化统计服务

应用启动时,需要调用统计SDK中的初始化方法,传入appID、appKey等身份验证参数和应用对应的渠道号。在调用其他统计服务相关API前,必须调用本方法初始化统计服务,建议您在程序的Application
的onCreate中初始化小米统计服务。

        MiStatInterface.initialize(this, MY_APPID, MY_APP_KEY, CHANNEL);

3. app常规数据统计

本节主要介绍如何设置数据上报策略,如何记录页面访问行为和用户自定义事件。本节也介绍了通过集成测试模块验证SDK是否集成成功的方法。

3.1. 数据上报策略

小米统计服务SDK会先把数据记录缓存在本地,然后根据开发者设定的数据上报策略,触发上报流程。SDK中提供了一系列数据上报策略供开发者选择,这些策略包括:

  • UPLOAD_POLICY_REALTIME 实时上报。每当有一条新的记录,就会激发一次上报。
  • UPLOAD_POLICY_WIFI_ONLY 只在WIFI下上报。当设备处于WIFI连接时实时上报,否则不上报记录。
  • UPLOAD_POLICY_BATCH 批量上报。当记录在本地累积超过一个固定值时(50条),会触发一次上报。
  • UPLOAD_POLICY_WHILE_INITIALIZE
    启动时候上报。每次应用启动(调用initialize方法)时候,会将上一次应用使用产生的数据记录打包上报。
  • UPLOAD_POLICY_INTERVAL
    指定时间间隔上报。开发者可以指定从1分钟-1天之间的任意时间间隔上报数据记录。需要注意,由于SDK并没有使用安卓的实时唤醒机制,因此采用此策略上报,SDK做不到严格的遵守开发者设定的间隔,而会根据应用数据采集的频率和设备休眠策略,会有一定的偏差。
  • UPLOAD_POLICY_DEVELOPMENT
    调试模式。使用此策略,只有开发者手动调用一个接口才会触发上报,否则在任何情况下都不上报。SDK中提供了一个triggerUploadManually方法用于手动触发。这种策略主要用于开发者调试时候可手动控制上报时机,便于做数据对比。

小米统计服务的本地缓存最长会保存3天,只要在3天内上报流程被触发,就会将本地之前没上报成功的所有数据打包上报。如果数据上报成功,则会把已经成功的数据从本地删除。

默认的数据上报策略是UPLOAD_POLICY_INTERVAL,默认的上报时间间隔是三分钟。

设置上报策略的代码示例如下:

MiStatInterface.setUploadPolicy(UPLOAD_POLICY_REALTIME, 0);

3.2. 默认事件

为了提供一些app所共有的统计维度,小米统计SDK会默认采集如下一些应用信息作为事件上报到小米统计后台:

表 1. 默认上报事件

事件名称 事件说明 上报时机
新增 用于实时统计应用的新增人数 应用第一次调用recordPageStart
版本升级 用于统计每个版本的升级人数和升级时间 应用每次版本更新后第一次启动
机型 用于统计机型分布,并可将机型设置为其它统计项的过滤条件 应用第一次调用recordPageStart
安卓系统版本 用于统计版本分布,并可将版本设置为其它统计项过滤条件 应用第一次调用recordPageStart
系统语言 用于统计系统语言的分布 应用第一次调用recordPageStart
运营商 用于统计运营商分布信息 应用第一次调用recordPageStart
IMEI 用于标识某个特定的设备 应用第一次调用recordPageStart
屏幕分辨率 用于统计屏幕分辨率的分布 应用第一次调用recordPageStart
App渠道号 用于统计应用渠道分布情况,并为其它统计项提供实时过滤 每次上报
App版本号 用于统计应用版本分布情况,并为其它统计项提供实时过滤 每次上报
网络环境 用于统计用户在打开应用时候的网络分布情况 每次session上报

 

3.3. session

小米统计服务将从用户打开应用开始,到离开应用并且超过30秒结束,这一段时间我们定义为一个session。session主要用于开发者观察用户的使用时长、打开次数等统计项。为了统计session,需要开发者在用户进入应用每个界面(Activity)的时候,调用recordPageStart方法,在用户离开该界面的时候,调用recordPageEnd方法。我们建议将这两个调用分别放于应用所有的Activity的onResume和onPause方法中。示例代码如下:

public class MainActivity extends Activity {
    
    @override
    protected void onResume() {
        super.onResume();
        MiStatInterface.recordPageStart(this, "主界面");
    }

    protected void onPause() {
        super.onPause();
        MiStatInterface.recordPageEnd();
    }
}

小米统计服务SDK会根据每个Activity进入-退出的时间,自动计算出用户使用的session数据。

3.4. 页面访问

在记录session的同时,小米统计SDK也会记录下用户页面之间的跳转,每条页面跳转的数据记录了一个session当中所有的页面访问记录。页面访问的数据同样通过recordPageStart和recordPageEnd这两个方法来记录,开发者可以为每个页面设置一个名称,作为recordPageStart的第二个参数传入:

MiStatInterface.recordPageStart(activity, MY_PAGE_NAME);

如果页面名称传入空,则SDK会直接采用activity的完整类名来作为页面名称。

在android
4.0以及之后的版本中,很多界面都采用Fragment方式来开发界面,这种方式下,Activity作为一个容器,不会对应某个特定的界面,因此会对页面访问的统计产生一些错误数据。这种情况下我们建议只在Fragment的onResume和onPause中添加recordPageStart和recordPageEnd方法。示例代码如下:

public class MyFragmentActivity extends FragmentActivity {
    
    @override
    protected void onResume() {
        super.onResume();
        // 这是一个fragment的容器activity,在onResume中不需要调用小米统计
        // 服务的recordPageStart方法
        ...
    }

    protected void onPause() {
        super.onPause();
        ...
    }
}

public class MyFragment extends Fragment {

    @override
    protected void onResume() {
        super.onResume();
        // 在fragment中的调用用于记录页面访问信息
        MiStatInterface.recordPageStart(getActivity(), "主界面");
        ...
    }

    protected void onPause() {
        super.onPause();
        MiStatInterface.recordPageEnd();
        ...
    }

}

3.5. 自定义事件

除了默认事件、session和页面访问外,小米统计服务提供了自定义事件的上报。开发者可结合应用的业务逻辑,添加自定义事件的统计。每个自定义事件有如下4个属性:类别(category)、主键(key)、值(value)和类型(type)。这4个参数的的含义和作用如下:

  • category
    自定义事件的类别,开发者可使用该参数对自定义打点做整理归类,方便在有大量的自定义事件时在数据统计后台快速定位到相应的事件。类别是一个可选的参数,如果这个值为空,统计SDK会将该事件放入默认的类别中。
  • key 自定义事件的主键,作为该事件的唯一标识。
  • value 自定义事件的值,根据事件类型不同,值会有字符串和数值两种类型。
  • type 自定义事件的类型。根据不同的业务上报逻辑,我们将自定义事件分成如下4种类型:计数(count)、计算(calculate)、字符串属性(string
    property)和数值属性(numeric property)。每个类型的详细解释如下:

计数和计算类型的事件,除了上述属性之外,还可以增加事件参数(参见API说明部分)。事件参数可以以更丰富的维度展示与该事件相关的数据。比如,游戏应用中的一种消费行为,开发者对发生该事件的用户性别,等级,年龄等感兴趣,就可以将性别,年龄,等级均设置为消费事件的参数;这样,对于该消费事件,除了统计发生次数外,还会展示事件发生时,用户的性别,年龄和等级的分布情况。

每个自定义事件最多可以传10个不同的参数。

3.5.1. 计数类型

计数类型事件通常用来描述一个事件累积发生的次数,适用的场景如按钮点击、界面进入、用户输入等。这类事件的上报代码如下:

MiStatInterface.recordCountEvent("Button_Click", "Button_OK_click");

每次调用需要传入分类和主键,这类事件的value都隐式的被设置成数字“1”,不需要单独设置。统计后台会对这类事件做总发生次数、总覆盖用户数等统计计算。

3.5.2. 计算类型

计算类型事件通常用来描述一个带数值的事件的发生,适用的场景如用户消费事件,附带的数值是每次消费的金额;下载文件事件,附带的数值是每次下载消耗的时长等。这类事件的上报代码如下:

MiStatInterface.recordCalculateEvent(“user_pay”, "buy_ebook", 20);

每次调用需要传入分类、主键和对应数值,其中数值是一个long型的整数。统计后台会对这类事件做累加、分布、按次平均、按人平均等统计计算。

3.5.3. 字符串属性类型

字符串属性类型通常用来描述某个具备字符串特征的属性,适用的场景如用户性别、用户职业、用户爱好等,这类属性的取值是一个字符串值。这类事件的上报代码如下:

MiStatInterface.recordStringPropertyEvent(“user_profile”, "genda", "female");

每次调用需要传入分类、主键和字符串值。对于同一主键的字符串属性,一个设备只会保存一个,即,一个设备上报多次同一个主键的字符串属性类型,统计服务后台只会保存和统计最新的属性。

3.5.4. 数值属性类型

数值属性类型通常用来描述某个具备数值特征的属性,适用的场景如用户年龄、工作年限、游戏等级等,这类属性的取值是一个整型数值。这类事件的上报代码如下:

MiStatInterface.recordNumericEvent(“user_profile”, "age", 26);

每次调用需要传入分类、主键和数值。和字符串属性一样,对于同一主键的数值属性,一个设备只会保存一个,即,一个设备上报多次同一个主键的数值属性类型,统计服务后台只会保存和统计最新的属性。

3.6. 集成测试

小米统计服务提供了集成测试模块,通过简单的几个步骤,即可以观察到通过小米统计上传的数据,判断统计是否生效;集成测试的数据和正式数据完全隔离,互不干扰。具体步骤如下:

  • 步骤一,增加测试设备。在统计数据网站中,点击进入“集成测试”项。通过在手机端调用MiStatInterface#getDeviceID(Context
    context)获取设备标示,增加到测试设备中。

    添加测试设备

    图 1. 添加测试设备

     

  • 步骤二,客户端上传统计数据,新增的测试设备统计数据会自动展示在测试日志列表中,点击可以查看该统计日志的详情。

    查看设备统计数据

    图 2. 查看设备统计数据

     

    统计日志详情

    图 3. 统计日志详情

     

4. 崩溃日志收集

应用程序发布后,在使用过程中,可能因为各种原因而崩溃。小米统计SDK内置了崩溃日志上报功能,开发者通过调用MiStatInterface#enableExceptionCatcher(boolean
uploadImmediately)即可开启该功能。根据参数不同,开发者可以选择崩溃后实时上传崩溃日志,也可以选择和常规统计数据相同的上报策略。

5. 实时网络监控

小米统计SDK提供应用的实时网络监控功能,开发者通过调用URLStatsRecorder#enableAutoRecord,即可实现HTTP网络访问信息的自动采集,包括某HTTP请求的时长,成功失败等信息。统计后台会实时计算,并且按照地域、网络、运营商等维度展示如请求次数、请求时长、成功率、失败率等信息,方便开发者发现app中关于网络请求的潜在问题。

6. API说明

6.1. MiStatInterface

MiStatInterface类中包含统计服务的初始化方法、与页面访问和事件相关API。其定义如下:

public abstract class
  extends Object
  java.lang.Object 
  ↳ com.xiaomi.mistatistic.sdk.MiStatInterface

其中每个方法的详细描述如下:

6.1.1. public static void initialize(Context context, String appID, String appKey, String
channel)

初始化统计服务接口,必须在所有数据记录之前调用。推荐将该方法放入Application对象或者主Activity的onCreate方法中。

表 2. initialize函数参数列表

参数列表 参数说明
context (必填) Android平台上app的上下文,建议传入当前app的application context
appID (必填) 在开发者网站上注册时生成的,小米统计服务颁发给app的唯一标识
appKey (必填) 在开发者网站上注册时生成的,与appID相对应,用于验证appID是否合法
channel (选填) app的渠道信息,便于后台可按照渠道来统计应用的各项数据

 

6.1.2. public static void setUploadPolicy(int policy, long interval)

设置上报策略接口。

表 3. setUploadPolicy函数参数列表

参数列表 参数说明
policy (必填) 所需要设置的上报策略类型,取值可从UPLOAD_POLICY_REALTIME、UPLOAD_POLICY_WIFI_ONLY、UPLOAD_POLICY_BATCH、UPLOAD_POLICY_WHILE_INITIALIZE、UPLOAD_POLICY_INTERVAL、UPLOAD_POLICY_DEVELOPMENT中选取
interval (选填) 时间间隔,单位毫秒(ms)。当policy设置为UPLOAD_POLICY_INTERVAL的时候,该参数生效。

 

6.1.3. public static void recordPageStart(Activity act, String pageName)

记录界面进入事件,建议放在Activity或Fragment的onResume方法中调用。

表 4. recordPageStart函数参数列表

参数列表 参数说明
act (必填) 所在界面的Activity实例
pageName (选填) 页面的名称,如果是NULL或空字符串,则SDK会使用act的完整包名作为当前页面的名称。

 

6.1.4. public static void recordPageStart(Context context, String pageName)

记录进入事件,可以在Activity或Fragment或Service中使用。

表 5. recordPageStart函数参数列表

参数列表 参数说明
context (必填) 所在类的Context实例
pageName (必填) 页面的名称,不能为空。

 

6.1.5. public static void recordPageEnd()

记录当前页面访问结束。

6.1.6. public static void recordCountEvent(String category, String key)

记录自定义计数事件。

表 6. recordCountEvent函数参数列表

参数列表 参数说明
category (选填) 事件的分类。
key (必填) 事件的主键,是这个自定义事件的唯一标识。

 

6.1.7. public static void recordCountEvent(String category, String key, Map<String,
String> params)

记录带参数的自定义计数事件。

表 7. recordCountEvent函数参数列表

参数列表 参数说明
category (选填) 事件的分类。
key (必填) 事件的主键,是这个自定义事件的唯一标识。
params (选填) 事件的参数,支持不超过10个不同的参数。

 

6.1.8. public static void recordCalculateEvent(String category, String key, long
value)

记录自定义计算事件。

表 8. recordCalculateEvent函数参数列表

参数列表 参数说明
category (选填) 事件的分类。
key (必填) 事件的主键,是这个自定义事件的唯一标识。
value (必填) 事件的值,是一个long型的整数。

 

6.1.9. public static void recordCalculateEvent(String category, String key, long value,
Map<String, String> params)

记录带参数的自定义计算事件。

表 9. recordCalculateEvent函数参数列表

参数列表 参数说明
category (选填) 事件的分类。
key (必填) 事件的主键,是这个自定义事件的唯一标识。
value (必填) 事件的值,是一个long型的整数。
params (选填) 事件的参数,支持不超过10个不同的参数。

 

6.1.10. public static void recordStringPropertyEvent(String category, String key, String
value)

记录自定义字符串属性事件。

表 10. recordStringPropertyEvent函数参数列表

参数列表 参数说明
category (选填) 事件的分类。
key (必填) 事件的主键,是这个自定义事件的唯一标识。
value (必填) 事件的值,是一个字符串类型。

 

6.1.11. public static void recordNumericPropertyEvent(String category, String key, long
value)

记录自定义数值属性事件。

表 11. recordNumericPropertyEvent函数参数列表

参数列表 参数说明
category (选填) 事件的分类。
key (必填) 事件的主键,是这个自定义事件的唯一标识。
value (必填) 事件的值,是一个long型的整数。

 

6.1.12. public static void triggerUploadManually()

手动触发上报,该调用仅会在当上报策略设置为UPLOAD_POLICY_DEVELOPMENT时起作用。

6.1.13. public static final String getDeviceID(Context context)

获取设备标示。在接入SDK时, 通过此方法获取设备标示,添加到测试设备中,就可以在测试数据列表中看到该设备上报的统计数据。

6.1.14. public static void enableExceptionCatcher(boolean uploadImmediately)

开启app崩溃日志上传功能。为了能够采集app所有的崩溃,建议在Application的onCreate方法中调用本方法。

表 12. enableExceptionCatcher函数参数列表

参数列表 参数说明
uploadImmediately 崩溃发生时,是否立即上传崩溃的日志。如果设置为true,立即上传;否则,采用和统计日志相同的上报策略。

 

6.1.15. public static boolean isExceptionCatcherEnabled()

返回当前是否开启了崩溃日志上报。

6.1.16. public static boolean shouldExceptionUploadImmediately()

返回是否应该立即上传崩溃日志。只有用户开启崩溃日志上传,并且设置为实时上传时,本方法返回true;否则返回false。

6.2. URLStatsRecorder

URLStatsRecorder包含HTTP网络监控相关的方法。其定义如下:

public class
  extends Object
  java.lang.Object 
  ↳ com.xiaomi.mistatistic.sdk.URLStatsRecorder

其中每个方法的详细描述如下:

6.2.1. public static boolean enableAutoRecord()

开启HttpURLConnection和HttpsURLConnection的网络连接信息自动采集。如果开启成功,返回true;否则返回false。如果开启成功,所有通过HttpURLConnection和HttpsURLConnection完成的网络请求,包括普通GET,POST等或者文件下载,其请求时长、成功、失败等信息都会自动采集。如果开启失败,开发者需要自行采集这些信息,以HttpEvent的方式,加入到统计服务中。

6.2.2. public static void addHttpEvent(HttpEvent event)

添加一个HttpEvent。对比如Socket连接,Apache的HttpClient,AndroidHttpClient等不会自动采集的网络请求,可以自行收集请求的相关信息,以HttpEvent的形式上报。调用此方法并不会立即触发一次上报,SDK会根据服务器配置的延迟和概率,自行决定上报时机。

6.2.3. public static void setEventFilter(HttpEventFilter eventFilter)

设置HttpEventFilter。所有SDK采集的数据,都会通过该eventFilter进行处理后再上传。如果不设置eventFilter,SDK会使用默认的filter,对所有采集数据的url,去掉url的参数,只保留问号之前的部分。通过此方法,开发者可以做到

  • 屏蔽某些URL信息的上传。
  • 将某些URL进行合并或者归类;比如去掉参数信息。比如对于一个Http的GET请求,URL中可能包含参数信息,如http://data.mistat.xiaomi.com/demoget?appid=123&package=com.xiaomi.statsdemo,
    其中的appid和package随着app不同而不同,此时,开发者可以通过filter,将采集的URL合并成http://data.mistat.xiaomi.com/demoget?,一方面可以去掉一些敏感参数,一方面可以对不规则的URL做合并。

6.3. HttpEvent

一个网络监控事件。

public class
  extends Object
  java.lang.Object 
  ↳ com.xiaomi.mistatistic.sdk.data.HttpEvent

其中每个方法的详细描述如下:

6.3.1. public HttpEvent(String url, long timeCost)

表 13. 参数列表

参数列表 参数说明
url 对应事件的URL或者host
timeCost 该url请求耗费的的时间,单位ms。

 

6.3.2. public HttpEvent(String url, long timeCost, long netFlow)

表 14. 参数列表

参数列表 参数说明
url 对应事件的URL或者host
timeCost 该url请求耗费的的时间,单位ms。
netFlow 该url请求耗费的的流量。

 

6.3.3. public HttpEvent(String url, long timeCost, long netFlow, int responseCode)

表 15. 参数列表

参数列表 参数说明
url 对应事件的URL或者host
timeCost 该请&#27#27714;耗费的的时间,单位ms。
netFlow 该请求耗费的的流量。
responseCode 该请求的Http的Response Code。

 

6.3.4. public HttpEvent(String url, long timeCost, String exceptionName)

表 16. 参数列表

参数列表 参数说明
url 对应事件的URL或者host
timeCost 该请求耗费的的时间,单位ms。
exceptionName 该url过程中发生的exception名字。

 

6.3.5. public HttpEvent(String url, long timeCost, int responseCode, String
exceptionName)

表 17. 参数列表

参数列表 参数说明
url 对应事件的URL或者host
timeCost 该请求耗费的的时间,单位ms。
responseCode 该请求的Http的Response Code。
exceptionName 该url请求过程中发生的exception名字。

 

6.3.6. public HttpEvent(String url, long timeCost, long netFlow, int responseCode, String
exceptionName)

表 18. 参数列表

参数列表 参数说明
url 对应事件的URL或者host
timeCost 该请求耗费的的时间,单位ms。
netFlow 该请求耗费的的流量。
responseCode 该请求的Http的Response Code。
exceptionName 该url请求过程中发生的exception名字。

 

6.3.7. public HttpEvent(String url, String exceptionName)

表 19. 参数列表

参数列表 参数说明
url 对应事件的URL或者host
exceptionName 该url请求过程中发生的exception名字。

 

6.3.8. public void setUrl(String url)

设置url或者host。

表 20. 参数列表

参数列表 参数说明
url 对应事件的URL或者host

 

6.3.9. public String getUrl()

获取当前的url。

6.3.10. public JSONObject toJSON() throws JSONException

获取当前的事件的JSON表达形式。

6.4. HttpEventFilter

HttpEvent的filter。开发者可以通过filter来过滤或者修改SDK采集的数据。

public interface com.xiaomi.mistatistic.sdk.controller.HttpEventFilter

其中每个方法的详细描述如下:

6.4.1. public HttpEvent onEvent(HttpEvent event)

SDK采集到一个HttpEvent,通过onEvent处理后再上报给服务器。返回修改后的HttpEvent;如果希望SDK不要上报该事件,返回null。

表 21. onEvent函数参数列表

参数列表 参数说明
event SDK采集到的HttpEvent。