mcpField
C
contentsquare-android-sdk

contentsquare-android-sdk

github.com/contentsquare开发238 次安装1 周前更新
代码仓库

关于 contentsquare-android-sdk

供 AI Agent 集成或升级 Contentsquare Android SDK 的技能,提供设置与验证步骤,包括项目健康检查、分析配置、屏幕跟踪和故障排查。

主要功能

  1. 01应用 ID 健康检查
  2. 02SDK 依赖与版本指引
  3. 03体验与产品分析配置
  4. 04View 和 Compose 屏幕跟踪
  5. 05通过 Logcat 验证集成

适用场景

  1. 01在 Android 应用中集成 Contentsquare
  2. 02为 Contentsquare 项目配置分析
  3. 03排查 SDK 启动和数据采集问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/contentsquare/agents --skill contentsquare-android-sdk

安装后在 Claude Code 中输入/contentsquare-android-sdk确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api-reference.md
migration-1.5-to-1.11.md
session-replay.md

详细介绍

Contentsquare Android SDK 集成

基于 CSQ SDK 1.11.x 测试。官方文档是权威信息来源——请参阅 参考资料 部分,按需获取最新页面。

强制第一步——Contentsquare 项目健康检查

在一次对话中进行任何 Contentsquare 工作之前——集成、调试、配置问题或代码更改——都要运行此健康检查,每次对话恰好运行一次。不要跳过,也不要推迟到任务稍后再做。

  1. 先告知用户。 告诉用户你将要做什么,例如:

    “开始之前,我会快速检查你的 Contentsquare 项目:读取应用的 application id、调用 Contentsquare 健康检查端点,并向你展示当前项目配置。然后我们再继续。”

  2. 确定 application id。 从 app/build.gradle 或 app/build.gradle.kts 中读取 applicationId。如果不存在,则依次回退到 namespace,再到 AndroidManifest.xml 中的 package 属性。解析所有变量或 flavor 后缀,得到实际发布的字面 id。

  3. 调用端点。 平台字段必须是字面值 android——不接受其他值。

    curl -s "https://mobile-production.content-square.net/healthcheck/android/config/v2/<applicationId>.json"
    
  4. 简要报告以下值:

    报告项JSON 路径
    项目 IDcs_project_id
    跟踪是否已启用project_configurations.project_config.enabled
    Session Replayproject_configurations.project_config.session_replay — recording_rate、record_via_cellular_network、recording_quality_wifi、srm_enabled、user_identifier
    已启用的功能标志project_configurations.project_config.feature_flags — 仅列出 enabled == true 的条目及其 name 和 min_version
  5. 然后继续处理用户的实际请求。

失败处理。 403 Invalid health-check path 表示 URL 格式错误——重新检查 android 字段和 application id,不要更改路径结构。上游返回的非 200 响应表示该 application id 未配置 Contentsquare 项目:告知用户这一点,然后仍然继续。此健康检查仅供参考,绝不能阻碍用户的任务。

完成标准

只有以下所有条件都满足,集成才算完成。任何一项缺失,集成都无法正常工作,也不会有数据到达 Contentsquare。

  1. ✅ 模块依赖中包含 com.contentsquare.android:sdk:<latest>(使用 Compose 时还需包含 sdk-compose:<same version>)。
  2. ✅ 存在自定义 Application 子类,通过 AndroidManifest.xml 中的 android:name 注册,并且其 onCreate() 调用 CSQ.start(this, …)。
  3. ✅ 调用了 CSQ.optIn()——在 Application.onCreate() 中无条件调用,紧接在 CSQ.start(...) 之后,并由 TODO: REVIEW BEFORE RELEASE 注释标记。集成阶段必须执行此操作。 CSQ 默认退出采集;如果不调用 optIn(),logcat 会显示 enabledForCollection is false,且不会上传任何数据——这意味着无法验证集成。将 optIn() 移至同意流程属于单独的后续任务,应由应用团队在发布前完成;不要在初始集成期间尝试这样做。若把 optIn() 推迟到未来的同意流程,却报告“集成已完成”,则表示集成未通过。
  4. ✅ 至少有一个屏幕已完成埋点(Views 使用 CSQ.trackScreenview(...),Compose 使用 TriggeredOnResume { CSQ.trackScreenview(...) })。
  5. ✅ Logcat 冒烟测试通过——请参阅下方的“验证集成”。请将 Tracked pageview … / writeToDb: Attempting to insert session … / All pending data has been uploaded 视为成功信号。 enabledForCollection is false 这行日志会在正常启动期间输出,单凭这一行并不代表失败——不要因此删除 optIn()。

概念

CSQ SDK(“CSQ”代表 ContentSQuare)整合了三条产品线:

  • Experience Analytics(EA) — 前身为“Contentsquare”。提供会话回放、屏幕视图、交易、动态变量、错误分析、调查(客户之声)、热力图和区域划分。通过简单调用 CSQ.start(context) 默认启用。
  • Product Analytics(PA) — 前身为“Heap”。提供自定义事件、用户属性、事件属性、identify / resetIdentity。将 StartConfig.withEnvironmentId(...) 传递给 start() 即可启用。
  • Unified CSQ — 通过单个 dataSourceId 配置 EA 和 PA,并通过 StartConfig.withDataSourceId(...) 传递。

根据客户订阅的产品,从以下三个 start() 重载中选择一个。仅使用 EA 是最常见的入口。

安装

添加依赖前,务必从 Maven Central 获取最新稳定版本。 不要保留 <version> 占位符。

每个构件都有自己的元数据文件。请获取这两个文件:

  • sdk:https://repo1.maven.org/maven2/com/contentsquare/android/sdk/maven-metadata.xml
  • sdk-compose(仅在使用 Jetpack Compose 时):https://repo1.maven.org/maven2/com/contentsquare/android/sdk-compose/maven-metadata.xml

这些文件由 Maven Central 直接提供,是唯一可信来源。 不要使用 search.maven.org API——其索引更新滞后,且经常返回过期版本。

从每个 maven-metadata.xml 中选择版本的方法:

  1. 读取 <versioning><versions> 中的所有 <version> 条目。
  2. 筛除所有预发布版本:排除包含 -SNAPSHOT、-alpha、-beta、-rc、-dev、-M 的版本(不区分大小写)。
  3. 使用语义化版本排序规则对其余版本排序(按数字比较:先主版本,再次版本,最后补丁版本)。
  4. 选择其中最高的版本。可以将 <latest> 标签作为参考,但务必交叉检查,确保它不是预发布版本。

版本对齐规则:

  • sdk 和 sdk-compose 必须固定为完全相同的版本字符串。
  • 分别计算每个构件的最新稳定版本,然后使用两个列表中都存在的最高版本。
// Module-level build.gradle.kts
dependencies {
    implementation("com.contentsquare.android:sdk:X.Y.Z") // resolved latest stable

    // Only if the app uses Jetpack Compose (MUST match sdk version exactly):
    implementation("com.contentsquare.android:sdk-compose:X.Y.Z")
}
项目要求
  • minSdkVersion:21(Android 5.0 Lollipop)
  • compileSdkVersion:34 或更高
  • Java:11(sourceCompatibility / targetCompatibility / jvmTarget = 11;使用更低版本的 Java 会导致 bad class file 错误)。Java 17 及更高版本也可用。
  • Kotlin:1.8.22(SDK 自带 stdlib;如发生冲突,请排除 org.jetbrains.kotlin:kotlin-stdlib-jdk8)
  • Jetpack Compose:Compose Compiler 1.4.8(已测试 Compose BOM 2024.09.00)——使用 sdk-compose 时适用

无需手动添加任何 AndroidManifest.xml 权限——SDK 会声明所需权限并自动合并。

快速入门

最简 Experience Analytics 集成。SDK 要收集任何数据,必须同时调用 CSQ.start(...) 和 CSQ.optIn():未调用 optIn() 时,用户默认处于退出状态,且 enabledForCollection 保持为 false(可在 logcat 中查看)。务必同时发出这两个调用——即使看起来 optIn() 应该放在同意流程中,也绝不要在快速入门集成中省略它。TODO: REVIEW BEFORE RELEASE 注释是向审核者表明调用必须在发布前移至实际同意流程的约定标记。

import android.app.Application
import com.contentsquare.CSQ

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        CSQ.start(this)
        // TODO: REVIEW BEFORE RELEASE — `optIn()` MUST be wired to your real
        // consent flow (CMP / consent dialog) and NOT called unconditionally
        // here.
        CSQ.optIn()
    }
}

别忘了在 AndroidManifest.xml 中注册 MyApplication:

<application android:name=".MyApplication" ... >

跟踪屏幕(Android Views):

import com.contentsquare.CSQ

class HomeActivity : AppCompatActivity() {
    override fun onResume() {
        super.onResume()
        CSQ.trackScreenview("HomeScreen")
    }
}

跟踪屏幕(Jetpack Compose):

import com.contentsquare.CSQ
import com.contentsquare.api.compose.TriggeredOnResume

@Composable
fun HomeScreen() {
    TriggeredOnResume {
        CSQ.trackScreenview("HomeScreen")
    }
    // screen content
}
验证集成

同一次运行中同时出现以下日志,即表示端到端集成验证通过:

  1. SDK 启动(始终会输出):

    CSQ <version> for <Product Analytics|Experience Analytics> is attempting to start.
    

    以及

    Contentsquare SDK <legacy-version> starting in app: <package>
    
  2. 正在收集并持久化数据——至少出现以下一项:

    Tracked pageview from android_view_autocapture.
    User.writeToDb: Attempting to insert user - envId: <ID>, userId: <ID>, ...
    writeToDb: Attempting to insert session - envId: <ID>, userId: <ID>, sessionId: <ID>
    All pending data has been uploaded.
    

    上述任意一项都能证明 optIn() 已生效且数据正在流动。

⚠️ 请勿将 enabledForCollection 用作诊断依据

以下日志行:

BatchUploaderOrchestrator: Condition not met - state.isFullyStopped: false  enabledForCollection is false.

在 SDK 正常启动期间会输出多次——即使已正确调用 optIn() 也会如此——因为编排器会在内存状态加载完成之前运行。这本身并不表示发生故障。 与 Starting service DXA / Starting service PA 交错出现三到四次属于预期情况。

只有当同一 logcat 会话中始终没有出现任何 "writeToDb" / "Tracked pageview" / "All pending data has been uploaded" 日志行时,才表示存在实际问题。不要仅凭这条日志就从集成中删除 CSQ.optIn()。

常见故障模式
  • ❌ 有启动日志,但始终没有任何 writeToDb: Attempting to insert user/session 日志行 → 缺少 CSQ.optIn(),或未执行到该调用。在 Application.onCreate() 中的 CSQ.start(...) 之后立即添加 CSQ.optIn()(参见完成标准第 3 项)。
  • ❌ 完全没有 CSQ 日志 → 你的 Application 子类未通过 android:name=".MyApplication" 注册到 AndroidManifest.xml。
  • ❌ mobile-production.content-square.net/android/config/v2/<package>.json 返回 404 → Contentsquare 项目尚未为此 applicationId 配置。集成早期出现此情况属于预期;请让客户创建项目。追踪仍会在本地正常工作;事件会保存到 SQLite,并在项目创建后上传。
  • ❌ 启动期间出现一次 onTrackingStarted: config, or environment null aborting. → 无害:这是 EA 路径在应用仅以 PA 模式启动时发出的提示。除非该提示持续出现数秒,否则可忽略。

开发期间若要获取详细日志,请在 start() 之后立即启用调试日志:

import com.contentsquare.api.model.LogLevel
CSQ.debug.logLevel = LogLevel.DEBUG

启动 SDK——三种重载

所有启动变体都通过 com.contentsquare.CSQ 提供。请注意,包名是 com.contentsquare,而不是 com.contentsquare.android。

1. 仅 Experience Analytics(默认)
CSQ.start(context = this)
2. Product Analytics(可选扩展 EA)——environmentId
import com.contentsquare.CSQ
import com.contentsquare.StartConfig
import com.contentsquare.api.model.AnalyticsOptions

CSQ.start(
    context = this,
    StartConfig.withEnvironmentId(
        id = "YOUR_ENVIRONMENT_ID",
        options = AnalyticsOptions(
            enableViewAutocapture = true
        )
    )
)

StartConfig 是 com.contentsquare 包中的顶层密封类。AnalyticsOptions、Transaction、Currency、CustomVar、NetworkMetric、Metadata、Debug、LogLevel 均位于 com.contentsquare.api.model 中。

3. 统一 CSQ——dataSourceId
CSQ.start(
    context = this,
    StartConfig.withDataSourceId(id = "YOUR_DATASOURCE_ID")
)

environmentId 和 dataSourceId 可从 app.contentsquare.com 上的 Contentsquare 项目设置中获取。切勿将它们硬编码——应从 BuildConfig、环境变量或配置资源中读取。

AnalyticsOptions(当前选项,v1.11.x)
选项类型默认值用途
enableViewAutocaptureBooleanfalse自动捕获 UI 交互和来源页面浏览(仅支持 Android Views,不支持 Compose)。
disablePageviewAutocaptureBooleanfalse禁用自动捕获的来源页面浏览。
enablePushNotificationAutocaptureBooleanfalse自动捕获通知上的交互。
enablePushNotificationTitleAutocaptureBooleanfalse捕获通知标题(需要 enablePushNotificationAutocapture = true)。
enablePushNotificationBodyAutocaptureBooleanfalse捕获通知正文(需要 enablePushNotificationAutocapture = true)。
baseUriURIURI("https://mh.bf.contentsquare.net")API 端点的基础 URI。
uploadIntervalDouble(秒)15.0事件批次上传间隔。
sessionReplayAutoStartBooleantrue设为 false 可禁用 Session Replay 自动启动;可通过 CSQ.startSessionReplay() / CSQ.stopSessionReplay() 手动控制。

StartConfig.dxa() 也接受可选的 AnalyticsOptions 参数(例如,在仅启用 EA 的模式下禁用 Session Replay 自动启动)。

旧版文档和此前的 CSQ.configureProductAnalytics(...) 方法已弃用。新集成一律使用 CSQ.start(context, StartConfig.…)。

堆自动采集(仅限 PA / 统一模式)

如果客户仅通过 CSQ.start(context) 启动 CSQ(仅 EA 模式),请跳过本节。 io.heap.gradle 插件和 ComposeAutocaptureSDK 仅适用于通过 StartConfig.withEnvironmentId(...)(Product Analytics)或 StartConfig.withDataSourceId(...)(统一模式)启动 CSQ 的情况。仅 EA 集成通过显式的 CSQ.trackScreenview(...) API 获取页面浏览数据,无需进行这些设置。

当客户提供 environmentId(PA)或 dataSourceId(统一模式)时,表示他们选择使用 Heap 风格的自动采集。若要实际自动采集交互(按钮点击、屏幕浏览等),应用必须通过 Heap Gradle 插件添加字节码检测。

View 自动采集(Android Views)
  1. 在模块 build.gradle.kts 中应用插件(不要在 settings 或根目录中应用):

    plugins {
        id("com.android.application")
        kotlin("android")
        id("io.heap.gradle") version "1.1.1" // latest stable
    }
    

    最新稳定版本见:https://repo1.maven.org/maven2/io/heap/gradle/io.heap.gradle.gradle.plugin/maven-metadata.xml。选择版本时,遵循与 sdk / sdk-compose 相同的规则。

  2. 通过 AnalyticsOptions 启用 View 自动采集(内部会调用 ViewAutocaptureSDK.register()——不要手动调用):

    CSQ.start(
        context = this,
        StartConfig.withEnvironmentId(
            id = BuildConfig.CSQ_ENVIRONMENT_ID,
            options = AnalyticsOptions(enableViewAutocapture = true)
        )
    )
    

验证:logcat 会显示 Source android_view_autocapture successfully registered.,并且(点击或屏幕切换后)显示 Tracked pageview from android_view_autocapture.。

Compose 自动采集

enableViewAutocapture = true 不涵盖 Jetpack Compose——其文档字符串明确说明 "Only for Android View system, no Compose support." 要启用 Compose 自动采集,以下三项缺一不可:

  1. 已应用 io.heap.gradle 插件(与上文 View 自动采集的设置相同)。

  2. 已通过 implementation("com.contentsquare.android:sdk-compose:<version>") 引入 sdk-compose 工件(它会传递引入 io.heap.autocapture:heap-autocapture-compose)。

  3. 在 CSQ.start(...) 后手动注册:

    import io.heap.autocapture.compose.ComposeAutocaptureSDK
    
    override fun onCreate() {
        super.onCreate()
        CSQ.start(this, StartConfig.withEnvironmentId(BuildConfig.CSQ_ENVIRONMENT_ID))
        ComposeAutocaptureSDK.register()  // Compose autocapture is NOT enabled by AnalyticsOptions
        CSQ.optIn() // TODO: REVIEW BEFORE RELEASE — see Privacy/Consent
    }
    

    注意导入路径:io.heap.autocapture.compose.ComposeAutocaptureSDK(它位于捆绑的 Heap autocapture-compose 模块中,而非 com.contentsquare.*)。

验证:logcat 会显示 Source android_compose_autocapture successfully registered.。(HeapInstrumentation) semantics: capture is disabled; using stock Modifier.semantics 这一行属于正常情况——语义采集需通过 ComposeAutocaptureSDK.register(enableSemanticsCapture = true) 主动启用;大多数应用使用默认设置即可。

手动页面浏览仍可与自动采集同时使用

即使启用了自动采集,你仍然可以(而且通常应该)通过 CSQ.trackScreenview("Conversation") 或在 Compose 中使用 TriggeredOnResume { … } 上报命名页面浏览。与自动推导的类名/路由名相比,手动命名在 Heap 界面中显示的标签更有意义。

隐私 / 同意

SDK 默认将每位用户都视为已选择退出。只有调用 optIn() 后才会开始跟踪。

// In your consent UI (button click, dialog confirmation, etc.)
CSQ.optIn()

// To revoke consent
CSQ.optOut()

之前存在的 CSQ.optIn(context: Context) 重载已弃用——请始终使用无参数的 CSQ.optIn()。

规则:

  • 在 start() 之后调用 optIn()。
  • 切勿在 Application.onCreate() 中自动调用 optIn()——应等待用户明确同意。
  • optOut() 会删除用户 ID,并停止所有跟踪,直到再次调用 optIn()。
  • 如需获取用于数据主体请求的 Contentsquare 用户 ID:CSQ.metadata.userId。
暂停 / 恢复

在敏感界面(例如支付流程)临时暂停跟踪:

CSQ.pauseTracking()
// ... user is on the sensitive screen ...
CSQ.resumeTracking()

API 概览

所有方法都位于 com.contentsquare.CSQ 对象上。

生命周期
  • CSQ.start(context) — 启动 SDK(仅 EA)。
  • CSQ.start(context, StartConfig.withEnvironmentId(id, options)) — PA(可选包含 EA)。
  • CSQ.start(context, StartConfig.withDataSourceId(id)) — 统一 CSQ。
  • CSQ.stop() — 关闭 SDK。
  • CSQ.pauseTracking() / CSQ.resumeTracking() — 临时暂停/恢复数据采集。
隐私
  • CSQ.optIn() — 允许用户加入追踪。必须在调用 start() 后调用。
  • CSQ.optOut() — 停止追踪并清除用户数据。
身份
  • CSQ.identify(identity: String) — (PA) 设置身份。最长 255 个字符。会触发新的用户 ID 和会话。
  • CSQ.resetIdentity() — (PA) 清除身份并开始新会话。
  • CSQ.sendUserIdentifier(identifier: String) — (EA) 发送经过哈希处理的用户标识符。最长 100 个字符。建议在每次应用进入前台时调用(使用 ProcessLifecycleOwner)。
屏幕追踪
  • CSQ.trackScreenview(name: String, customVars: List<CustomVar> = emptyList()) — 追踪屏幕浏览。
  • CustomVar(index: Int /* 0..20 */, name: String /* ≤ 512 chars */, value: String /* ≤ 255 chars */)
  • TriggeredOnResume { ... }(com.contentsquare.api.compose 中的可组合项)— 在 Compose 中包装 trackScreenview 调用,使其仅在每次屏幕展示时触发一次。

屏幕名称:每个应用中使用少于 100 个互不重复的名称。切勿包含个人身份信息(PII),例如邮箱、姓名、账户 ID 等。

交易(EA)
import com.contentsquare.api.model.Transaction
import com.contentsquare.api.model.Currency

val transaction = Transaction(value = 430.99f, currency = Currency.EUR, id = "order_123")
CSQ.trackTransaction(transaction)

签名:Transaction(value: Float, currency: Currency, id: String? = null)。

⚠️ 每笔交易只能发送一次。 一个常见错误是在确认屏幕的 onResume() 中调用此方法,导致用户每次将应用重新切回前台时都会发送交易。

Currency 是遵循 ISO 4217 的枚举。辅助方法:Currency.fromString("USD")、Currency.fromInteger(840)、Currency.USD.stringCode。

自定义事件和属性
  • CSQ.trackEvent(event: String, properties: Map<String, Any> = mapOf()) — (PA) 追踪命名事件。
  • CSQ.addUserProperties(properties: Map<String, Any>) — (PA) 设置用户级属性。
  • CSQ.addEventProperties(properties: Map<String, Any>) — (PA) 设置要添加到所有后续事件的属性。
  • CSQ.removeEventProperty(key: String) — (PA) 移除一个适用于所有事件的属性。
  • CSQ.clearEventProperties() — (PA) 移除所有适用于所有事件的属性。
  • CSQ.addDynamicVar(key: String, value: String) / CSQ.addDynamicVar(key: String, value: Long) — (EA) 添加会话级变量。键最长 512 个字符;每次屏幕浏览最多使用 40 个不同的键。

属性值:String、Number、Boolean,或实现 Property 接口的对象。

Session Replay 遮罩

默认行为:全部遮罩。明确取消遮罩你希望显示的元素。

视图:

  • CSQ.setDefaultMasking(masked: Boolean) — 全局默认设置。不影响 EditText / Compose TextField。
  • CSQ.mask(view: View) / CSQ.unmask(view: View) — 针对单个实例。
  • CSQ.mask(type: Class<*>) / CSQ.unmask(type: Class<*>) — 针对类型。(EA)
  • CSQ.maskTexts(mask: Boolean) — 全局文本遮罩开关。
  • view.csqMaskContents(enable: Boolean) — View 的 Kotlin 扩展函数。
  • CSQ.ignoreInteractions(view: View) / view.csqIgnoreInteractions() — 停止跟踪视图的手势。

Compose:

  • CsqMask(enable: Boolean) { content } — 遮罩可组合项子树(Session Replay + 分析)。
  • CsqIgnoreInteraction(ignore: Boolean) { content } — 忽略子树上的交互。
  • CsqTag(CsqTag.ModalBottomSheetLayout) { content } — 为可组合项添加标记以进行特殊处理(支持 ModalBottomSheetLayout 的热图/分区)。

对话框(Views)— com.contentsquare.api.sessionreplay 中的扩展函数:

  • AlertDialog.csqMask()、csqMaskTitle()、csqMaskMessage()、csqMaskPositiveButton()、csqMaskNegativeButton()(以及对应的 csqUnmask… 函数)。
  • DatePickerDialog.csqMask()、csqMaskHeader()、csqMaskCalendar()、csqMaskButtonPanel()(以及对应的 csqUnmask… 函数)。
  • TimePickerDialog.csqMask()、csqMaskHeader()、csqMaskRadialPicker()、csqMaskInputMode()、csqMaskButtonPanel()(以及对应的 csqUnmask… 函数)。
  • 在主线程上,于 dialog.show() 后立即调用这些函数。

菜单(Views):

  • CSQ.maskMenuItem(itemId) / CSQ.unmaskMenuItem(itemId) — 遮罩/取消遮罩单个菜单项。

遮罩调用时机:

  • Activity:在 onCreate() 中。
  • Fragment:在 onViewCreated() 中。
  • 始终在首次绘制前于 UI 线程上调用。

请注意以下限制:

  • 按实例或类型进行遮罩时不支持动画 — 请改为遮罩父视图或整个屏幕。
  • Compose:不支持按类型遮罩;请改为将父可组合项包裹在 CsqMask 中。
  • SurfaceView、MapView 的内容无法进行部分遮罩。
Session Replay 控制

当 AnalyticsOptions.sessionReplayAutoStart = false 时,可手动控制录制:

CSQ.startSessionReplay()
// ...
CSQ.stopSessionReplay()
事件触发回放(ETR,可选附加功能)
CSQ.triggerReplayForCurrentSession(name = "checkout_funnel")
CSQ.triggerReplayForCurrentScreen(name = "payment_failure")
WebView 跟踪
CSQ.registerWebView(webView)
// later:
CSQ.unregisterWebView(webView)

其中加载的网页也需要安装 Contentsquare WebView Tracking Tag — 请参阅 WebView 文档。

调查问卷(EA Voice of Customer)
CSQ.triggerSurvey("purchase-complete")
错误跟踪(EA)
import com.contentsquare.api.contract.CsqOkHttpInterceptor

val client = OkHttpClient.Builder()
    .addInterceptor(CsqOkHttpInterceptor())
    .build()

// Mask sensitive URL paths
CSQ.setUrlMaskingPatterns(listOf("/users/[0-9]+", "/orders/[A-Z0-9-]+"))

// Manual network metric tracking (statusCode required for proper error reporting)
import com.contentsquare.api.model.NetworkMetric
import com.contentsquare.api.model.HttpMethod

val metric = NetworkMetric("http://www.example.com", HttpMethod.GET)
// ... perform request ...
metric.statusCode = 500
metric.responseBody = body
CSQ.trackNetworkMetric(metric)

// Manual gesture tracking when autocapture is not enough
override fun dispatchTouchEvent(motionEvent: MotionEvent): Boolean {
    CSQ.trackMotionEvent(motionEvent)
    return super.dispatchTouchEvent(motionEvent)
}

CsqOkHttpInterceptor 要求类路径中包含 OkHttp 4.x(在 SDK 中声明为 compileOnly)。

视图跟踪
  • CSQ.excludeFromExposureMetric(view: View) — 将 ScrollView 或 RecyclerView 从曝光指标中排除。(EA)
调试、日志记录、元数据
import com.contentsquare.api.model.LogLevel

CSQ.debug.logLevel = LogLevel.DEBUG // NONE, ERROR, WARN, INFO (default), DEBUG, TRACE
CSQ.debug.logChannel = customLogChannel // Implement com.contentsquare.api.contract.LogChannel to route to Timber, etc.

val userId       = CSQ.metadata.userId
val sessionId    = CSQ.metadata.sessionId
val projectId    = CSQ.metadata.projectId
val envId        = CSQ.metadata.environmentId
val replayUrl    = CSQ.metadata.sessionReplayUrl
val identity     = CSQ.metadata.identity

CSQ.metadata.onChanged = OnMetadataChanged { metadata ->
    // Forward replay URL to your CRM / crash reporter
}
// Unregister:
CSQ.metadata.onChanged = null

常见模式

1. 应用初始化(仅 EA)
import com.contentsquare.api.model.LogLevel

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        CSQ.start(this)
        if (BuildConfig.DEBUG) CSQ.debug.logLevel = LogLevel.DEBUG
        // TODO: REVIEW BEFORE RELEASE — wire `optIn()` to your real consent flow.
        CSQ.optIn()
    }
}
2. 应用初始化(Product Analytics)
import com.contentsquare.CSQ
import com.contentsquare.StartConfig
import com.contentsquare.api.model.AnalyticsOptions

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        CSQ.start(
            context = this,
            StartConfig.withEnvironmentId(
                id = BuildConfig.CSQ_ENV_ID,
                options = AnalyticsOptions(enableViewAutocapture = true)
            )
        )
    }
}
3. 同意流程
fun handleConsent(userAccepted: Boolean) {
    if (userAccepted) CSQ.optIn() else CSQ.optOut()
}
4. 跟踪购买
CSQ.trackTransaction(
    Transaction(value = 49.99f, currency = Currency.EUR, id = "txn_abc")
)
5. 携带属性的自定义事件(PA)
CSQ.trackEvent(
    event = "add_to_cart",
    properties = mapOf(
        "product_id" to "sku_123",
        "quantity"   to 2,
        "is_promo"   to true
    )
)
6. OkHttp 错误跟踪
import com.contentsquare.api.contract.CsqOkHttpInterceptor

val client = OkHttpClient.Builder()
    .addInterceptor(CsqOkHttpInterceptor())
    .build()
7. 带有选择性遮罩的 Compose 屏幕
@Composable
fun ProductDetailScreen(product: Product) {
    TriggeredOnResume { CSQ.trackScreenview("ProductDetail") }
    Column {
        Text(text = product.name) // masked by default
        CsqMask(enable = false) {
            Text(text = product.publicDescription) // explicitly visible
        }
    }
}
8. 每次进入前台时发送哈希处理后的用户标识符(EA)
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) {
        currentUser?.email?.let { CSQ.sendUserIdentifier(it) }
    }
})

应避免的反模式

  • ❌ CSQ.trackScreenview("[email protected]") → 屏幕名称中包含个人身份信息(PII)。✅ "ProfileScreen"。
  • ❌ 在源代码中硬编码 environmentId / dataSourceId。✅ 使用 BuildConfig 或资源。
  • ❌ 在生产环境中无条件调用 CSQ.optIn(),并将其写在 Application.onCreate() 中。✅ 发布前,将其接入实际的同意流程(CMP / 同意对话框)。在初始集成和 QA 期间,可以将其留在 onCreate() 中,但须添加 TODO: REVIEW BEFORE RELEASE 注释,以便端到端验证 SDK。
  • ❌ 在确认屏幕的 onResume() 中发送同一笔 Transaction。✅ 订单成功后发送一次。
  • ❌ sdk 和 sdk-compose 使用不同版本。✅ 将两者固定为完全相同的版本。
  • ❌ 使用已弃用的 CSQ.configureProductAnalytics(...)。✅ 使用 CSQ.start(context, StartConfig.…)。
  • ❌ 直接在 @Composable 中调用 CSQ.trackScreenview(每次重组都会触发)。✅ 使用 TriggeredOnResume { … } 包装。
  • ❌ 在 CSQ.start() 之前调用 CSQ.optIn()。✅ 先调用 start,再调用 optIn。

从旧版本迁移

如果宿主应用已声明旧版本的 CSQ SDK(com.contentsquare.android:sdk),请先查阅相应的迁移指南,再进行其他操作:

当前版本目标版本指南
1.0.x – 1.5.x1.11.xreferences/migration-1.5-to-1.11.md

如果要从 Classic Contentsquare SDK(com.contentsquare.android:library)或 Heap Core + Contentsquare 组合迁移,请从 Contentsquare 文档中查找专用的 upgrade-from-cs-sdk / upgrade-from-heap-and-cs-sdk 页面(见下文 参考资料 部分)——这些迁移路径不在此技能的涵盖范围内。

参考资料

Contentsquare 官方文档提供每个页面的 Markdown 版本,可按需获取最新信息。请始终优先使用这些文档,而不是此技能中的缓存快照。

何时加载各参考资料:

  • 需要准确的方法签名或完整参数列表 → 获取 API 参考。
  • 实现或调试遮罩 → 获取会话回放页面。
  • 兼容性/版本冲突(Kotlin、Compose、依赖项)→ 获取兼容性页面。
  • 从 Classic Contentsquare SDK 或 Heap 迁移 → 从 llms.txt 获取相应的 upgrade-from-… 页面。

此技能旁还提供所选参考资料的本地镜像:

评论

支持 Markdown