Flutter SDK
从 Flutter SDK 下载页获取离线集成包,并使用包内配套的 Android/iOS 原生组件。适用版本以下载页为准。
包声明 Dart >=3.0.0、Flutter >=3.10.0。
一、 支持范围与接入前确认
- 向项目负责人获取测试环境的
endpoint和公开projectKey;在真机上使用设备可访问的地址。 - SDK 使用包内配套的 Android/iOS 原生组件管理身份、队列和上传。
- 以下示例适用于宿主已确认允许基础采集的情况。需要事前授权时,以
ConsentLevel.pending初始化,用户同意后由宿主调用setConsent(ConsentLevel.granted)。 - 事件属性和路由名称应避免包含凭据或不必要的个人信息。
二、 安装与原生依赖配置
解压离线包后,按宿主项目选择以下安装方式。
1. 添加 Flutter 依赖
在 Flutter 项目的 pubspec.yaml 中添加依赖:
dependencies:
flutter:
sdk: flutter
track_business_flutter:
path: ./libs/track-business-flutter-<下载包版本> # 解压 Flutter 离线集成包后的目录运行获取依赖包:
flutter pub get2. iOS 依赖安装
cd ios
pod install原生依赖: 离线包固定包含
ios/Frameworks/TrackBusinessSDKKit.xcframework;缺少时安装明确失败,不回退到公开 SDK Pod。
**iOS 模拟器:**请确认下载的 SDK 包包含与开发电脑匹配的模拟器架构。如果 SDK 包仅包含 ARM64 模拟器版本,请在 Apple Silicon Mac 上使用 ARM64 模拟器;若构建同时要求
x86_64,请在应用工程及 CocoaPods 构建配置中排除模拟器的x86_64架构。Intel Mac 上的模拟器需要包含x86_64模拟器版本的 SDK 包。
3. Android 依赖配置
在宿主 android/settings.gradle 的 dependencyResolutionManagement.repositories 中加入下载包的本地 Maven 目录(按实际目录调整,保留项目已有仓库):
// android/settings.gradle
dependencyResolutionManagement {
repositories {
exclusiveContent {
forRepository { maven { url = uri(file('../libs/track-business-flutter-1.0.0/android/maven')) } }
filter { includeGroup('com.trackbusiness') }
}
google()
mavenCentral()
}
}旧版宿主没有 dependencyResolutionManagement 时,可在项目级 android/build.gradle 使用:
查看旧版 Gradle 配置
allprojects {
repositories {
exclusiveContent {
forRepository { maven { url = uri(rootProject.file('../libs/track-business-flutter-1.0.0/android/maven')) } }
filter { includeGroup('com.trackbusiness') }
}
google()
mavenCentral()
}
}两种方式按宿主配置选择其一,不要把 allprojects 放到 settings.gradle。启用 FAIL_ON_PROJECT_REPOS 或 PREFER_SETTINGS 的宿主使用 settings 仓库块。
如果项目使用 Kotlin DSL(.gradle.kts 文件),请根据项目现有的仓库管理方式添加同一目录。例如,项目级 android/build.gradle.kts 使用 allprojects.repositories 时:
allprojects {
repositories {
exclusiveContent {
forRepository {
maven { url = uri(rootProject.file("../libs/track-business-flutter-1.0.0/android/maven")) }
}
filter { includeGroup("com.trackbusiness") }
}
google()
mavenCentral()
}
}请将示例路径调整为 pubspec.yaml 中填写的 SDK 目录。如果项目要求在 settings 文件中统一管理仓库,请将仓库配置放在 settings.gradle.kts 的 dependencyResolutionManagement.repositories 中,并保留项目已有的仓库配置。
原生依赖: 插件离线包内的
android/maven附 AAR、POM 与 Module 元数据;插件声明固定原生版本。缺包不会回退到公开 SDK Registry。通用 Flutter/AndroidX 依赖仍由宿主环境提供。
三、 SDK 初始化
先启动应用界面,再异步初始化 SDK:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:track_business_flutter/track_business_flutter.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
unawaited(initializeAnalytics());
}
Future<void> initializeAnalytics() async {
try {
await TrackBusinessFlutter.instance.initialize(
const TrackBusinessConfig(
endpoint: 'https://collector.example.com/v1/events/batch',
projectKey: 'your-public-project-key',
deferredCapture: false,
initialConsent: ConsentLevel.granted,
),
);
} on TrackBusinessException catch (error) {
debugPrint('Track Business 初始化未完成:${error.code}');
}
}原生端在后台完成存储和身份恢复。调用 SDK API 前可检查 isInitialized,初始化失败时继续业务流程。日志记录受控错误码即可。
初始化配置参数说明
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
endpoint | String | 是 | - | 网关或上报接收端 URL(支持 HTTP 与 HTTPS) |
projectKey | String | 是 | - | 环境唯一公开凭据 |
deferredCapture | bool | 否 | false | 为 true 时以 PENDING 初始化,授权前不采集或入队 |
initialConsent | ConsentLevel | 否 | granted | 初始隐私合规状态(pending / granted / denied) |
四、 核心 API 使用
1. 自定义事件埋点 (track)
await TrackBusinessFlutter.instance.track('sdk_integration_check', properties: {
'source': 'flutter-docs',
});使用测试项目运行该合成事件。检查原生端队列与诊断,再通过目标测试 Collector 核对事件与有效整批 ACK;调用完成不等于接收成功。完整步骤见数据校验。
排查时可读取当前原生健康状态和队列计数:
final sdk = TrackBusinessFlutter.instance;
final health = await sdk.getHealthSnapshot();
final queue = await sdk.getQueueStats();
print('SDK 状态: ${health.status}, 待发送事件: ${queue.pendingEvents}');快照反映调用时的本地状态,队列为空也不能单独证明 Collector 已接收;需要确认投递时使用本页的 verifyDelivery 和接收端检查。避免在日志中输出事件属性或用户身份。
2. 页面与屏幕曝光 (screen)
await TrackBusinessFlutter.instance.screen('ProductDetailScreen', properties: {
'category': 'Electronics',
'sku': 'SKU_100234',
});3. 用户登录与绑定 (identify)
当用户在 App 完成登录或身份认证时,调用 identify 绑定业务主体:
await TrackBusinessFlutter.instance.identify('user_vip_9988');4. 退出身份与重置
安全退出账号时调用 signOut();需要退出登录但保留匿名旅程时调用 clearUser()。reset() 用于显式重置身份,不应替代所有退出场景。
await TrackBusinessFlutter.instance.signOut();5. 请求刷新队列 (flush)
await TrackBusinessFlutter.instance.flush();五、 按需启用页面与点击事件
1. 路由生命周期监听 (TrackNavigationObserver)
只有将 TrackNavigationObserver 注册到 MaterialApp 的 navigatorObservers 后,SDK 才会针对该 Navigator 的命名路由跳转(didPush、didPop、didReplace)调用原生 screen()。它不会扫描其它页面或控件:
MaterialApp(
title: 'My App',
navigatorObservers: [
TrackNavigationObserver(),
],
routes: {
'/': (context) => const HomeScreen(),
// 示例中的实际命名路由;Observer 会把数字段归一化为 :id。
'/order/123': (context) => const OrderDetailScreen(),
},
);高基数路由规整保护机制
默认情况下,TrackNavigationObserver 会自动将路径中的动态数字 ID 替换为 :id,将 UUID 替换为 :uuid,减少动态路由带来的属性基数。如需自定义规整逻辑,可传入 routeTransformer:
路径规整不等同于个人信息脱敏;仍需检查路由名称,避免包含敏感数据。
TrackNavigationObserver(
routeTransformer: (rawName) {
// 自定义规整逻辑
return rawName.replaceAll(RegExp(r'/user/\w+'), '/user/:id');
},
);2. 声明式点击捕获组件 (TrackWidget)
针对按钮、卡片或任意手势交互元素,使用 TrackWidget 包裹记录点击事件,业务操作放在 onTap 回调中:
TrackWidget(
eventName: 'banner_click',
properties: const {
'banner_id': 'summer_sale_2026',
'position': 1,
},
onTap: () {
// 业务跳转逻辑
},
child: Image.asset('assets/banner.png'),
)六、 Android Release 与 R8
正常通过 Flutter 插件和 Android AAR 引入依赖时,不需要把 SDK 内部类型规则复制到宿主 proguard-rules.pro。Android 核心 AAR 自带消费端 R8 规则,Gradle 会随依赖合并。若只在 Release 构建中出现类缺失或序列化问题,先用最小 Release Host 复现,再依据实际 mapping.txt 与 R8 诊断添加最窄规则;不要直接保留整个 SDK 包或 Flutter 插件包。
七、常见问题
Android 缺少 FlutterPlugin
请确保宿主 App 采用 Android Embedding V2。TrackBusinessFlutterPlugin 不支持 V1 Embedding(PluginRegistry.Registrar)。
调用后没有立即发送
- 检查是否开启了
deferredCapture: true;该模式在明确授权前不会创建事件,不是暂存等待上传; - 原生 SDK 默认采用批量聚合策略(
flushAt: 20或flushInterval: 30s),可手动调用TrackBusinessFlutter.instance.flush()尝试发送本地队列。
兼容性与授权
Android 宿主提供 AGP/Kotlin 插件:Java 17、Kotlin 2.0.21 或更新兼容版本、compileSdk 35+、minSdk 23+。请核对 Flutter、原生依赖与宿主工具链的兼容性。
iOS 使用包内配套的原生模块。事前授权使用 ConsentLevel.pending 或 deferredCapture: true 初始化;用户同意后调用 setConsent(ConsentLevel.granted)。pending 只用于初始化,不能通过运行时 setConsent 设置。
属性校验失败会返回 TB_INVALID_PROPERTIES,本次调用不会记录事件或更新属性。请精简过长的字段值。
公共属性
公共属性委托给原生运行时,只影响之后创建的事件并保存在内存中;应用重新初始化后需重新设置。账号边界变化时,移除不应继续共享的自定义属性。
final sdk = TrackBusinessFlutter.instance;
await sdk.setGlobalProperties({'appEdition': 'team'});
await sdk.removeGlobalProperties(['appEdition']);位置快照
final sdk = TrackBusinessFlutter.instance;
// 宿主已取得系统定位权限和业务定位授权后显式启用。
await sdk.grantLocationConsent();
await sdk.trackWithLocation('store_visit', location: LocationSnapshot(
latitude: 31.2,
longitude: 121.5,
coordinateSystem: 'WGS84',
observedAt: DateTime.now().millisecondsSinceEpoch,
));
await sdk.revokeLocationConsent();SDK 不申请系统定位权限或主动获取位置;宿主提供已授权的坐标。授权、撤销、有效期和已发送数据的处理见事件级位置快照。
出现 TB_NATIVE_UNAVAILABLE 时,请核对 Flutter 包与原生依赖是否配套安装。
用户画像
先绑定测试用户,再按需写入画像属性:
final sdk = TrackBusinessFlutter.instance;
await sdk.identify('customer-42');
await sdk.setUserProperties({'tier': 'pro', 'score': 2});
await sdk.setUserPropertyOnce({'source': 'app'});
await sdk.profileIncrement({'score': 1});
await sdk.profileAppend({'tags': ['campaign-a']});
await sdk.unsetUserProperties(['source']);
final localProfile = await sdk.getUserProperties();
await sdk.clearUserProperties();getUserProperties() 返回原生本地缓存;clearUserProperties() 只提交本地已知属性的移除,不删除服务端全部画像。profileIncrement 接受有限数字,profileAppend 接受同类型的字符串或数字数组。
接入时确认投递
确认所用 Flutter 包和配套原生包提供 verifyDelivery 后,可在测试中观察当前待发范围:
final sdk = TrackBusinessFlutter.instance;
await sdk.track('integration_check');
final report = await sdk.verifyDelivery(timeoutMs: 3000);根据 report.status 和 report.reason 判断结果。flush() 完成不等于 Collector ACK;结果含义见可靠投递。