# 自动采集

> 来源：https://help.gravity-engine.com/docs/client-sdk/android/advanced/automatic-tracking
> 介绍 Gravity Engine Android SDK 支持自动采集的基础事件、开启方式及相关配置。



Android SDK 支持包括安装、启动、关闭、页面浏览、元素点击等在内事件的自动采集。

## 1. 介绍 [#1-介绍]

`GravityEngineSDK` 提供自动化收集数据的接口，您可根据业务需求自行选择需要自动收集的数据。

目前支持的自动采集事件类型有：

* `安装事件（$AppInstall）`：记录 APP 被安装的行为
* `启动事件（$AppStart）`：包括打开 APP 和从后台打开 APP
* `关闭事件（$AppEnd）`：包括关闭 APP 和 App 进入后台，同时收集启动的时长
* `浏览事件（$AppView）`：用户在 APP 中浏览页面（Activity）
* `点击事件（$AppClick）`：用户在 APP 中点击控件
* `崩溃事件（$AppCrash）`：APP 发生崩溃时记录崩溃信息

> 由于`$AppInstall`、`$AppStart`、`$AppEnd`的特殊性，SDK 会默认采集，且不可关闭！

接下来将会对每种类型的自采集事件做详细介绍。

## 2. 开启自动采集 [#2-开启自动采集]

您需要手动调用`enableAutoTrack`，来打开自动采集功能：

```java
List<GravityEngineSDK.AutoTrackEventType> typeList = new ArrayList<>();
typeList.add(GravityEngineSDK.AutoTrackEventType.APP_CRASH);
typeList.add(GravityEngineSDK.AutoTrackEventType.APP_VIEW_SCREEN);
typeList.add(GravityEngineSDK.AutoTrackEventType.APP_CLICK);
gravityEngineSDKInstance.enableAutoTrack(typeList);
```

> 如果您需要采集控件点击事件或者 `Fragment` 浏览事件，需要集成自动采集插件，详情见可选插件

## 3. 详细介绍 [#3-详细介绍]

### 3.1 安装事件 [#31-安装事件]

APP 安装事件将会记录 APP 的实际安装，在 APP 启动时上报，事件触发时间是 APP 安装后首次启动的时间，APP 升级并不会触发安装事件，而删除重装后会上报安装事件。

* 事件英文名：`$AppInstall`

### 3.2 启动事件 [#32-启动事件]

APP 启动事件将会在用户开启 APP 时触发。

* 事件英文名：`$AppStart`

### 3.3 关闭事件 [#33-关闭事件]

APP关闭事件会在用户退出或切换至后台时触发。如果此时网络正常，事件会立即上报；&#x2A;*但如果应用进程被系统强制结束或用户主动杀死，导致上报失败，该事件便会保存在本地。** 用户下次启动应用时，SDK会重新尝试上报这些暂存的事件。需要注意的是，如果用户在事件成功上报前卸载了应用，本地保存的所有数据将会被清除，相关事件会永久丢失。

* 事件英文名：`$AppEnd`
* 预置属性：`$event_duration`，数值型，表示该次 APP 访问（自启动至结束）的时长，单位是秒。

设置前台会话阀值（频繁切换前后台，AppEnd时间会很小，可以设置这个值忽略这种操作）当AppEnd发生时，事件少于设置的time，会忽略计时

```java
geConfig.setForegroundSessionThreshold(10);
```

### 3.4 浏览页面事件 [#34-浏览页面事件]

APP 浏览页面事件会在用户浏览页面（Activity）时触发。

* 事件英文名：`$AppView`
* 预置属性：
  * `$screen_name`，字符串型，为 Activity 的包名.类名
  * `$title`，字符串型，为 Activity 的标题，取值为 Activity 的 title 属性的值

> 页面浏览事件中可以加入其它属性以扩展其分析价值，以下是自定义浏览页面事件的属性的方法

#### 3.4.1 开启自动采集 Fragment 的页面浏览事件 [#341-开启自动采集-fragment-的页面浏览事件]

在 SDK 初始化完成后，调用以下方法启动 Fragment 的自动采集功能

* 对于 `android.support.v4.app.Fragment` 的 Fragment

```java
gravityEngineSDKInstance.trackFragmentAppViewScreen();
```

* 对于 `android.app.Fragment` 的 Fragment

```java
// targetFragment 可替换为需要上传页面浏览事件的 Fragment
gravityEngineSDKInstance.trackViewScreen(targetFragment);
```

#### 3.4.2 自定义页面浏览事件的属性 [#342-自定义页面浏览事件的属性]

对于 `Activity` 的页面浏览事件，可以通过实现接口 `ScreenAutoTracker` 的方法增加属性，通过以下两个方法，可以为页面浏览事件增加页面 URL 信息，以及其他自定义属性：

```java
public class MainActivity extends AppCompatActivity implements ScreenAutoTracker {
    private Context mContext;

    @Override
    public String getScreenUrl() {
        return "gravityengine://page/main";
    }

    @Override
    public JSONObject getTrackProperties() throws JSONException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("param1", "ABCD");
        jsonObject.put("param2", "gravityengine");
        return jsonObject;
    }
}
```

* `getScreenUrl`的返回值将作为该`Activity`的 URL Schema，当触发该页面的浏览事件时，将会加入预置属性`$url`，取值即为当前页面的 URL Schema；同时 SDK 会取跳转前页面的 URL Schema，如果能取到则会加入到预置属性`$referrer`中则为前向地址。
* `getTrackProperties`的返回值是该页面的浏览事件的自定义属性，将会自动加入到该页面的浏览事件中

对于 Fragment 的页面浏览事件，我们提供两种方式添加属性

* 通过 `@GravityEngineFragmentTitle` 方式添加属性

```java
@GravityEngineFragmentTitle(title = "myFragment")
public class ListViewFragment extends BaseFragment {
  // your fragment implementations
}
```

* 通过 `ScreenAutoTracker` 接口 添加属性

```java
@Override
public JSONObject getTrackProperties() {
    try {
        JSONObject properties = new JSONObject();
        properties.put("$title", "RecyclerViewFragment");
        return properties;
    } catch (JSONException e) {
        // ignore
    }
    return null;
}
```

### 3.5 点击事件 [#35-点击事件]

APP 控件点击事件将会在用户点击控件（view）时触发

* 事件英文名：`$AppClick`
* 预置属性：
  * `$screen_name`，字符串型，为控件所属 Activity 的`包名.类名`
  * `$title`，字符串型，为控件所属 Activity 的标题，取值为 Activity 的 title 属性的值
  * `$element_content`，字符串型，为控件的内容
  * `$element_type`，字符串型，为控件的类型
  * `$element_id`，字符串型，为控件的 ID，默认使用 `android:id`
  * `$element_position`，字符串型，当控件存在 position 时才会上传
  * `$element_selector`，字符串型，为控件的 viewPath 的拼接

对于页面上 View 的点击事件，有以下多种方式来设置更多属性，以扩展其分析价值：

#### 3.5.1 自定义控件 ID [#351-自定义控件-id]

控件的 ID 默认使用 `android:id`，如果该属性无法取到，或者希望自定义控件 ID，可以使用以下方法覆盖 `$element_id` 属性

```java
gravityEngineSDKInstance.setViewID(view,viewID);
```

对于 `Dialog` ，可以使用如下方法：

```
//android.app.Dialog
gravityEngineSDKInstance.setViewID(view,viewID);
```

或者

```
//android.support.v7.app.AlertDialog
gravityEngineSDKInstance.setViewID(view,viewID);
```

参数 `view` 为需要设置控件 ID 的 view，参数 viewID 为设置的控件 ID，当上传该控件的点击事件时，`$element_id` 的取值即为此处的传入值

#### 3.5.2 自定义控件点击事件的属性 [#352-自定义控件点击事件的属性]

您可以通过以下方法，为某控件（view）的点击事件增加自定义属性：

```java
gravityEngineSDKInstance.setViewProperties(view,properties);
```

参数 `view` 为需要设置自定义属性的 view，参数 `properties` ，类型为 `JSONObject` ，为设置的自定义属性，当上传该控件的点击事件时，将会添加这些属性。

另外，对于 `ExpandableListView` 、`ListView` 与 `GridView` ，还可以通过 Adapter 实现接口的方式，来增加点击某 item 时的自定义属性。

* `ExpandableListView` 需实现 `GravityExpandableListViewItemTrackProperties` 接口

```java
public interface GravityExpandableListViewItemTrackProperties {
    /**
     * 增加点击 groupPosition、childPosition 处 item 时的属性
     * @param groupPosition
     * @param childPosition
     * @return
     * @throws JSONException
     */
    JSONObject getGravityChildItemTrackProperties(int groupPosition, int childPosition) throws JSONException;

    /**
     * 增加点击 groupPosition 处 item 时的属性
     * @param groupPosition
     * @return
     * @throws JSONException
     */
    JSONObject getGravityGroupItemTrackProperties(int groupPosition) throws JSONException;
}
```

* `ListView` 与 `GridView` 需实现 `GravityAdapterViewItemTrackProperties` 接口

```java
public interface GravityAdapterViewItemTrackProperties {
    /**
     * 增加点击 position 处 item 时的属性
     * @param position
     * @return
     * @throws JSONException
     */
    JSONObject getGravityItemTrackProperties(int position) throws JSONException;
}
```

#### 3.5.3 对 AlertDialog 的点击事件增加页面（Activity）信息 [#353-对-alertdialog-的点击事件增加页面activity信息]

对于 `AlertDialog`（`android.app.AlertDialog`与`android.support.v7.app.AlertDialog`）的点击事件，可以通过以下方法绑定所属页面（Activity），在其点击事件中将会加入所属页面的 `$screen_name` 与 `$title` 属性。

* 通过调用 `dialog.show()`显示 dialog，请使用以下方法：

```java
dialog.setOwnerActivity(targetActivity);
```

* 通过调用 `builder.show()`显示 dialog，请使用以下方法:

```java
builder.show().setOwnerActivity(activity);
```

#### 3.5.4 通过注解@GravityEngineTrackViewOnClick 上传控件点击事件 [#354-通过注解gravityenginetrackviewonclick-上传控件点击事件]

如果您使用的是 `android:onClick` 为控件（view）添加点击事件的调用方法，则可以在调用方法上添加注解`@GravityEngineTrackViewOnClick`，当该调用方法被执行时，SDK 将会上传控件点击事件

```java
@GravityEngineTrackViewOnClick
public void buttonOnClick(View v){}
```

如果方法 `buttonOnClick` 被调用，则会上传控件点击事件

### 3.6 崩溃事件 [#36-崩溃事件]

当 APP 出现未捕获异常时，会上报 APP 崩溃事件

* 事件英文名：`$AppCrash`
* 预置属性：`$app_crashed_reason`，字符型，记录崩溃时的堆栈轨迹

## 4. 忽略自动采集事件 [#4-忽略自动采集事件]

您可以通过以下方式，忽略某页面或控件的自动采集事件

### 4.1 忽略页面的自动采集事件 [#41-忽略页面的自动采集事件]

对于某些页面（Activity），如果不想传输自动采集事件（包括页面浏览与控件点击事件），可以通过以下方法进行忽略：

```java
//单页面的忽略
gravityEngineSDKInstance.ignoreAutoTrackActivity(MainActivity.class);
//多页面的忽略
List<Class<?>> classList = new ArrayList<>();
classList.add(MainActivity.class);
gravityEngineSDKInstance.ignoreAutoTrackActivities(classList);
```

也可以在`Activity`或`Fragment`前添加注解`@GravityEngineIgnoreTrackAppViewScreen`，忽略某个 Activity 或 Fragment 的页面浏览事件

```java
//忽略 TestActivity 的页面浏览事件
@GravityEngineIgnoreTrackAppViewScreen
public class TestActivity extends AppCompatActivity {
    ...
}
```

在`Activity`前添加注解`@GravityEngineIgnoreTrackAppViewScreenAndAppClick`，忽略某个 Activity 页面浏览事件与该页面下的控件点击事件

```java
//忽略 TestActivity 的页面浏览事件与该页面下的控件点击事件
@GravityEngineIgnoreTrackAppViewScreenAndAppClick
public class TestActivity extends AppCompatActivity {
    ...
}
```

### 4.2 忽略某个类型控件的点击事件 [#42-忽略某个类型控件的点击事件]

如果需要忽略某个类型控件的点击事件，可以使用以下方法进行忽略

```java
gravityEngineSDKInstance.ignoreViewType(ignoredClass);
```

* `ignoredClass`即为需要忽略的控件类型，比如`Dialog`、`Checkbox`等

### 4.3 忽略某个元素（View）的点击事件 [#43-忽略某个元素view的点击事件]

如果希望忽略某个元素（View）的点击事件，可以使用以下方法进行忽略

```java
gravityEngineSDKInstance.ignoreView(targetView);
```

* `targetView`即为需要忽略的 View

## 5. 使用注解快速设置事件 [#5-使用注解快速设置事件]

如果需要监控某个方法的调用次数，或者某方法一经调用即需要上传一个事件，则可以使用注解`@GravityEngineTrackEvent`快速设置需要上传的事件，需要注意的是，属性无法传入变量，因此只适合上传简单的事件

```java
//使用注解
@GravityEngineTrackEvent(eventName = "event_name", properties = "{\"paramString\":\"value\",\"paramNumber\":123,\"paramBoolean\":true}")
public void fun(){}
```

此时如果方法 `fun` 被调用，则会上传一个事件名为`event_name`，属性为`"paramString":"value"`、`"paramNumber":123` 与 `"paramBoolean":true` 的事件

## 6. 设置自定义属性 [#6-设置自定义属性]

您可以调用 `enableAutoTrack(List<GravityEngineSDK.AutoTrackEventType>, JSONObject)`，打开自动采集功能，同时设置自定义属性

```java
JSONObject properties = new JSONObject();
try {
    properties.put("auto_self_define_key", "auto_self_define_value");
} catch (Exception e) {
    e.printStackTrace();
}
gravityEngineSDKInstance.enableAutoTrack(typeList, properties);
```

您也可以调用 `setAutoTrackProperties(List<GravityEngineSDK.AutoTrackEventType>, JSONObject)`，设置或者更新自定义属性

```java
JSONObject properties = new JSONObject();
try {
    properties.put("auto_self_define_key", "auto_self_define_value");
} catch (Exception e) {
    e.printStackTrace();
}
gravityEngineSDKInstance.setAutoTrackProperties(typeList, properties);
```

## 7. 自动采集事件设置回调 [#7-自动采集事件设置回调]

您可以通过设置回调，在已开启的自动采集事件发生时，获取到当前事件的事件类型以及所携带的事件属性，并且可以通过设置返回值的方式为该事件增加额外需要上报的属性。

```java
List<GravityEngineSDK.AutoTrackEventType> typeList = new ArrayList<>();
typeList.add(GravityEngineSDK.AutoTrackEventType.APP_INSTALL);
typeList.add(GravityEngineSDK.AutoTrackEventType.APP_END);

gravityEngineSDKInstance.enableAutoTrack(typeList, new GravityEngineSDK.AutoTrackEventListener() {
    @Override
    public JSONObject eventCallback(GravityEngineSDK.AutoTrackEventType eventType, JSONObject properties) {
        try {
            return new JSONObject("{\"keykey\":\"value1111\"}");
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }
});
```

## 8. 可选插件 [#8-可选插件]

> **只有当您需要开启控件点击事件和 `Fragment` 页面浏览事件时，才需要集成此插件。**

```groovy
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'cn.gravity.android:android-gradle-plugin-autotrack:${PLUGIN_LATEST_VERSION}'
    }
}
```

> PLUGIN\_LATEST\_VERSION 请参见下方的发版记录

可以在项目 build.gradle 文件中配置插件相关参数

```groovy
apply plugin: 'cn.gravity.android'
android {
}
GravityEngineSDK {
    // 打开编译日志
    debug = false
    //是否允许扫描jar
    disableJar = false
    //是否扫描指定的类，默认全部扫描
    useInclude = false
    //指定的类列表，useInclude为true时有效
    include = []
    //指定排除的类列表，useInclude为false时有效
    exclude = []
}
```

* 如果想打开编译日志，可以设置 debug = true，默认为 false
* 如果想禁止扫描 jar 中的类，可以设置 disableJar = true，默认是 false
* 如果不想扫描某个路径下的类，可以通过设置 exclude = \['cn.test.android','android.support']，默认全局扫描
* 也可以通过设定 useInclude = true，开启指定类列表扫描模式，这时需要使用 `include` 来说明哪些类自动添加埋点

## 9. 发版记录 [#9-发版记录]

| 版本    | 日期         | 备注                  |
| ----- | ---------- | ------------------- |
| 2.0.0 | 2025-01-20 | 支持高版本gradle         |
| 1.1.2 | 2025-11-12 | 支持更多kotlin语法解析      |
| 1.0.8 | 2025-09-10 | 修复 kotlin 包的概率的打包失败 |
| 1.0.7 | 2023-03-16 | 支持全埋点自采集方案          |
