1. 如何查看埋点方案
在进行埋点前,需要确定在哪里埋点、埋哪些点等,即需要梳理清楚明确的埋点需求。在QuickTracking平台中将明确的埋点需求称为埋点方案,并为埋点方案设计了规范模板。如下:
在埋点方案中,明确的所需埋点内容有:
1、事件主体:指“谁”触发了这个事件,分为设备ID和账号ID,上报的事件务必具备其中之一。
设备ID:HarmonyNext应用的默认设备ID为应用级别唯一的设备ID,由Quicktracking自动生成:
账号ID:客户端用户登录后账号标识,当一个用户在不同的设备进行登录时,设备ID会发生变化,但是账号ID不会发生变化。例如一个用户使用手机和pad分别登录。
2、用户属性:针对账号ID的属性,例如账号ID为“testdemo@111”的用户,“生日”为“1999-02-13”,“会员等级”为“铂金”等。“生日”和“会员”等级就为用户属性。
3、渠道属性:广告投放的属性,例如投放渠道、投放方式、投放内容等。
4、全局属性:在全局设置一次后,每一个事件都会携带的属性
5、页面浏览事件:页面加载时上报的事件(埋点方案中页面编码和事件编码相等的事件,也是标记为蓝色的事件)
6、点击、曝光、自定义事件:客户端用户与客户端发生任意交互时上报的事件
2. 设备ID&账号ID&用户属性设置
2.1. 设备ID
当前版本,即@quicktracking/analytics_1.0.0版本设备ID的生成为QuickTrackingSDK自动生成,暂不支持自定义设备ID和获取当前生成的设备ID
2.2. 账号ID
QuickTracking SDK在统计用户时以设备为标准,如果需要统计自身的账号,请使用以下方法
2.2.1. 用户登入
2.2.1.1. API说明
import { onProfileSignIn } from '@quicktracking/analytics';
function onProfileSignIn(provider: string, puid: string):void
2.2.1.2. 参数说明
参数 | 类型 | 含义 | 是否必填 |
provider | string | 用户昵称,非空字符串,且长度不超过32 | 是 |
puid | string | 用户账号ID,非空字符串,且长度不超过64 | 是 |
注意:账号ID设置后将被存入本地存储,只有卸载App、清空应用数据或者调用下述的登出接口时,账号ID才会失效,否则每一个事件都将携带账号ID。
2.2.1.3. 示例代码
import { onProfileSignIn } from '@quicktracking/analytics';
Button('登入').onClick(() => {
onProfileSignIn("QuickTrackingUser", "QuickTrackingUser_demo");
})
2.2.2. 用户登出
如果不再需要绑定用户账号,可以调用SDK提供的用户登出方法,调用后,SDK不再发送用户账号相关内容
2.2.2.1. API说明
import { onProfileSignOff } from '@quicktracking/analytics';
function onProfileSignOff():void
2.2.2.2. 示例代码
import { onProfileSignOff } from '@quicktracking/analytics';
Button('登出').onClick(() => {
onProfileSignOff();
})
2.3. 用户属性上传
使用事件编码固定为$$_user_profile
的自定义事件上传,该事件所携带的事件属性会被作为用户属性放在用户表中。
2.3.1. API说明
参见自定义事件API
2.3.2. 示例代码
import { trackEvent } from '@quicktracking/analytics';
Button('上传用户属性').onClick(() => {
trackEvent("$$_user_profile", {
sex: "boy",
age: 13,
favorite: "basketball"
});
})
3. 渠道属性
有两种场景需要统计渠道属性信息:
H5链接拉活已安装APP应用
H5链接拉新未安装APP应用
3.1. H5链接拉活已安装APP应用
唤起App的URL Scheme中携带这些渠道属性,且属性key务必以“utm_”开头,因为SDK识别的关键字为“utm_”。
例如:<URL scheme>?utm_channel=gzh
注意:!!!如果渠道属性已经与市面上渠道投放公司进行了合作,无法使用utm_开头,可以使用全局属性API将渠道属性进行埋点上报(属性key依然需要以utm_开头)
3.1.1. h5端唤起代码示例
<html>
<script>
function openHarmonyApp() {
var url = "hmapp://ut.open.realtime:80/Index?utm_a=aaa&utm_b=bbb";
alert(url)
window.location.href = url
};
</script>
<body>
<button onclick="openHarmonyApp()">唤起鸿蒙应用</button>
</body>
</html>
3.1.2. 鸿蒙Next应用代码示例
应用如能被H5链接唤起,需对模块的skills标签进行额外配置,具体请参考鸿蒙Next官网文档
3.1.2.1. 配置示例截图
3.1.2.2. 解析utm参数并设置为全局属性示例
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import {registerGlobalProperties, trackAppInstall } from '@quicktracking/analytics'
export default class EntryAbility extends UIAbility {
handleWant(want: Want) {
if (want.uri && want.uri.indexOf('utm_')) {
const dUri = decodeURI(want.uri)
const utmArgs:Record<string, string> = {}
const paramsString = dUri.split("?")[1]
const paramsArray = paramsString.split("&")
for (let i of paramsArray) {
const kvs = i.split("=")
const k: string = kvs[0]
const v = kvs[1]
utmArgs[k] = v
}
registerGlobalProperties(utmArgs)
}
}
//H5链接拉起APP应用,热启动
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.handleWant(want)
}
//H5链接拉起APP应用,冷启动
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.handleWant(want)
//!!!仅在enableAutoTrackApplication = false时需要调用
trackAppInstall({
browser: `'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.x.x Safari/537.36'`,
page_name: "ManIndex", //唤起页面的页面编码,可选,建议配置
url: "pages/Index" //唤起页面的页面路径,可选,建议配置
}, {
man_app_p1: 111, //自定义属性,可选
man_app_p2: 222
})
}
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
return;
}
});
}
}
3.2. H5链接拉新未安装APP应用
该场景下,如果仅是H5链接中携带“utm_”参数,已经无法做到下载APP后的启动事件携带“utm_”参数。所以需要进行“H5唤起事件”与“应用激活事件”做关于“IP地址和浏览器UserAgent”的模糊匹配。
当用户在H5中点击「唤起/下载App」的按钮时,上报“应用唤起事件($$_app_link)”,在事件中需要携带唤起App的appKey和渠道属性。
//示例
aplus_queue.push({
action:'aplus.recordAppLink',
arguments:[{
targetAppKey:'要唤起的应用appKey', // 必填,要唤起的应用appKey
custom1: 'custom1', // 选填,自定义参数
...
}]
})
App下载后的通过自动或者手动上报第一次启动事件“应用激活事件($$_app_install)”完成关联动作。
如果 SDK 默认配置 enableAutoTrackApplication = true,自动上报$$_app_install应用激活事件
如果 SDK 默认配置 enableAutoTrackApplication = false,需开发者主动上报应用激活事件
3.2.1. API说明
import { trackAppInstall } from '@quicktracking/analytics'
function trackAppInstall(params: {
browser?: string,
[key: string]: string
}, customProps?: object)
3.2.2. 调用示例
参见3.1.2鸿蒙Next3.1.2. 3.1.2. 鸿蒙Next应用代码示例
4. 全局属性
4.1. 注册全局属性
4.1.1. API 说明
import { registerGlobalProperties } from '@quicktracking/analytics'
function registerGlobalProperties(params?: Record<string, string | number | string[]>)
4.1.2. 参数说明
参数 | 含义 |
params | kv键值对 k属性名,string类型,应为长度为128个字符以内的非空(包括undefined)字符串 v属性值,string类型或number类型或字符串数组类型
|
4.1.3. 代码示例
import { registerGlobalProperties } from '@quicktracking/analytics'
Button('注册全局属性').onClick(async () => {
registerGlobalProperties({
"a": 1,
"b": 2
}) // 输出结果:{a: 1, b: 2}
})
Button('重新注册全局属性').onClick(async () => {
registerGlobalProperties({
"b": 6,
"c": 4
}) // 输出结果:{a: 1, b: 6, c: 4}
})
注意:如果和已经存在的全局属性key重复,则更新已有值;如果和已经存在的全局属性key不一致,则插入新的全局属性。
4.2. 删除一个全局属性
4.2.1. API 说明
import { unregisterGlobalProperty } from '@quicktracking/analytics'
function unregisterGlobalProperty(key?: string)
4.2.2. 参数说明
参数 | 含义 |
key | 需要删除的属性key名称,key应该有值并且是128个字符以内的字符串 |
4.2.3. 代码示例
import { unregisterGlobalProperty } from '@quicktracking/analytics'
Button('删除一个全局属性值').onClick(async () => {
unregisterGlobalProperty('a')
})
4.3. 根据key获取单个全局属性
4.3.1. API 说明
import { getGlobalProperty } from '@quicktracking/analytics'
function getGlobalProperty(key?: string): string | number | string[] | undefined
4.3.2. 参数说明
参数 | 含义 |
key | 属性key名称,key应该有值并且是128个字符以内的字符串 |
4.3.3. 代码示例
import { getGlobalProperty } from '@quicktracking/analytics'
Button('根据Key获取单个全局属性').onClick(async () => {
promptAction.showToast({
message:`获取的属性b = ${getGlobalProperty("b")}`,
duration: 3000
})
})
4.4. 获取所有全局属性
4.4.1. API 说明
import { getGlobalProperties } from '@quicktracking/analytics'
function getGlobalProperties(): Record<string, string | number | string[]>
4.4.2. 代码示例
import { getGlobalProperties } from '@quicktracking/analytics'
Button('获取所有全局属性').onClick(async () => {
promptAction.showToast({
message: `全局属性为\n${JSON.stringify(getGlobalProperties())}`,
duration: 5000
})
})
4.5. 清除所有全局属性
4.5.1. API 说明
import { clearGlobalProperties } from '@quicktracking/analytics'
function clearGlobalProperties()
4.5.2. 代码示例
Button('清除所有的全局属性').onClick(async () => {
clearGlobalProperties()
promptAction.showToast({
message: `全局属性为\n${JSON.stringify(getGlobalProperties())}`,
duration: 5000
})
})
5. 页面浏览事件
QuickTracking 鸿蒙Next SDK 提供页面自动采集和手动采集两种能力
5.1. 自动采集
如果 SDK 默认配置 enableAutoTrackPage = true,则自动采集页面浏览事件,详情参见预初始化API说明
路由模式 | 自动页面浏览事件-页面编码 | 自动页面浏览事件-页面路径 |
RouterPage | 触发生命周期的routerPage页面的名称 | 触发生命周期的routerPage页面的路径 |
NavDestination | NavDestination组件的名称 | NavDestination组件的名称 |
5.2. 手动采集
相比iOS系统或者Android系统,鸿蒙Next系统从概念上没有严格意义上的页面组件,任何通过装饰器语法声明的组件只要在main_pages.json
文件或者route_map.json
文件中添加了标识,都可以认为是业务意义上的页面组件。
定义在main_pages.json文件中的RouterPage页面
定义在route_map.json文件中NavDestination页面
针对上述两种场景,SDK 提供一组需成对调用的API onPageStart
和 onPageEnd
进行页面埋点。
5.2.1. API 说明
import { onPageStart, onPageEnd } from '@quicktracking/analytics'
function onPageStart(context: PageContext | null, pageName: string, pageUrl?: string) //页面进入时调用
function onPageEnd(context: PageContext | null, pageName: string, pageUrl?: string) //页面退出时调用
5.2.2. 参数说明
参数 | 含义 |
context | 页面环境上下文变量 |
pageName | 页面事件的事件编码,长度为128位字符以内的字符串,且不能为空 |
pageUrl | 页面url,若某些页面调用逻辑拿不到context,需要开发者主动传值,否则数据分析会不准备。默认值"undefined" |
5.2.3. 代码示例
RouterPage 页面
import { onPageStart, onPageEnd, updatePageProperties, skipAutoTrack } from '@quicktracking/analytics';
@Entry
@Component
struct RouterPageDemo {
@State message: string = 'RouterPageDemo';
onPageShow(): void {
//skipAutoTrack(this)
onPageStart(this, "RouterPageDemo")
updatePageProperties(this, "RouterPageDemo", {
a: 1,
b: 2
})
}
onPageHide() {
onPageEnd(this, "RouterPageDemo")
}
build() {
Column() {
Text(this.message)
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}
NavDestination 页面
import { onPageStart, updatePageProperties, onPageEnd, skipAutoTrack } from '@quicktracking/analytics';
@Builder
export function IndexBuilder(name: string, param: Object) {
NaviPageOne()
}
@Component
export default struct NaviPageOne {
@State name: string = 'NaviPageOne';
pathInfos: NavPathStack = new NavPathStack();
build() {
NavDestination() {
Column() {
Text("")
.id('NaviPageOneHelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
.onReady((context: NavDestinationContext) => {
this.pathInfos = context.pathStack
})
.title(this.name)
.id(this.name)
.onShown(() =>{
//skipAutoTrack(this)
onPageStart(this, "NaviPageOne")
updatePageProperties(this, "NaviPageOne", {
a: 1,
b: 2
})
})
.onHidden(() => {
onPageEnd(this, "NaviPageOne")
})
}
}
5.3. 设置页面事件属性
5.3.1. API 说明
import { updatePageProperties } from '@quicktracking/analytics';
function updatePageProperties(context: PageContext, pageName: string, params?: Record<string, string | number | string[]>, pageUrl?: string)
5.3.2. 参数说明
参数 | 含义 |
context | 页面环境上下文变量 |
pageName | 页面事件的事件编码,长度为128位字符以内的字符串,且不能为空 |
params | 页面事件的事件属性,kv键值对集合 k属性名,string类型,应为长度为128个字符以内的非空(包括undefined)字符串 v属性值,string类型或number类型或字符串数组类型
|
pageUrl | 页面url,若某些页面调用逻辑拿不到context,需要开发者主动传值,否则数据分析会不准备。默认值"undefined" |
5.3.3. 代码示例
见5.2.3节代码示例
5.4. 页面自动采集与页面手动采集混用
某些场景下,用户埋点期望既用自动页面采集完成通用行为采集,又希望某些页面通过手动控制埋点时机完成精细化采集,然而如果自动页面浏览事件和手动页面浏览事件重复上报会引起用户行为数据的准确性,为此SDK通过了关闭单独某个页面自动采集的能力
5.4.1. API说明
import { skipAutoTrack } from '@quicktracking/analytics';
function skipAutoTrack(context: PageContext)
5.4.2. 参数说明
参数 | 含义 |
context | 页面环境上下文变量 |
5.4.3. 代码示例
见5.2.2代码示例
注意:!!!
为了保障页面事件编码的统计归一,当自动采集的页面在页面进入时开发者调用onPageStart,并指定了页面事件的事件编码pageName,此时自动的页面事件的事件编码也会变成onPageStart传入的pageName
如果开发者开启页面事件自动采集功能,并且页面A没有调用skipAutoTrack,又通过代码埋点成对调用onPageStart、onPageEnd,此时当触发A页面离开时将同时上报 2 条页面浏览事件
onPageStart、onPageEnd 需要成对调用,否则影响页面事件采集的准确性
6. 自定义事件
6.1.1. API 说明
import { trackEvent } from '@quicktracking/analytics';
function trackEvent(eventID: string, params?: Record<string, string | number | string[]>)
6.1.2. 参数说明
参数 | 含义 |
eventID | 自定义事件的事件编码 |
params | 自定义事件的事件属性,kv键值对集合 k属性名,string类型,应为长度为128个字符以内的非空(包括undefined)字符串 v属性值,string类型或number类型或字符串数组类型
注意:!!!其中 k="$page_name":为事件预制属性,用于声明当前自定义事件所归属页面的页面编码,可选参数,若传值,则长度为128位字符以内的字符串,且不能为空 k="$page_url":为事件预制属性,用于声明当前自定义事件所归属页面的页面路径,可选参数,若传值,则长度为256位字符以内的字符串,且不能为空 |
6.1.3. 代码示例
在UI线程中埋点
import { trackEvent } from '@quicktracking/analytics';
Button('自定义事件').onClick(() => {
trackEvent("eventid", {
param1: "value"
param2: 2,
param3: ["productId1", "productId2"],
$page_name: "pageDemo", // 事件预制属性,可选参数
$page_url: "pages/pageDemo", // 事件预制属性,可选参数
});
});
在worker线程中埋点
import worker, { ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@ohos.worker';
import { trackEvent } from '@quicktracking/analytics';
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
workerPort.onmessage = function (e: MessageEvents) {
trackEvent("workerevent", {
param1: "value"
param2: 2,
param3: ["productId1", "productId2"],
$page_name: "pageDemo", // 事件预制属性,可选参数
$page_url: "pages/pageDemo", // 事件预制属性,可选参数
})
}
workerPort.onmessageerror = function (e: MessageEvents) {}
workerPort.onerror = function (e: ErrorEvent) {}
暂未提供c++中直接调用的方法,如需要c++层埋点,请参考鸿蒙Next官网c++与arkts互通的知识,通过NAPI来调用trackEvent方法实现埋点
7. 手动采集应用启动、退出、激活事件
SDK配置 enableAutoTrackApplication = true
默认开启,如果某些场景下不能满足启动、退出、激活事件的采集需求,可以通过手动调用API采集这三个场景行为。
注意:!!!
使用手动采集启动、退出、激活事件不能与自动采集应用启动、退出、激活事件混用,否则影响数据统计准确性。即需要设置enableAutoTrackApplication = false
。
7.1. 手动上报应用激活事件
7.1.1. API 说明
import { trackAppInstall } from '@quicktracking/analytics';
function trackAppInstall(context: ApplicationContext, appKey: string, params: {
browser?: string,
$page_name?: string,
$page_url?: string,
[key: string]: string | number | string[]
}) {
appTrack.manager.manualTrackAppInstall(context, appKey, params)
}
7.1.2. 参数说明
参数 | 含义 |
context | 应用环境上下文变量 |
appKey | 应用唯一标识appKey,入参的appkey一定要与QT后台保持一致 |
params | 应用激活事件的事件属性,kv键值对集合 k属性名,string类型,应为长度为128个字符以内的非空(包括undefined)字符串 v属性值,string类型或number类型或字符串数组类型
注意:!!!其中 k="browser":为激活事件的预制属性,用于声明当前唤起应用的浏览器UserAgent信息,可选参数,默认为undefined k="utm_xxx":为激活事件的预制属性,k以‘utm_’字符串开头,用于声明当前唤起应用的渠道参数信息,sdk会解析这类参数,并存储在全局属性中。 k="$page_name":为激活事件的预制属性,用于声明当前激活事件所归属页面的页面编码,可选参数, 默认为undefined。若传值,则长度为128位字符以内的字符串,且不能为空 k="$page_url":为激活事件的预制属性,用于声明当前激活事件所归属页面的页面路径,可选参数, 默认为undefined。若传值,则长度为256位字符以内的字符串,且不能为空 |
7.1.3. 代码示例
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import { trackAppInstall } from '@quicktracking/analytics';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
trackAppInstall(
this.context.getApplicationContext(),
"您应用的appKey",
{
$browser: 'Mozilla/5.0 Chrome/126.0.X.X Safari/537.36', //可选参数,默认为undefined
$page_name: "home_page", //可选参数,默认为undefined
$page_url: "pages/Index", //可选参数,默认为undefined
utm_source: "hwbroser",
man_app_p1: 111,
man_app_p2: '222',
man_app_p3: ['1', '2']
}
)
}
}
7.2. 手动上报应用启动事件
7.2.1. API 说明
import { trackAppStart } from '@quicktracking/analytics';
function trackAppStart(params: {
isFirstLaunch?: boolean,
$page_name?: string,
$page_url?: string,
}, customParams?: object )
7.2.2. 参数说明
参数 | 含义 |
params | 应用启动事件的预制属性,kv键值对集合。 其中: k="isFirstLaunch"为冷热启动标识,默认值为false,代表热启动,如果想区分冷、热启动事件,需要开发者自己控制isFirstLaunch字段的传值 k="$page_name":为激活事件的预制属性,用于声明当前激活事件所归属页面的页面编码,可选参数, 默认为undefined。若传值,则长度为128位字符以内的字符串,且不能为空 k="$page_url":为激活事件的预制属性,用于声明当前激活事件所归属页面的页面路径,可选参数, 默认为undefined。若传值,则长度为256位字符以内的字符串,且不能为空 |
customParams | 应用启动事件的事件属性,kv键值对集合 k属性名,string类型,应为长度为128个字符以内的非空(包括undefined)字符串 v属性值,string类型或number类型或字符串数组类型
|
7.2.3. 代码示例
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import { trackAppStart } from '@quicktracking/analytics';
export default class EntryAbility extends UIAbility {
onForeground(): void {
trackAppStart({
isFirstLaunch: true, //可选参数,默认为false
$page_name: "home_page", //可选参数,默认为undefined
$page_url: "pages/Index" //可选参数,默认为undefined
}, {
man_app_p1: 111,
man_app_p2: "222",
man_app_p3: ['1', '2']
})
}
}
7.3. 手动上报应用退出事件
7.3.1. API 说明
import { trackAppEnd } from '@quicktracking/analytics';
function trackAppEnd(params: {
$page_name?: string,
$page_url?: string,
duration?: number
}, customParams?: object)
7.3.2. 参数说明
参数 | 含义 |
params | 应用退出事件的预制属性kv键值对集合。 其中: k="duration":代表应用浏览时长,number类型,默认值为0 k="$page_name":代表当前应用退出事件所归属页面的页面编码,可选参数,默认为undefined。若传值,则长度为128位字符以内的字符串,且不能为空 k="$page_url":代表当前应用退出事件所归属页面的页面路径,可选参数,默认为undefined。若传值,则长度为256位字符以内的字符串,且不能为空 |
customParams | 应用启动事件的事件属性,kv键值对集合 k属性名,string类型,应为长度为128个字符以内的非空(包括undefined)字符串 v属性值,string类型或number类型或字符串数组类型
|
7.3.3. 代码示例
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import { trackAppEnd } from '@quicktracking/analytics';
export default class EntryAbility extends UIAbility {
onBackground(): void {
trackAppEnd({
$page_name: "home_page",
$page_url: "pages/Index",
duration: 666
}, {
man_app_p1: 111,
man_app_p2: "222",
man_app_p3: ['1', '2']
})
}
}