1 如何查看埋点方案

在进行埋点前,需要确定在哪里埋点、埋哪些点等,即需要梳理清楚明确的埋点需求。在QuickTracking平台中将明确的埋点需求称为埋点方案,并为埋点方案设计了规范模板。如下:

image

在埋点方案中,明确的所需埋点内容有:

1、事件主体:指“谁”触发了这个事件,分为设备ID账号ID,上报的事件务必具备其中之一。

  • 设备ID:Android设备和iOS设备的默认设备ID为应用级别唯一的设备ID,由Quicktracking自动生成

    • Android9及以下设备:SDK自动采集imei、wifimac、androidid、SN生成设备ID,生成后存入本地,只有卸载应用或者删除应用数据才会重新生成设备ID。

    • Android10级以上设备:SDK自动采集oaid、gaid、androidid、SN生成设备ID,生成后存入本地,只有卸载应用或者删除应用数据才会重新生成设备ID。

    • iOS设备:SDK自动采集openudid生成设备ID,生成后放入keychain中,只有恢复出厂设置或者删除应用数据才会重新生成设备ID。

    • 使用应用的C端用户同意采集idfa和oaid,QuickTracking SDK才会采集,只有QuickTracking app SDK可以采集到oaid、gaid、imei、wifimac、androidid、SN、idfa、idfv。

  • 账号ID:客户端用户登录后账号标识,当一个用户在不同的设备进行登录时,设备ID会发生变化,但是账号ID不会发生变化。例如一个用户使用手机和pad分别登录。

2、用户属性:针对账号ID的属性,例如账号ID为“testdemo@111”的用户,“生日”为“1999-02-13”,“会员等级”为“铂金”等。“生日”和“会员”等级就为用户属性。

3、渠道属性:广告投放的属性,例如投放渠道、投放方式、投放内容等。

4、全局属性:在全局设置一次后,每一个事件都会携带的属性

5、页面浏览事件:页面加载时上报的事件(埋点方案中页面编码和事件编码相等的事件,也是标记为蓝色的事件)

6、点击、曝光、自定义事件:客户端用户与客户端发生任意交互时上报的事件。

2 设置设备ID&账号ID

2.1 设备ID设置

SDK 在com.quick.qt.commonsdk 包路径下实现了默认的设备标识符采集工具类DefaultDeviceInfo,此默认实现类默认会采集如下标识。

设备标识或设备信息

采集方法

备注

AndroidID

String getAndroidID(Context context)

Android ID

Serial

String getSerial()

Android手机设备序列号

IMEI

String getImei(Context context)

IMEI

IMSI

String getImsi(Context context)

IMSI

WiFi-Mac

String getWifiMac(Context context)

WiFi-Mac

OAID

String getOaid(Context context)

广告ID(国内)

GAID

String getGaid(Context context)

Google广告ID

MCCMNC

String getMCCMNC(Context context)

MCC:移动国家编码

MNC:移动网号

接口返回值:MCC值和MNC值拼接结果,MCC是3位整数,MNC为两位整数。例如:46011

如果开发者希望针对上表中的某几个设备标识符采集行为做控制,如:不采集IMEI字段和Serial字段,自行实现OAID的采集方法。就可以实现一个DefaultDeviceInfo类的子类,重载getImei,getSerial,getOaid三个采集方法,如下示例:

public class CustomDeviceInfo extends DefaultDeviceInfo {

	@Override
	public String getImei(Context context) {
		return null;
	}

	@Override
	public String getSerial() {
		return null;
	}

	@Override
	public String getOaid(Context context) {
		String oaid = "";
        // oaid = getOaidMethod(); // 您自己的 oaid 获取方法
        return oaid;
	}

}

请注意:如果不进行重载,则默认由QuickTracking SDK采集,请谨慎决定是否实现对应方法,一旦您选择自己实现采集方法,此设备标识的采集工作就由您全权接管了,SDK不会再试图采集此设备标识。SDK能采集到的设备标识越少,对统计数据的准确性和稳定性的负面影响越大。

自定义工具类注册:

// 请在设置收数域名之前,调用SDK预初始化函数之前,先调用采集工具类注册函数
// 如果不需要对设备标识采集行为做控制,就不需要实现自定义工具类并注册它。
QtConfigure.setDeviceInfo(new CustomDeviceInfo());
QtConfigure.setCustomDomain("您的收数服务域名", null);

SDK支持自定义设备ID,如果要使用自定义设备ID需要在初始化前(即init前) 设置setCustomDeviceId 接口为有效值(非空)。

public static void setCustomDeviceId(Context var0, String var1)

使用示例:

QtConfigure.setCustomDeviceId(this, "xxxxxx");

注意:因此功能在未获取设备ID时生效,本地如果已存在设备ID,设置后无效。如果本地已获取到设备ID可以通过卸载重装方式验证此功能。

设备ID的获取

可使用下述方法获取:

QtConfigure.getUMIDString()

2.2 账号ID设置

1、在统计用户时以设备为标准,如果需要统计应用自身的账号,请使用以下接口:

public static void onProfileSignIn(String ID);

参数

含义

ID

用户账号ID,长度小于64字节

注意:账号ID设置后将被存入本地存储,只有卸载App、清空应用数据或者调用下述的登录接口时,账号ID才会失效,否则每一个事件都将携带账号ID。

2、账号登出时需调用此接口,调用之后不再发送账号相关内容。

public static void onProfileSignOff();

示例:

//当用户使用自有账号登录时,可以这样统计:
QtTrackAgent.onProfileSignIn("userID");

//登出
QtTrackAgent.onProfileSignOff();

3 设置用户属性

通过预置事件编码 $$_user_profile 上报用户属性。

在上报用户属性之前,需要先设置_user_id上报用户账号,否则QuickTracking流量分析对用户属性不会进行关联计算。确认上报用户的账号ID后,上报用户属性示例如下:

Map<String, Object> user = new HashMap<String, Object>();
user.put("sex", "girl");//性别
user.put("age", "8"); //年龄
QtTrackAgent.onEventObject(mContext, "$$_user_profile", user);

4 渠道属性

4.1 H5链接唤起App

渠道属性无需进行任何埋点,但是需要唤起小程序或App的URL中携带这些渠道属性,且属性key务必以“utm_”开头,因为SDK识别的关键字为“utm_”。例如:

<URL scheme>?utm_channel=gzh

PS:如果渠道属性已经与市面上渠道投放公司进行了合作,无法使用utm_开头,可以使用全局属性API将渠道属性进行埋点上报(属性key依然需要以“utm_”开头)。

4.2 H5链接唤起应用市场下载并启动App

该场景下,如果仅是H5链接中携带“utm_”参数,已经无法做到下载App后的启动事件携带“utm_”参数。所以需要进行“H5唤起事件”与“应用激活事件”做关于“IP地址和浏览器UserAgent”的模糊匹配。

  1. 当用户在H5中点击「唤起/下载App」的按钮时,上报“应用唤起事件($$_app_link)”,在事件中需要携带唤起App的appkey和渠道属性。

//示例
aplus_queue.push({
  action:'aplus.recordAppLink',
  arguments:[{
    targetAppKey: '要唤起的应用appKey',  // 必填,要唤起的应用appKey
    custom1: 'custom1', // 选填,自定义参数
    ...
  }]
})
  1. App下载后的第一次启动事件“应用激活事件($$_app_install)”由QT App SDK自动采集上报。

  2. QuickTracking系统进行应用唤起事件($$_app_link)和应用激活事件($$_app_install)关于“IP地址和浏览器UserAgent”的模糊匹配。您使用时,可以直接在app应用中分析“应用激活(预置)”的渠道属性即可。

4.3 App各应用市场活跃数据统计

在初始化函数中的第三个入参Channel即为设置该应用的应用市场:QtConfigure.preInit(this,"您的appkey","Channel-华为");QtConfigure.init(this,"您的appkey","Channel-华为",QtConfigure.DEVICE_TYPE_PHONE, "");

5 全局属性

注册全局属性后,后续触发的所有事件都将自动包含这些属性;且这些属性及属性值存入缓存,APP退出后清除。在分析数据时,可根据此属性进行查看和筛选。

5.1 注册一个全局属性

public static void registerGlobalProperties(Context var0, Map<String, Object> var1);

参数

含义

var0

当前宿主进程的ApplicationContext上下文。

propertyName

属性名。

propertyValue

属性值。

注意:

  1. 属性名、String类型的属性值,只支持大小写字母、数字及下划线!

  2. 属性值可以是如下几种Java类型之一:String、Long、Integer、Float、Double、Short。

  3. 如果和已经存在的全局属性key重复,则更新已有值;如果和已经存在的全局属性key不一致,则插入新的全局属性。

    示例:

    Map firstMap = new HashMap<String, Object>();
    firstMap.put("a", "1");
    firstMap.put("b", "2");
    QtTrackAgent.registerGlobalProperties(mContext, firstMap);//当前globalproperty为a:1和b:2
    
    Map secondMap = new HashMap<String, Object>();
    secondMap.put("b", "3");
    secondMap.put("c", "4");
    QtTrackAgent.registerGlobalProperties(mContext, secondMap);//当前globalproperty为a:1、b:3和c:4

5.2 删除一个全局属性

public static void unregisterGlobalProperty(Context context, String propertyName);

参数

含义

context

当前宿主进程的ApplicationContext上下文。

propertyName

属性名,只支持大小写字母、数字及下划线!

示例:

删除一个特定的全局属性,删除后,后续触发的所有事件都不再携带该属性。

QtTrackAgent.unregisterGlobalProperty(mContext, "lnch_Source");

5.3 根据Key获取单个全局属性

public static Object getGlobalProperty(Context context, String propertyName);

参数

含义

context

当前宿主进程的ApplicationContext上下文。

propertyName

属性名,只支持大小写字母、数字及下划线!

Object(返回值)

返回的全局属性值类型可以是如下几种Java类型之一:String、Long、 Integer、Float、Double、Short。必须和注册此全局属性时传入参数类型一致。

示例:

String userId = QtTrackAgent.getGlobalProperty(mContext, "lnch_Source");

5.4 获取所有全局属性

public static String getGlobalProperties(Context context);

参数

含义

context

当前宿主进程的ApplicationContext上下文。

String(返回值)

返回字符串中包含所有全局属性及对应的属性值,以 K-V键值对 形式表示全局属性-属性值。多个键值对间用逗号分割。数据外层是大括号。如:{"id":"SA1375","userName":"Mike","account_type":"vip", "MemberLevel":"Level1"}

示例:

String allSuperProp = QtTrackAgent.getGlobalProperties(mContext);

5.5 清除所有的全局属性

public static void clearGlobalProperties(Context context);

参数

含义

context

当前宿主进程的ApplicationContext上下文。

示例:

QtTrackAgent.clearGlobalProperties(mContext);

6 页面浏览事件API

6.1 页面手动采集

开发者如果希望对Activity、Fragment、CustomView及其它自定义页面的页面路径和页面停留时长进行采集和统计。可以通过调用QtTrackAgent.onPageStart/QtTrackAgent.onPageEnd这组接口进行手动埋点。

public static void onPageStart(String viewName);
public static void onPageEnd(String viewName);

参数

含义

viewName

自定义页面名。

手动统计Fragemnt页面路径的例子代码:

// 一次成对的 onPageStart -> onPageEnd 调用,对应一次非Activity页面(如:Fragment)生命周期统计。

// Fragment页面onResume函数重载
public void onResume() {
    super.onResume();
    QtTrackAgent.onPageStart("MainScreen"); //统计页面("MainScreen"为页面编码,可自定义)   
}

// Fragment页面onResume函数重载
public void onPause() {
    super.onPause();
    QtTrackAgent.onPageEnd("MainScreen");
}

注意:

onPageStart 是SDK记录页面进入的信息,onPageStart不会上报事件,只有调用onPageEnd的时候才会上报页面浏览事件。

onPageStart和onPageEnd必须成对调用,且传值的page_name需要保持一致,如果没有onPageEnd或者onPageEnd与onPageStart传值的page_name不一致,则onPageStart记录的信息不会生效。

6.1.1 页面属性上传

QtTrackAgent.setPageProperty(),支持给当前页面附加自定义属性。

接口:QtTrackAgent.setPageProperty

参数:

参数

含义

context

当前Application的上下文。

pageName

目标页面名,必须和当前页面名一致。如不一致,函数执行无效。

pageProperty

需要关联到页面的k-v键值对参数。value值支持String,Integer,Long,Float,Short,Double类型。

示例:

Activity页面开始展现时进行当前页面属性设置示例:

private static final String PAGE_NAME = "page_home"; // 页面名
 
 @Override
 public void onResume() {
    super.onResume();
   
    QtTrackAgent.onPageStart(PAGE_NAME); // 页面开始展现打点
    Map<String, Object> params = new HashMap<>();
    params.put("home_param_1", "value11"); // 当前页面相关属性设置
    QtTrackAgent.setPageProperty(mContext, PAGE_NAME, params);
 }

请注意:页面属性设置只支持页面手动埋点

6.1.2 透传页面属性

此外,QuickTracking SDK提供了SpmAgent.updateNextPageProperties接口,该接口支持给下一个页面附加自定义属性。

接口:SpmAgent.updateNextPageProperties

参数:

参数

含义

params

需要透传的k-v键值对Map。value值支持String,Integer,Long,Float,Short,Double类型。

/**
* 
当需要将当前坑位属性透传给⽬标⻚⾯时调用
* 
此函数在通过坑位跳转到下⼀个⽬标⻚⾯时调⽤。
*/
public static void updateNextPageProperties(Map<String, Object> params)

示例:

public class PageHome extends Activity {
    private Context mContext;
    private static final String PAGE_NAME = "page_home"; // 页面名
    private static final String PAGE_SPM_CNT = "1.1.0.0"; // 页面spm编码

    // 跳转到news的坑位 spm 编码
    private static final String PAGE_SPM_TO_NEWS = "1.1.0.1"; // 按钮控件mGoNewsWithHole spm编码
    private Button mGoNewsWithHole;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle("QuickTracking统计Home页");
        setContentView(R.layout.activity_u4a_home);

        mContext = this;

        mGoNewsWithHole = (Button)findViewById(R.id.u4a_goto_page_news2);
        mGoNewsWithHole.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 带坑位spm的跳转
                SpmAgent.updateCurSpm(mContext, PAGE_SPM_TO_NEWS); // 跳转按钮控件spm编码
                Map<String, Object> params = new HashMap<String, Object>();
                
                params.put("my_transfer_arg1", "transfer_value1");
                SpmAgent.updateNextPageProperties(params); // 
                startActivity(new Intent(mContext, PageNews.class));
            }
        });
    }

请注意:透传页面属性只支持页面手动埋点

6.2 Activity页面自动采集(全埋点)

Activity页面默认开启页面自动采集,无须集成全埋点的gradle 插件。SDK在采集会话数据时,默认会主动采集每个Activity页面的路径和页面访问时长数据并上报。如果开发者同时调用页面路径手动采集API QtTrackAgent.onPageStart/onPageEnd,则会导致页面数据重复上报,产生冗余页面路径数据,可以在调用QtConfigure.preInit预初始化函数后紧接着调用QtTrackAgent.disableActivityPageCollection()函数禁止SDK自动采集Activity页面路径数据。

public static void disableActivityPageCollection();

若只需禁止某activity页面的自动采集上报的接口,需要在activity的onCreate函数中调用此函数:

QtTrackAgent.skipMe(this, null); 

参数

类型

备注

this

Activity对象

WebView宿主Activity对象,该参数控制当前页面的自动页面数据是否上报,传this则表示不上报。

viewName

字符串

手动埋点时的自定义页面编码,该参数控制当前页面的手动埋点页面数据是否上报,传空则表示上报,传自定义页面编码则表示不上报。

6.3 Fragment页面自动采集(全埋点)

Fragment页面默认没有自动采集,需要集成全埋点的插件并开启自动采集开关才可以。具体操作可以查看

8.1 全埋点gradle插件引入开启Fragment PV数据全埋点

7 事件埋点

自定义事件可以用于追踪用户行为,记录行为发生的具体细节。

7.1 事件埋点

使用onEventObject接口进行事件的统计,参数值可以是如下几种类型之一:StringLongIntegerFloatDoubleShort

接口:

public static void onEventObject(Context context, String eventID, Map<String, Object> map)

public static void onEventObject(Context context, String eventID, Map<String, Object> map, String pageName)

参数

含义

context

当前宿主进程的ApplicationContext上下文。

eventId

为当前统计的事件ID。

map

对当前事件的参数描述,定义为“参数名:参数值”的HashMap“<键-值>对”。

pageName

事件发生时的页面编码

事件上传数量限制:

  • 自定义属性key字符串长度上限:1024

  • 自定义属性value字符串长度上限:1024*4

  • 自定义属性map长度(参数个数):100 个键值对

  • 当自定义属性值value为数组元素时,属性值的数组长度上限:100

示例:

Map<String, Object> music = new HashMap<String, Object>();
music.put("music_type", "popular");//自定义参数:音乐类型,值:流行
music.put("singer", "JJ"); //歌手:(林俊杰)JJ
music.put("song_name","A_Thousand_Years_Later"); //歌名:一千年以后
music.put("song_price",100); //价格:100元
QtTrackAgent.onEventObject(this, "play_music", music, "home_page");

备注:

  • 当前拉取事件采样率配置依赖于自动采集开关,使用SDK时需要调用setAutoEventEnabled()方法;

    示例:

    public class MyApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    	QtConfigure.setCustomDomain("您的收数服务域名", null);
            // 打开调试log
            QtConfigure.setLogEnabled(true);
            // 采样率拉取依赖全埋点开关设置,如需要事件采样率控制功能,请按需调用此API
            QtTrackAgent.setAutoEventEnabled(false);        
            //...
        }
        //... 
    }
  • 多参数类型事件能满足原来计算事件/计数事件的分析场景;

  • 对于计算型事件不同的参数类型对应不同的计算方式,总共可以分为两大类,数值型和字符型

    • 数字型:支持累加值、最大值、最小值、平均值和去重数计算

    • 字符型:支持去重数计算

7.2 子进程埋点

SDK仅支持子进程自定义事件埋点,页面等其他类型采集暂不支持。子进程埋点需要在SDK初始化完成后调用函数QtConfigure.setProcessEvent。

示例:

public class UmengApplication extends Application{
    @Override
    public void onCreate(){
        super.onCreate();
        // 初始化SDK
        QtConfigure.preInit(this, "您的appkey", "应用市场");
        
        // 支持在子进程中统计自定义事件
        QtConfigure.setProcessEvent(true);
        // ...

注意:

  • 如果需要在某个子进程中统计自定义事件,则需保证在此子进程中进行SDK初始化。

8 全埋点(自动埋点)

8.1 全埋点gradle插件引入

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

说明

注意:

  • Android Plugin 需要 Android Gradle Plugin 3.2.0+,否则会导致元素点击事件和 Fragment 的页面浏览事件无法触发。

buildscript {
    repositories {
        maven { url 'https://repo1.maven.org/maven2/' } // QuickTracking仓库
        jcenter()
            google()
        }
    
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.4'
            
            // 添加QuickTracking插件 android-gradle-plugin 依赖
            //classpath 'com.umeng.umsdk:android-gradle-plugin:1.0.1' 
            classpath 'com.lydaas.qtsdk:quick-gradle-plugin2:1.0.2'
            // 适配 gradle 8+版本
            // classpath 'com.lydaas.qtsdk:quick-gradle-plugin2:2.0.0'
        }
}

allprojects {
    repositories {
        maven { url 'https://repo1.maven.org/maven2/' } // QuickTracking仓库
        jcenter()
            google()
        }
}

说明

注意:

  • 在App根工程目录下gradle.properties文件中org.gradle.jvmargs参数值追加 “-noverify” 参数。

  • 如果App根工程目录下没有gradle.properties文件,请自行创建此文件。如果此文件中之前没有org.gradle.jvmargs参数,需开发者自行增加此参数,并在参数值中指定/或追加 -noverify参数值。

image.png

8.2 依赖使用gradle编译插件

在主 module 的 build.gradle 配置中应用全埋点插件:

apply plugin: 'com.android.application'
//apply plugin: 'com.qt.analytics.plugin' // P版本插件(全埋点场景)
apply plugin: 'com.quick.analytics.plugin' // PX版本插件(全埋点场景)

dependencies {
   // 添加 QuickTracking 统计SDK,SDK版本需要与上述的gradle版本匹配
   //implementation 'com.umeng.umsdk:qt-common:1.4.4.P' //P版本(SDK版本为x.x.x.P)
   implementation 'com.lydaas.qtsdk:qt-px-common:1.4.9.PX'  // PX版本(SDK版本为x.x.x.PX)
}

8.3 全埋点API

8.3.1 全埋点开关

开启Fragment PV数据全埋点

通过 enableFragmentPageCollection() 方法可以开启全部 Fragment 页面浏览事件的自动采集功能。

/**
* Fragment 页面数据自动采集开关,SDK默认关闭
* @param enable true-开启; false-关闭
*/
public static void enableFragmentPageCollection(boolean enable);

示例:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
	QtConfigure.setCustomDomain("您的收数服务域名", null);
        // 打开调试log
        QtConfigure.setLogEnabled(true);
        // 开启全部 Fragment 页面浏览事件的自动采集功能
        QtTrackAgent.enableFragmentPageCollection(true);
        //...
    }
    //... 
}

开启Activity PV数据开关

默认开启Activity页面自动采集,SDK在采集会话数据时,默认会主动采集每个Activity页面的路径和页面访问时长数据并上报。如果开发者同时调用页面路径手动采集API QtTrackAgent.onPageStart/onPageEnd,则会导数页面数据重复上报产生冗余页面路径数据,可以在调用QtConfigure.preInit预初始化函数后紧接着调用QtTrackAgent.disableActivityPageCollection()函数禁止SDK自动采集Activity页面路径数据。

public static void disableActivityPageCollection();

若只需禁止某activity页面的自动采集上报的接口,需要在activity的onCreate函数中调用此函数:

QtTrackAgent.skipMe(this, null); 

关闭某个页面的自动采集

若只需禁止某activity页面的自动采集上报的接口,需要在activity的onCreate函数中调用此函数:

QtTrackAgent.skipMe(this, null); 

参数

类型

备注

this

Activity对象

WebView宿主Activity对象,该参数控制当前页面的自动页面数据是否上报,传this则表示不上报。

viewName

字符串

手动埋点时的自定义页面编码,该参数控制当前页面的手动埋点页面数据是否上报,传空则表示上报,传自定义页面编码则表示不上报。

开启控件点击数据全埋点
/**
 * 拉取事件采样率配置。
 * 设置是否自动采集控件点击事件, SDK默认不自动采集。
 * @param enable true-自动采集; false-不自动采集
 */
public static void setAutoEventEnabled(boolean enable);

示例:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
	QtConfigure.setCustomDomain("您的收数服务域名", null);
        // 打开调试log
        QtConfigure.setLogEnabled(true);
        QtTrackAgent.enableFragmentPageCollection(true);
        // 开启控件点击事件的自动采集功能。
        QtTrackAgent.setAutoEventEnabled(true);
        //...
    }
    //...
    
}

支持自动监控的控件类型列表:

控件名称

备注

CheckBox

针对onCheckedChanged 方法自动插桩打点

RadioButton

针对onCheckedChanged 方法自动插桩打点

ToggleButton

Switch

Button

ImageButton

CheckedTextView

TextView

ImageView

RatingBar

针对onRatingChanged方法自动插桩打点

SeekBar

针对onStopTrackingTouch方法自动插桩打点

Spinner

ListView

ExpandableListView

RecyclerView

仅支持RecyclerView Item内部子控件事件自动采集

TabHost

TabLayout

MenuItem

Dialog

GridView

Layout

实现了点击事件响应函数的Layout对象及子类生成对象。

8.3.2 自动Activity/Fragment PV设置自定义属性

通过给特定Activity/Fragment 实现接口 com.umeng.analytics.autotrack.PageAutoTracker,可以给自动采集的Activity/Fragment页面定制化属性、页面名、或者来源页面名。

public interface PageAutoTracker {
    /**
     * 返回当前页面名
     * @return 如果不需要自定义页面名则返回null或者空字符串
     */
    String getPageName();

    /**
     * 返回来源页面名
     * @return 如果不需要自定义来源页面名则返回null或者空字符串
     */
    String getRefPageName();

    /**
     * 返回自定义属性键值对,Key和Value都需要是字符串类型,如果没有自定义属性请返回null
     *
     * @return 如果没有自定义属性请返回null
     */
    Map<String, String> getTrackProperties();
}

示例:

// 给FragmentContacts指定 自定义页面名 及 自定义页面属性
public static class FragmentContacts extends Fragment implements PageAutoTracker {
        private final String mPageName = "FragmentContacts";

        static FragmentSimple newInstance(int num) {
            FragmentSimple f = new FragmentSimple();

            // Supply num input as an argument.
            Bundle args = new Bundle();
            args.putInt("num", num);
            f.setArguments(args);

            return f;
        }

        /**
         * The Fragment's UI is just background simple text view showing its instance
         * number.
         */
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            FrameLayout fl = new FrameLayout(getActivity());
            fl.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.MATCH_PARENT));
            fl.setBackgroundColor(Color.LTGRAY);
            TextView tv = new TextView(getActivity());
            tv.setText("Fragment Contacts");
            tv.setTextColor(Color.BLACK);
            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    QtTrackAgent.ignoreView(v); // 禁止TextView控件的自动采集数据上报
                    Toast.makeText(getActivity(), "文本框被点击了", Toast.LENGTH_LONG).show();
                }
            });
            fl.addView(tv);
            return fl;
        }

        // 自定义FragmentContacts页面名
        @Override
        public String getPageName() {
            return "FragmentContacts";
        }

    	// 不需要自定义FragmentContacts的来源页面名,所以直接返回null
        @Override
        public String getRefPageName() {
            return null;
        }

    	// 自定义FragmentContacts页面自定义属性
        @Override
        public Map<String, String> getTrackProperties() {
            Map<String, String> properties = new HashMap<>();
            properties.put("fragment_arg1", "fragment_value111");
            properties.put("fragment_arg2", "fragment_value222");
            return properties;
        }
    }

8.3.3 设置控件点击事件自定义属性

通过 setViewProperties() 方法,可以对特定控件设置自定义属性,自定义属性可以设置多个K-V键值对,Key和Value都需要是字符串类型。自定义属性和值会包含在此控件全埋点点击事件数据中。

/**
* 设置控件自定义属性,自定义属性可以设置多个K-V键值对,Key和Value都需要是字符串类型
* @param view 控件对象
* @param properties 自定义属性
*/
public static void setViewProperties(View view, JSONObject properties);

示例:

	@QtDataTrackViewOnClick
    public void onButtonClick(View v) {
        int id = v.getId();
        Intent in = null;
        if (id == R.id.normal) {
        	// 对Resource ID为 normal 的Button控件设置自定义事件ID ekv_normal。
        	// 设置后,点击此控件是SDK上报数据中事件ID就为"ekv_normal"。
            QtTrackAgent.setViewEventID(v, "ekv_normal");
            // 针对 normal Button控件点击事件(即ekv_normal 事件),设置自定义属性值。
            // customArgs内属性和属性值会包含在"ekv_normal"事件数据中一起上报。
            JSONObject customArgs = new JSONObject();
            try {
                customArgs.put("customArg1", "value1111");
                customArgs.put("customArg2", "value2222");
            } catch (JSONException e) {

            }
            QtTrackAgent.setViewProperties(v, customArgs);

8.3.4 给控件点击事件设置自定义事件编码

通过 setViewEventID() 方法,给特定控件的点击事件设置自定义事件编码。

/**
* 针对自动采集的控件点击事件,设置自定义事件编码
* @param view 控件对象
* @param eventID 自定义事件编码
*/
public void setViewEventID(View view, String eventcode);

示例:

    @QtDataTrackViewOnClick
    public void onButtonClick(View v) {
        int id = v.getId();
        Intent in = null;
        if (id == R.id.normal) {
        	// 对Resource ID为 normal 的Button控件设置自定义事件编码 ekv_normal。
        	// 设置后,点击此控件是SDK上报数据中事件编码就为"ekv_normal"。
            QtTrackAgent.setViewEventID(v, "ekv_normal");
            	//...

8.3.5 处理通过 onClick 属性设置的点击事件

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

布局文件:

<Button
        android:id="@+id/normal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:onClick="onButtonClick"
        android:text="@string/ana_name"/>

onClick事件自定义处理函数:

import com.umeng.analytics.autotrack.QtDataTrackViewOnClick;

	@QtDataTrackViewOnClick
    public void onButtonClick(View v) {
         //...
    }

8.3.6 忽略特定类型控件点击事件的自动采集

通过 ignoreViewType() 方法忽略特定类型控件点击事件的自动采集。

/**
* 忽略viewType类型控件点击事件的自动采集行为。
* 该方法支持多次调用,对设置结果合集进行忽略。
* @param viewType
*/
public static void ignoreViewType(Class viewType);

示例:

// 忽略Button类型控件点击事件
QtTrackAgent.ignoreViewType(Button.class);

8.3.7 忽略特定控件点击事件的自动采集

通过 ignoreView() 方法忽略特定控件点击事件的自动采集。

/**
* 忽略某个 View 对象的点击事件自动采集行为。
*
* @param view 对象
*/
public static void ignoreView(View view);

示例:

Button myButton = (Button)findViewById(R.id.testButton);
// 忽略myButton控件点击事件
QtTrackAgent.ignoreView(myButton);

9 分享裂变

分享裂变是增长黑客策略的一个关键概念,它依靠用户之间的社交联系来实现信息的相互传递,从而促进新用户的获取。

完成分享裂变的SDK功能集成,您将可以使用QuickTracking平台分享趋势模型,通过分享回流相关指标衡量营销活动的拉新效益。

  1. 支持查看TOP分享用户和不同分享回流层级的分享回流效果指标。

  2. 支持回流指标灵活组合配置,查看最具裂变拉新能力和分享回流转化能力的TOP用户,追踪用户分享裂变链路与分享回流关系,快速定位关键意见消费者。

9.1 获取来源分享参数

import com.quick.qt.analytics.QtTrackAgent;
/**
 * 来源分享参数获取API
 * @param context 宿主App的ApplicationContext对象。必须传入
 * */
public static Map<String, String> getRefShareParams(Context context);

版本

Android SDK v1.6.0.PX版本及以上

功能

在请求分享参数之前,用于获取来源分享id 和来源分享 url 的 API

请求参数

参数

类型

默认值

含义

备注

context

Context

null

宿主App 的 ApplicationContext 上下文

必须传入,不能为 null

返回参数

参数

类型

默认值

含义

备注

$$_ref_share_url

String

null

不包含分享 id 的来源分享 url

"$$_ref_share_id

String

null

来源分享 id

调用示例

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.analytics.share.ShareResultHandler;

public class DemoActivity {
    ...
    public void onShare() {
        Context context = DemoActivity.this;
        Map<String, String> refShareParams = QtTrackAgent.getRefShareParams(context);
        String $$_ref_share_id = refShareParams.get("$$_ref_share_id");
        
        Map<String, String> shareParams = new HashMap<String, String>();
        shareParams.put("shareId", $$_ref_share_id);
        shareParams.put("title", "分享活动A");
        shareParams.put("campaign", "分享活动A");
        QtTrackAgent.requestShareParams(context, "https://www.taobao.com/productId", shareParams, 0, new ShareResultHandler() {
            @Override
            public void onShareResultSuccess(final JSONObject result) {
                try {
                    Log.i("Test", "shareParams = " + result.toString());
                    String $sid = result.getString("shareId");
                    Map<String, Object> properties = new HashMap<String, Object>();
                    properties.put("$$_share_id", $sid);
                    properties.put("$$_share_url", "https://www.taobao.com/productId"); 
                    properties.put("$$_share_title","分享活动A"); 
                    properties.put("$$_share_campaign_id", "这是一个自定义分享活动");
                      // 
                    properties.put("$$_share_type", "用户自定义分享目标平台");
                    QtTrackAgent.onEventObject(this, "$$_share", properties);
                    // 假设这是后台线程中的某个操作
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            // 执行一些后台任务...

                            // 需要更新UI,切回主线程
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    // 在主线程上显示对话框
                                    AlertDialog.Builder builder = new AlertDialog.Builder(context);
                                    builder.setTitle("分享参数");
                                    builder.setMessage(result.toString());
                                    builder.show();
                                }
                            });
                        }
                    }).start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onShareResultFail(Throwable t) {
                Log.i("Test", "fail = " + t.getMessage());
            }
        });
    }
    ...
}

9.2 请求分享参数

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.analytics.share.ShareResultHandler;

/**
 * 分享 url 获取API
 * @param context 宿主App的ApplicationContext对象。必须传入
 * @param url 页面的地址,必须传入
 * @param params 可能的分享参数,可为 null
 *    {
 *      title: 分享标题, 可为 null, 最大长度 4*1024
 *    campaign: 分享活动, 可为 null, 最大长度 4*1024
 *    shareId: 来源分享Id, 可为 null
 *      ... 待扩展
 *  }
 * @params timeout 请求超时时间,单位秒,有效值范围:0~10(包含0和10),如果传入0,则使用sdk内部默认值3秒
 * @param callback 结果回调对象,必须传入,不能为null
 * */
public static void requestShareParams(Context context, String url, Map<String, String> params, int timeout,final ShareResultHandler callback)

版本

Android SDK v1.6.0.PX版本及以上

功能

请求用于构建分享链需要的分享id

请求参数

参数

类型

默认值

含义

备注

context

Context

null

宿主 App 的ApplicationContext 上下文

必须传入,不能为null

url

String

null

分享页面的 url

必须传入,不能为 null

params

Map<String,String>

null

分享参数获取 API 请求参数

  • 可选参数

campaign:分享活动标识。String 类型,默认值为 "",最大长度为 4*1024 个字符

title:分享标题。String类型,默认值为 "",最大长度为 4*1024个长度

shareId:来源分享Id。String 类型,默认值为""

timeout

int

0

接口超时时间

取值范围1~10,单位为秒。sdk 默认超时时间为3秒

callback

ShareResultHandler

null

结果回调对象

必须传入, 不能为 null

注:此结果回调上下文为SDK内部网络请求后台工作线程,如果需要在回调方法中操作UI控件,请通过UI线程Handler执行相关操作。

其中 callback 的回调接口 ShareResultHandler 定义如下:

public interface ShareResultHandler {
    //本方法在分享参数成功返回时会回调
    void onShareResultSuccess(JSONObject result);
    //本方法在分享参数失败返回时会回调, 可通过t.getMessage 获取失败原因
    void onShareResultFail(Throwable t);
}

返回参数

参数

类型

默认值

含义

备注

data

JSONObject

null

分享参数 API 请求结果

包含一个属性shareId, String类型,分享id

调用示例

import com.quick.qt.analytics.QtTrackAgent;
import com.quick.qt.analytics.share.ShareResultHandler;

public class DemoActivity {
    ...
    public void onShare() {
        Context context = DemoActivity.this;
        Map<String, String> shareParams = new HashMap<String, String>();
        shareParams.put("shareId", "");
        shareParams.put("title", "分享活动A");
        shareParams.put("campaign", "分享活动A");
        QtTrackAgent.requestShareParams(context, "https://www.taobao.com/productId", shareParams, 0, new ShareResultHandler() {
            @Override
            public void onShareResultSuccess(final JSONObject result) {
                try {
                    Log.i("Test", "shareParams = " + result.toString());
                    String $sid = result.getString("shareId");

                    Map<String, Object> properties = new HashMap<String, Object>();
                    properties.put("$$_share_id", $sid);
                    properties.put("$$_share_url", "https://www.taobao.com/productId"); 
                    properties.put("$$_share_title","分享活动A"); 
                    properties.put("$$_share_campaign_id", "这是一个自定义分享活动");
                    properties.put("$$_share_type", "用户自定义分享平台");
                    QtTrackAgent.onEventObject(this, "$$_share", properties);
                    
                    // 假设这是后台线程中的某个操作
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            // 执行一些后台任务...

                            // 需要更新UI,切回主线程
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    // 在主线程上显示对话框
                                    AlertDialog.Builder builder = new AlertDialog.Builder(context);
                                    builder.setTitle("分享参数");
                                    builder.setMessage(result.toString());
                                    builder.show();
                                }
                            });
                        }
                    }).start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onShareResultFail(Throwable t) {
                Log.i("Test", "fail = " + t.getMessage());
            }
        });
    }
}

9.3 上报分享事件

通过预置事件编码 $$_share 上报分享事件

示例

Map<String, Object> properties = new HashMap<String, Object>();
properties.put("$$_share_id", "通过请求分享参数API获取到的分享ID");
properties.put("$$_share_url", "https://www.taobao.com/productId"); 
properties.put("$$_share_title","分享活动A"); 
properties.put("$$_share_campaign_id", "这是一个自定义分享活动");
properties.put("$$_share_type", "用户自定义分享平台");
QtTrackAgent.onEventObject(this, "$$_share", properties);

请注意:唤起的链接需要携带key为"$sid",value为分享Id的参数,如:https://example.aliyun.com/path/to/content?$sid=123456"