# 数据上报

> 来源：https://help.gravity-engine.com/docs/gravity-dock/integration/event-tracking
> 使用 GravityDockSDKTrack 上报自定义事件、账号与付费事件、广告事件、用户属性与公共事件属性，并进行接入验证。
> 文档修改日期：2026-11-06




SDK 通过 `GravityDockSDKTrack` 提供统一的数据上报接口，事件经统计总线分发到当前渠道包接入的统计组件（如引力引擎）。事件先写入本地缓存，按策略批量上报；账号、付费等关键预置事件内部会自动 flush。

```java
import com.gravitydock.sdk.GravityDockSDKTrack;
```

> **注意**
> 以下事件均为客户端埋点，用于投放回收与渠道行为分析。事件是否生效取决于当前渠道包启用的统计组件，未接入统计组件的渠道包会自动忽略调用。

## 自定义事件 [#自定义事件]

```java
// 仅事件名
GravityDockSDKTrack.track("dock_demo_event");

// 携带自定义属性
JSONObject properties = new JSONObject();
try {
    properties.put("level", 10);
    properties.put("scene", "demo");
} catch (Exception ignore) {
}
GravityDockSDKTrack.track("dock_demo_event", properties);
```

## 账号事件 [#账号事件]

在[渠道登录](/docs/gravity-dock/integration/account-and-payment)流程中配套调用，内部自动 flush：

| 方法                     | 触发时机             |
| ---------------------- | ---------------- |
| `trackRegisterEvent()` | 用户完成业务注册后上报注册事件。 |
| `trackLoginEvent()`    | 登录成功后上报登录事件。     |
| `trackLogoutEvent()`   | 登出后上报登出事件。       |

```java
// 登录成功回调中上报
GravityDockSDKTrack.trackLoginEvent();

// 登出后上报
GravityDockSDKTrack.trackLogoutEvent();
```

## 付费事件 [#付费事件]

用户发生付费行为后调用 `trackPayEvent`，此事件影响渠道投放回收统计，请务必重点测试：

```java
JSONObject payOtherParams = new JSONObject();
try {
    payOtherParams.put("type", "gift");       // 商品类型
    payOtherParams.put("name", "flower");     // 商品名称
    payOtherParams.put("id", "008");          // 商品 ID
    payOtherParams.put("num", 1);             // 购买数量，不传默认 1
    payOtherParams.put("channel", "wechat");  // 付费渠道
    payOtherParams.put("currency", "CNY");    // 币种
} catch (JSONException e) {
    throw new RuntimeException(e);
}
// payAmount 单位：分。支付成功回调中上报，内部自动 flush
GravityDockSDKTrack.trackPayEvent(100, "CNY", merchantOrderNo, "60钻石", "支付宝", payOtherParams);
```

| 参数             | 说明                            | 类型     | 是否必传 |
| -------------- | ----------------------------- | ------ | ---- |
| payAmount      | 付费金额，单位为分。传错单位会影响买量统计。        | int    | 是    |
| payType        | 货币类型，ISO 4217 三位字母，如 CNY、USD。 | string | 是    |
| orderId        | 订单号，用于去重，建议与商户订单号一致。          | string | 是    |
| payReason      | 付费原因，如“60钻石”。                 | string | 是    |
| payMethod      | 付费方式，如“支付宝”。                  | string | 是    |
| payOtherParams | 渠道扩展参数，各渠道 SDK 按需读取，见下表。      | object | 建议   |

`payOtherParams` 各字段含义及渠道消费情况：

| 字段         | 说明                                  | 消费渠道        |
| ---------- | ----------------------------------- | ----------- |
| `type`     | 商品类型，如 gift、diamond、prop、monthcard。 | 穿山甲、广点通     |
| `name`     | 商品名称。                               | 穿山甲、广点通     |
| `id`       | 商品 ID。                              | 穿山甲、广点通（必传） |
| `num`      | 购买数量，不传默认 1。                        | 穿山甲、广点通     |
| `channel`  | 付费渠道。                               | 穿山甲、广点通（必传） |
| `currency` | 币种，如 CNY、USD。                       | 穿山甲（必传）     |

各渠道适配器对付费事件的取值逻辑：

| 渠道 SDK          | 取值逻辑                                                                                                             |
| --------------- | ---------------------------------------------------------------------------------------------------------------- |
| 引力引擎            | 仅消费固定 5 个参数（金额分、币种、订单号、原因、方式），不读取 `payOtherParams`。                                                              |
| 穿山甲             | 读取 `type`、`name`、`id`、`num`、`channel`、`currency` 上报付费转化；`payAmount` 自动由分换算为元。                                    |
| 广点通             | 读取 `type`、`name`、`id`、`num`、`channel` 上报付费转化；币种取 `payType` 参数，金额保持分为单位。                                          |
| 快手              | 仅消费 `payAmount`，自动由分换算为元上报，不读取 `payOtherParams`。                                                                 |
| 数数 ThinkingData | 固定 5 个参数映射为 `pay_amount`、`pay_type`、`order_id`、`pay_reason`、`pay_method`，并将 `payOtherParams` 全部键值透传到 `pay` 事件属性。 |

> **注意**
> 穿山甲与广点通通过 `getString` 强制读取 `id`、`channel`（穿山甲还含 `currency`），对应字段缺失时该渠道的付费转化不会上报且异常被静默捕获。面向这两类渠道投放的渠道包，务必在 `payOtherParams` 中补全这些字段。

## 提现事件 [#提现事件]

用户发生应用内提现行为时调用 `trackWithdrawEvent`，固定参数与付费事件一致（金额单位为分）：

```java
GravityDockSDKTrack.trackWithdrawEvent(300, "CNY", "order_id", "用户首次提现", "支付宝");
```

与付费事件不同，`trackWithdrawEvent` 的 `payOtherParams` 没有强制字段要求：各渠道适配器均只消费固定 5 个参数，不强制读取 `payOtherParams`（穿山甲、广点通、快手直接忽略；数数 ThinkingData 会将其全部键值透传到 `withdraw` 事件属性，可作为附加维度选传）。付费事件中对 `id`、`channel`、`currency` 的必传要求不适用于提现事件。

## 广告事件 [#广告事件]

产品内有广告变现时上报广告事件组，`ecpm` 单位为元：

| 方法                                               | 触发时机                      |
| ------------------------------------------------ | ------------------------- |
| `trackAdLoadEvent(...)`                          | 广告加载完成。                   |
| `trackAdShowEvent(...)`                          | 广告展示。                     |
| `trackAdClickEvent(...)`                         | 用户点击广告。                   |
| `trackAdPlayStartEvent(...)`                     | 视频广告开始播放。                 |
| `trackAdPlayEndEvent(..., duration, isPlayOver)` | 视频广告播放结束，`duration` 单位为秒。 |
| `trackAdSkipEvent(...)`                          | 用户跳过广告。                   |

```java
String adUnionType = "topon";   // 广告聚合平台：topon、gromore、admore、self
String adPlacementId = "placement_id"; // 广告位 ID
String adSourceId = "ad_source_id";    // 广告源（代码位）ID
String adType = "reward";       // 广告类型：reward、banner、native、interstitial、splash 等
String adnType = "csj";         // 广告平台：csj、gdt、ks、mint、baidu、other

GravityDockSDKTrack.trackAdLoadEvent(adUnionType, adPlacementId, adSourceId, adType, adnType);
GravityDockSDKTrack.trackAdShowEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, 1);
GravityDockSDKTrack.trackAdClickEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, 1);
GravityDockSDKTrack.trackAdPlayStartEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, 1);
GravityDockSDKTrack.trackAdPlayEndEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, 1, 50, false);
```

## 广点通标准行为 [#广点通标准行为]

针对广点通投放的渠道包，SDK 内置了与广点通 `ActionUtils` 对应的标准行为上报方法，按业务节点调用即可：

| 方法                                                                                                             | 对应行为   |
| -------------------------------------------------------------------------------------------------------------- | ------ |
| `trackViewContentEvent(type, name, id)`                                                                        | 内容浏览   |
| `trackAddToCartEvent(type, name, id, number, success, money)`                                                  | 加入购物车  |
| `trackCheckoutEvent(type, name, id, number, isVirtualCurrency, virtualCurrencyType, currency, success, money)` | 下单/结账  |
| `trackBindAccountEvent(method, success)`                                                                       | 绑定账号   |
| `trackCreateRoleEvent(role)`                                                                                   | 创建角色   |
| `trackUpdateLevelEvent(level)`                                                                                 | 更新等级   |
| `trackRateAppEvent(value)`                                                                                     | 应用评分   |
| `trackQuestFinishEvent(id, type, name, number, desc, success)`                                                 | 任务完成   |
| `trackAddPaymentChannelEvent(channel, success)`                                                                | 添加支付渠道 |

```java
// 示例：玩家升级时上报
GravityDockSDKTrack.trackUpdateLevelEvent(10);

// 示例：创建角色时上报
GravityDockSDKTrack.trackCreateRoleEvent("战士小明");
```

## 用户属性 [#用户属性]

记录用户的固定画像与数值型进度，按需选用：

| 方法                           | 行为                                         |
| ---------------------------- | ------------------------------------------ |
| `userSet(properties)`        | 覆盖写用户属性。                                   |
| `userSetOnce(properties)`    | 首次设置，已存在时不覆盖，如首次访问时间。                      |
| `userIncrement(key, value)`  | 数值累加，也可传 `userIncrement(JSONObject)` 批量累加。 |
| `userMax(key, value)`        | 保存历史最大值，如最高 ecpm。                          |
| `userMin(key, value)`        | 保存历史最小值。                                   |
| `userAppend(properties)`     | 向数组类型属性追加元素。                               |
| `userUniqAppend(properties)` | 向数组类型属性去重追加元素。                             |
| `userUnset(key)`             | 重置（删除）指定用户属性。                              |
| `userDelete()`               | 删除用户并清空全部用户属性。                             |

```java
// 覆盖写
JSONObject properties = new JSONObject();
try {
    properties.put("$name", "dockDemoUser");
    properties.put("$gender", "男");
} catch (Exception ignore) {
}
GravityDockSDKTrack.userSet(properties);

// 首次设置
JSONObject firstVisit = new JSONObject();
try {
    firstVisit.put("$first_visit_time", "2026-01-01 00:00:00");
} catch (Exception ignore) {
}
GravityDockSDKTrack.userSetOnce(firstVisit);

// 数值累加、最大最小值
GravityDockSDKTrack.userIncrement("$age", 1);
GravityDockSDKTrack.userMax("ad_ecpm_max", 300);
GravityDockSDKTrack.userMin("ad_ecpm_min", 100);

// 数组去重追加
try {
    JSONArray movies = new JSONArray();
    movies.put("Interstellar");
    JSONObject appendProps = new JSONObject();
    appendProps.put("Movies", movies);
    GravityDockSDKTrack.userUniqAppend(appendProps);
} catch (Exception ignore) {
}

// 重置指定属性 / 删除用户
GravityDockSDKTrack.userUnset("$age");
GravityDockSDKTrack.userDelete();
```

## 公共事件属性 [#公共事件属性]

公共事件属性会自动附加到之后上报的所有事件上，适合放置渠道、服务器等全局字段：

```java
// 设置
JSONObject superProperties = new JSONObject();
try {
    superProperties.put("channel", "developer");
    superProperties.put("age", 2);
} catch (Exception ignore) {
}
GravityDockSDKTrack.setSuperProperties(superProperties);

// 移除单个属性
GravityDockSDKTrack.unsetSuperProperties("channel");

// 清空全部
GravityDockSDKTrack.clearSuperProperties();
```

## 立即上报 [#立即上报]

事件默认按策略批量上报。如需在关键节点立即发送缓存中的事件（如退出游戏前），调用 `flush()`。账号、付费等预置事件内部已自动 flush，无需重复调用：

```java
GravityDockSDKTrack.flush();
```

## 演练模式 [#演练模式]

演练模式用于投放前验证转化事件链路：命中演练名单的事件不再走全量统计上报，而是单独路由到引力引擎的演练通道，便于在渠道后台观察事件是否被正确接收和转化，避免污染正式统计数据。

### 1. 配置演练事件名单 [#1-配置演练事件名单]

在对应渠道后台配置“动态参数”-“演练事件”，将需要演练的事件名加入名单。SDK 启动时通过运行时配置拉取该名单，无需改代码重新打包。

### 2. 调用 SDK 时传入 otherParams [#2-调用-sdk-时传入-otherparams]

事件命中演练名单后，SDK 会将事件路由到引力演练模式。此时可通过 `otherParams` 传入 `origin_event` 声明原始事件语义；若不传，SDK 会自动把事件名（如 `dock_demo_event`）填入 `origin_event`：

```java
JSONObject activeOtherParams = new JSONObject();
try {
    activeOtherParams.put("origin_event", "游戏过关事件");
} catch (JSONException e) {
    throw new RuntimeException(e);
}
GravityDockSDKTrack.track("dock_demo_event", activeOtherParams);
```

> **注意**
> `origin_event` 传入后以业务自定义值为准；未传入时 SDK 自动设置事件名为 `origin_event`。建议在渠道后台与运营约定好各演练事件的 `origin_event` 取值，便于对账排查。

### 演练名单命中规则 [#演练名单命中规则]

按事件名匹配，各事件的匹配名称：

| 事件类型                                            | 名单中的匹配名                                                                                                                                             |
| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| 自定义事件                                           | 自定义事件名本身，如 `dock_demo_event`                                                                                                                        |
| 注册                                              | `$AppRegister`                                                                                                                                      |
| 登录                                              | `$AppLogin`                                                                                                                                         |
| 登出                                              | `$AppLogout`                                                                                                                                        |
| 付费                                              | `$PayEvent`                                                                                                                                         |
| 提现                                              | `$UserWithdraw`                                                                                                                                     |
| 分享                                              | `$AppShare`                                                                                                                                         |
| 广告加载 / 展示 / 跳过 / 点击                             | `$AdLoad` / `$AdShow` / `$AdSkip` / `$AdClick`                                                                                                      |
| 广告播放开始 / 结束                                     | `$AdPlayStart` / `$AdPlayEnd`                                                                                                                       |
| 广点通标准行为（内容浏览、加购、结账、绑定账号、创建角色、升级、评分、任务完成、添加支付渠道） | `view_content` / `add_to_cart` / `checkout` / `bind_account` / `create_role` / `update_level` / `rate_app` / `quest_finish` / `add_payment_channel` |

> **注意**
> 命中演练名单的事件只走引力演练通道，不进行全量统计；未命中的事件保持原有全量上报逻辑。演练完成后请在渠道后台移除对应事件名，恢复正式上报。

## 接入验证 [#接入验证]

在真机上打开 SDK 日志（`GravityDockSDK.setLogEnabled(true)`），依次触发注册、登录、付费、广告等事件，确认事件成功分发并进入本地缓存；随后在统计平台（如引力引擎后台事件流）核对事件是否实时入库。若事件未出现，核对渠道包是否启用对应统计组件、`server_url` 连通性及事件参数单位（付费与提现单位为分，ecpm 单位为元）。
