Title: Android SDK Locale: zh URL: https://sensorswave.com/docs/data-integration/client-sdks/android/ Description: Android SDK 集成指南和 API 参考 Sensors Wave Android SDK 是专为 Android 移动应用设计的客户端数据采集和 AB 实验工具。 ## 核心功能 Android SDK 提供以下核心能力: - **事件追踪**:手动追踪自定义事件和用户行为 - **自动埋点**:自动采集应用启动、应用退出、页面浏览、应用安装等事件 - **用户识别**:支持匿名用户和登录用户身份关联 - **用户属性管理**:完整的用户属性操作(设置、追加、增量更新等) - **A/B 测试集成**:支持功能开关(Feature Gate)和实验变量获取 - **批量发送**:优化网络请求性能,每 5 秒批量发送最多 10 个事件 - **公共属性**:支持静态和动态公共属性,自动附加到所有事件 ## 系统要求 | 项目 | 要求 | |------|------| | **最低 SDK 版本** | API 21 (Android 5.0) | | **目标 SDK 版本** | API 34 (Android 14) | ## 安装 ### 通过 Maven 仓库安装 在您的 app 模块的 `build.gradle` 文件中添加依赖: ```groovy dependencies { implementation 'com.sensorswave.android:SensorswaveSDK:0.2+' } ``` 或者在使用 Kotlin DSL 的 `build.gradle.kts` 文件中: ```kotlin dependencies { implementation("com.sensorswave.android:SensorswaveSDK:0.2+") } ``` ## 快速开始 ### 1. 添加必要的权限 在您的 `AndroidManifest.xml` 中添加网络权限: ```xml ``` ### 2. 初始化 SDK 在您的 Application 类中初始化 SDK: ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() val config = SensorswaveConfig( apiHost = "https://your-api-host.com", autoCapture = true, enableAB = false ) Sensorswave.getInstance().setup( application = this, sourceToken = "your-source-token", config = config ) } } ``` 在 `AndroidManifest.xml` 中声明 Application 类: ```xml ... ``` ### 3. 设置用户 ID 请初始化之后,尽快设置用户 ID,以确保 A/B 测试等功能正常工作。 ```kotlin // 设置用户 ID(推荐方式) Sensorswave.getInstance().setLoginId("user_12345") // 或者使用 identify(会发送绑定事件) Sensorswave.getInstance().identify("user_12345") ``` ### 4. 追踪自定义事件 ```kotlin Sensorswave.getInstance().trackEvent("ButtonClick", mapOf( "button_name" to "submit", "page" to "home" )) ``` ## 配置选项 | 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `apiHost` | `String` | `""` | API 服务器地址 | | `autoCapture` | `Boolean` | `true` | 是否自动采集应用事件(页面浏览、应用启动、应用安装等) | | `enableClickTrack` | `Boolean` | `false` | 是否启用自动点击追踪 | | `enableAB` | `Boolean` | `false` | 是否启用 A/B 测试功能 | | `abRefreshInterval` | `Long` | `600000` | A/B 测试配置刷新间隔(毫秒),默认 10 分钟 | | `batchSend` | `Boolean` | `true` | 是否使用批量发送(每 5 秒或每 10 个事件批量发送一次) | ### 完整配置示例 ```kotlin val config = SensorswaveConfig( apiHost = "https://your-api-host.com", autoCapture = true, // 开启自动埋点 enableClickTrack = true, // 开启点击追踪 enableAB = true, // 开启 A/B 测试 abRefreshInterval = 10 * 60 * 1000, // A/B 测试数据每 10 分钟刷新 batchSend = true // 批量发送优化性能 ) Sensorswave.getInstance().setup( application = this, sourceToken = "your-source-token", config = config ) ``` > **提示**:在生产环境中建议根据实际需求选择性开启自动埋点功能,以控制数据量。 ## API 方法 ### 事件追踪 #### trackEvent - 追踪自定义事件 手动追踪自定义事件及其属性。 **参数**: - `eventName` (String,必填):事件名称 - `properties` (Map,可选):事件属性 **示例**: ```kotlin // 追踪按钮点击 Sensorswave.getInstance().trackEvent("ButtonClick", mapOf( "button_name" to "submit", "page" to "home" )) ``` **实际场景示例**: ```kotlin // 电商场景:用户浏览商品 Sensorswave.getInstance().trackEvent("ProductView", mapOf( "product_id" to "12345", "product_name" to "无线蓝牙耳机", "category" to "电子产品", "price" to 299.00, "currency" to "CNY" )) // 电商场景:用户加入购物车 Sensorswave.getInstance().trackEvent("add_to_cart", mapOf( "product_id" to "12345", "quantity" to 1, "price" to 299.00 )) // 内容平台:文章阅读 Sensorswave.getInstance().trackEvent("article_read", mapOf( "article_id" to "article_001", "title" to "Android 性能优化技巧", "category" to "技术博客", "read_duration" to 120 // 阅读时长(秒) )) ``` #### track - 高级事件追踪 发送完整的事件对象,支持更精细的控制。此方法允许您手动指定所有事件字段。 **参数**: - `event` (AdvanceEvent,必填):完整事件对象,包含以下字段: - `event` (string,必填):事件名称 - `properties` (mapOf,可选):事件属性 - `time` (number,必填):时间戳(毫秒) - `anon_id` (string,可选):匿名用户 ID - `login_id` (string,可选):登录用户 ID。login_id 和 anon_id 必须传一个,同时传递时,优先使用 login_id - `trace_id` (string,必填):请求追踪 ID - `user_properties` (mapOf,可选):用户属性 **示例**: ```kotlin Sensorswave.getInstance().track(mapOf( "event" to "purchase_completed", "properties" to mapOf( "product_id" to "12345", "amount" to 99.99, "currency" to "USD" ), "time" to System.currentTimeMillis(), "trace_id" to "unique-trace-id-12345", "login_id" to "user_12345" )) ``` > **注意**:`track` 方法是高级功能,大多数场景下使用 `trackEvent` 即可满足需求。 ### 用户识别 #### identify - 设置登录用户 ID 设置登录用户 ID 并发送绑定事件,将匿名行为与已识别用户关联。 **参数**: - `loginId` (String,必填):用户的唯一标识符(如邮箱、用户 ID、用户名) **示例**: ```kotlin // 用户登录后设置用户 ID Sensorswave.getInstance().identify("user_12345") ``` **完整登录流程示例**: ```kotlin // 用户登录流程 fun handleUserLogin(email: String, password: String) { // 调用登录 API apiService.login(email, password) { result -> when (result) { is Success -> { val userId = result.data.userId // 设置用户 ID 并关联匿名行为 Sensorswave.getInstance().identify(userId) // 追踪登录事件 Sensorswave.getInstance().trackEvent("user_login", mapOf( "login_method" to "email" )) } is Error -> { // 处理登录失败 } } } } ``` > **重要提醒**:如果 `loginId` 包含隐私信息(如手机号、邮箱、身份证号等),请务必在加密后再进行传输,避免敏感信息明文上报。 #### setLoginId - 仅设置登录 ID 设置登录用户 ID,但不发送绑定事件。如果您只想识别用户但不需要关联用户,可以使用此方法。 **参数**: - `loginId` (String,必填):用户的唯一标识符 **示例**: ```kotlin Sensorswave.getInstance().setLoginId("user_12345") ``` > **重要提醒**:如果 `loginId` 包含隐私信息(如手机号、邮箱、身份证号等),请务必在加密后再进行传输,避免敏感信息明文上报。 > **使用建议**: > - 在用户登录时推荐使用 `identify` 方法,因为它会记录用户身份关联事件 > - 在应用启动时恢复用户会话可以使用 `setLoginId`,避免发送不必要的绑定事件 ### 用户属性 用户属性用于描述用户的特征,如会员等级、注册时间、偏好设置等。与事件属性不同,用户属性会持久化保存并与用户关联。 #### setProfile - 设置用户属性 设置用户属性,如果属性已存在则覆盖。 **参数**: - `properties` (Map,必填):要设置的用户属性 **示例**: ```kotlin // 用户完成注册后,设置用户属性 Sensorswave.getInstance().setProfile(mapOf( "name" to "John Doe", "age" to 30, "plan" to "premium" )) ``` #### setOnceProfile - 仅首次设置 设置用户属性,仅在属性不存在时设置,已存在的属性不会被覆盖。 **参数**: - `properties` (Map,必填):要设置的用户属性 **示例**: ```kotlin // 记录用户首次访问信息(仅记录一次,后续不会覆盖) Sensorswave.getInstance().setOnceProfile(mapOf( "signup_date" to "2024-01-15", "initial_referrer" to "google", "initial_campaign" to "spring_sale" )) ``` #### profileIncrement - 增量更新数值属性 对数值类型的用户属性进行增减操作。仅支持数值属性。 **参数**: - `properties` (Map,必填):要增减的属性及其数值 **示例**: ```kotlin // 增加单个属性 Sensorswave.getInstance().profileIncrement(mapOf( "login_count" to 1 )) // 增加多个属性 Sensorswave.getInstance().profileIncrement(mapOf( "login_count" to 1, "points_earned" to 100, "purchases_count" to 1 )) ``` #### profileAppend - 追加到数组属性 向数组类型的用户属性追加新值,不进行去重。 **参数**: - `properties` (Map,必填):要追加的属性及其数组值 **示例**: ```kotlin Sensorswave.getInstance().profileAppend(mapOf( "categories_viewed" to listOf("electronics", "mobile_phones"), "tags" to listOf("new_customer", "q1_2024") )) ``` #### profileUnion - 追加到集合属性(去重) 向数组类型的用户属性追加新值,自动去重。 **参数**: - `properties` (Map,必填):要追加的属性及其数组值 **示例**: ```kotlin // 第一次调用 Sensorswave.getInstance().profileUnion(mapOf( "interests" to listOf("technology", "gaming") )) // 第二次调用,"technology" 不会重复添加 Sensorswave.getInstance().profileUnion(mapOf( "interests" to listOf("technology", "music") // 只会增加 "music" )) ``` #### profileUnset - 删除指定属性 将指定的用户属性设置为 null。 **参数**: - `key` (String,必填):要删除的单个属性名 - 或 - `keys` (List,必填):要删除的属性名列表 **示例**: ```kotlin // 删除单个属性 Sensorswave.getInstance().profileUnset("temporary_campaign") // 删除多个属性 Sensorswave.getInstance().profileUnset(listOf("old_plan", "expired_flag", "temp_id")) ``` #### profileDelete - 删除所有用户属性 删除当前用户的所有用户属性数据。此操作不可撤销。 **示例**: ```kotlin // 用户注销账号时,删除所有用户属性 Sensorswave.getInstance().profileDelete() ``` > **警告**:`profileDelete` 会删除所有用户属性,请谨慎使用。 #### 用户属性使用示例 **会员升级场景**: ```kotlin fun handleMembershipUpgrade(newPlan: String) { // 更新会员等级和升级时间 Sensorswave.getInstance().setProfile(mapOf( "plan" to newPlan, "upgrade_time" to System.currentTimeMillis().toString() )) // 增加升级次数 Sensorswave.getInstance().profileIncrement(mapOf( "upgrade_count" to 1 )) // 追踪升级事件 Sensorswave.getInstance().trackEvent("membership_upgrade", mapOf( "from_plan" to "basic", "to_plan" to newPlan )) } ``` ### 公共属性 公共属性会自动添加到所有事件中,适用于需要在每个事件中都包含的通用信息。支持静态属性(固定值)和动态属性(函数返回值)。 #### registerCommonProperties - 注册公共属性 注册静态或动态公共属性,这些属性将自动包含在所有事件中。 **参数**: - `properties` (Map,必填):要注册的属性 - 静态属性:非函数类型的值 - 动态属性:函数类型的值(返回 `() -> Any`),会在每个事件中求值 **示例**: ```kotlin Sensorswave.getInstance().registerCommonProperties(mapOf( // 静态属性 "app_version" to "1.0.0", "environment" to "production", // 动态属性(每个事件都会求值) "current_time" to { System.currentTimeMillis() }, "user_session_id" to { getSessionId() } )) ``` #### clearCommonProperties - 清除公共属性 移除指定的已注册公共属性。 **参数**: - `keys` (List,必填):要移除的属性名列表 **示例**: ```kotlin Sensorswave.getInstance().clearCommonProperties(listOf("app_version", "user_session_id")) ``` > **注意**:公共属性会增加每个事件的数据量,建议仅添加确实需要的通用属性。 ### A/B 测试 Android SDK 内置了 A/B 测试支持,可以获取功能开关状态和实验变量。 #### 开启 A/B 测试功能 ```kotlin val config = SensorswaveConfig( apiHost = "https://your-api-host.com", enableAB = true, // 开启 A/B 测试 abRefreshInterval = 10 * 60 * 1000 // 配置刷新间隔(默认 10 分钟) ) ``` #### checkFeatureGate - 检查功能开关 检查功能开关(Feature Flag)是否为当前用户启用。 **参数**: - `key` (String,必填):功能开关的 Key - `callback` (Boolean -> Unit,必填):回调函数,返回功能开关状态 **示例**: ```kotlin // 检查功能是否启用 Sensorswave.getInstance().checkFeatureGate("new_checkout_flow") { isEnabled -> if (isEnabled) { // 显示新功能 showNewCheckout() } else { // 显示旧功能 showOldCheckout() } } ``` #### getExperiment - 获取实验变量 获取当前用户的实验变量数据。 **参数**: - `key` (String,必填):实验的 Key - `callback` (Map? -> Unit,必填):回调函数,返回实验配置 **返回值**: - `Map?`:实验配置对象,包含实验的变量配置值 **示例**: ```kotlin // 获取实验配置 Sensorswave.getInstance().getExperiment("homepage_layout") { experiment -> if (experiment != null) { // 应用实验配置 val layoutType = experiment["layout_type"] as? String applyLayout(layoutType) } } // 获取实验配置的具体字段 Sensorswave.getInstance().getExperiment("pricing_display") { experiment -> if (experiment != null) { val priceFormat = experiment["price_format"] as? String val discountType = experiment["discount_type"] as? String updatePricingDisplay(priceFormat, discountType) } } ``` **完整 A/B 测试示例**: ```kotlin // 电商首页 CTA 按钮 A/B 测试 fun initHomepageCTA() { Sensorswave.getInstance().getExperiment("homepage_cta_test") { experiment -> if (experiment != null) { val buttonText = experiment["button_text"] as? String ?: "立即购买" val buttonColor = experiment["button_color"] as? String ?: "#ff6600" val buttonSize = experiment["button_size"] as? String ?: "16px" // 应用实验配置 val ctaButton: Button = findViewById(R.id.cta_button) ctaButton.text = buttonText ctaButton.setBackgroundColor(Color.parseColor(buttonColor)) ctaButton.textSize = buttonSize.toFloatOrNull() ?: 16f } } } // Activity 或 Fragment 初始化时调用 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) initHomepageCTA() } ``` > **提示**:A/B 测试功能需要在 Sensors Wave 后台配置实验和功能开关后才能使用。 ### SDK 管理 #### isInitialized - 检查 SDK 是否已初始化 检查 SDK 是否已成功初始化。 **返回值**:Boolean **示例**: ```kotlin if (Sensorswave.getInstance().isInitialized()) { // SDK 已初始化,可以安全调用 Sensorswave.getInstance().trackEvent("custom_event", properties) } else { Log.w("MyApp", "SDK not initialized") } ``` #### destroy - 销毁 SDK 实例 销毁 SDK 实例,释放所有资源。调用此方法后,需要重新调用 `setup()` 才能使用 SDK。 **功能**: 1. 清理批量发送器 2. 停用并清理所有插件 3. 清空公共属性 4. 重置初始化状态 ## 自动埋点 开启自动埋点后,SDK 会自动采集以下事件类型: | 事件名称 | 说明 | 触发时机 | |---------|------|---------| | `$AppInstall` | 应用首次安装 | 应用首次安装时 | | `$AppStart` | 应用启动 | 应用启动时 | | `$AppEnd` | 应用退出 | 应用退出时 | | `$AppPageView` | 页面浏览 | Activity 切换时 | | `$AppPageLeave` | 页面离开 | Activity 切换时 | | `$AppClick` | 元素点击 | 用户点击元素时(需开启 `enableClickTrack`) | ### 开启自动埋点 ```kotlin val config = SensorswaveConfig( apiHost = "https://your-api-host.com", autoCapture = true, // 开启自动埋点 enableClickTrack = true // 开启点击自动追踪 ) ``` > **提示**:自动埋点功能可以大幅减少手动编码工作量,但会增加一定的数据量。建议根据实际需求选择性开启。 ## 最佳实践 ### 初始化时机 在 Application 的 `onCreate()` 中初始化 SDK,确保 SDK 在应用启动时即可用。 ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() val config = SensorswaveConfig( apiHost = "https://your-api-host.com", autoCapture = true ) Sensorswave.getInstance().setup(this, "your-source-token", config) // 尽快设置用户 ID val userId = getUserIdFromPrefs() if (userId.isNotEmpty()) { Sensorswave.getInstance().setLoginId(userId) } } } ``` ### 设置用户 ID 的时机 **推荐**:在用户登录后立即调用 `setLoginId()` 或 `identify()`。 ```kotlin // 用户登录成功后 fun onLoginSuccess(userId: String) { // 保存用户 ID saveUserId(userId) // 设置 SDK 用户 ID Sensorswave.getInstance().setLoginId(userId) } ``` **区别说明**: | 方法 | 是否发送事件 | 适用场景 | |------|------------|---------| | `identify()` | ✅ 是 | 用户登录时,需要记录身份关联事件 | | `setLoginId()` | ❌ 否 | 应用启动时恢复用户会话 | ### A/B 测试集成 确保在调用 A/B 测试相关方法前,已经设置了用户 ID(如果分流主体为 Login ID): ```kotlin // 1. 先初始化 SDK Sensorswave.getInstance().setup(this, "your-source-token", config) // 2. 设置用户 ID Sensorswave.getInstance().setLoginId(userId) // 3. 然后使用 A/B 测试功能 Sensorswave.getInstance().checkFeatureGate("new_feature") { isEnabled -> if (isEnabled) { enableNewFeature() } } ``` ### 使用公共属性 将应用级别的信息注册为公共属性,避免在每个事件中重复添加: ```kotlin Sensorswave.getInstance().registerCommonProperties(mapOf( "app_version" to BuildConfig.VERSION_NAME, "device_model" to android.os.Build.MODEL, "os_version" to android.os.Build.VERSION.RELEASE )) ``` ### 错误处理 所有 SDK 方法都内置了错误处理,但建议添加额外的检查: ```kotlin if (Sensorswave.getInstance().isInitialized()) { Sensorswave.getInstance().trackEvent("custom_event", properties) } else { Log.w("MyApp", "SDK not initialized") } ``` ## 注意事项 ### 性能优化 - 避免在循环中频繁调用 `trackEvent`,建议合并事件或使用节流 - 批量发送功能默认已开启,可有效减少网络请求 - 自动埋点会增加一定性能开销,仅在需要时开启 ### 数据安全 - 不要在事件属性中传递敏感信息(如密码、信用卡号、身份证号) - Source Token 应妥善保管,避免在公开代码仓库中暴露 - SDK 使用 HTTPS 加密传输所有数据 - 用户数据保存在本地 SharedPreferences 中 ### 数据丢失风险 - 移动端埋点可能受网络环境影响,存在约 5-10% 的数据丢失风险 - 核心业务数据建议使用服务端埋点,详见 [埋点方案选择](../tracking-strategy.mdx) ## 常见问题 ### 为什么 A/B 测试返回的配置为空? 检查以下几点: 1. **是否已启用 A/B 测试功能**:确认 `enableAB = true` 2. **网络连接是否正常**:确认设备网络连接正常 3. **用户 ID 是否已设置**:确认已调用 `setLoginId()` 或 `identify()` 4. **服务端是否已配置实验**:确认在 Sensors Wave 后台已配置相应的实验或功能开关 ### 事件发送失败怎么办? SDK 会自动重试失败的事件。检查以下几点: 1. **网络连接**:确认设备网络连接正常 2. **数据上报地址**:确认 `apiHost` 配置是否正确 3. **网络权限**:确认已添加 `INTERNET` 和 `ACCESS_NETWORK_STATE` 权限 4. **调试模式**:开启 `debug` 模式查看详细日志 ### 如何调试 SDK? 配置 debug 模式,检查 Logcat 中标签为 `SensorsWaveSDK` 的日志,查看详细的运行信息。 ### 批量发送和实时发送有什么区别? | 发送方式 | 说明 | 适用场景 | |---------|------|---------| | **批量发送** | 事件会缓存,每 5 秒或每 10 个事件批量发送一次 | 大多数场景,减少网络请求 | | **实时发送** | 每个事件立即发送 | 需要实时数据的场景 | ## 相关文档 - [埋点方案选择](../tracking-strategy.mdx):了解服务端埋点和客户端埋点的优劣 - [如何正确的标识用户](../user-identification.mdx):用户身份识别的最佳实践 - [数据模型](../data-model.mdx):理解 Sensors Wave 的数据结构 - [事件和属性](../events-and-properties.mdx):事件设计规范和最佳实践 --- **最后更新时间**:2026 年 2 月 6 日 **许可证**:Apache-2.0