Skip to content
AI 文档索引 ↗

Flutter SDK ​

AI 辅助接入 Flutter

从 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 中添加依赖:

yaml
dependencies:
  flutter:
    sdk: flutter
  track_business_flutter:
    path: ./libs/track-business-flutter-<下载包版本> # 解压 Flutter 离线集成包后的目录

运行获取依赖包:

bash
flutter pub get

2. iOS 依赖安装 ​

bash
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 目录(按实际目录调整,保留项目已有仓库):

groovy
// 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 配置
groovy
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 时:

kotlin
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:

dart
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,初始化失败时继续业务流程。日志记录受控错误码即可。

初始化配置参数说明 ​

参数名类型必填默认值说明
endpointString是-网关或上报接收端 URL(支持 HTTP 与 HTTPS)
projectKeyString是-环境唯一公开凭据
deferredCapturebool否false为 true 时以 PENDING 初始化,授权前不采集或入队
initialConsentConsentLevel否granted初始隐私合规状态(pending / granted / denied)

四、 核心 API 使用 ​

1. 自定义事件埋点 (track) ​

dart
await TrackBusinessFlutter.instance.track('sdk_integration_check', properties: {
  'source': 'flutter-docs',
});

使用测试项目运行该合成事件。检查原生端队列与诊断,再通过目标测试 Collector 核对事件与有效整批 ACK;调用完成不等于接收成功。完整步骤见数据校验。

排查时可读取当前原生健康状态和队列计数:

dart
final sdk = TrackBusinessFlutter.instance;
final health = await sdk.getHealthSnapshot();
final queue = await sdk.getQueueStats();
print('SDK 状态: ${health.status}, 待发送事件: ${queue.pendingEvents}');

快照反映调用时的本地状态,队列为空也不能单独证明 Collector 已接收;需要确认投递时使用本页的 verifyDelivery 和接收端检查。避免在日志中输出事件属性或用户身份。

2. 页面与屏幕曝光 (screen) ​

dart
await TrackBusinessFlutter.instance.screen('ProductDetailScreen', properties: {
  'category': 'Electronics',
  'sku': 'SKU_100234',
});

3. 用户登录与绑定 (identify) ​

当用户在 App 完成登录或身份认证时,调用 identify 绑定业务主体:

dart
await TrackBusinessFlutter.instance.identify('user_vip_9988');

4. 退出身份与重置 ​

安全退出账号时调用 signOut();需要退出登录但保留匿名旅程时调用 clearUser()。reset() 用于显式重置身份,不应替代所有退出场景。

dart
await TrackBusinessFlutter.instance.signOut();

5. 请求刷新队列 (flush) ​

dart
await TrackBusinessFlutter.instance.flush();

五、 按需启用页面与点击事件 ​

1. 路由生命周期监听 (TrackNavigationObserver) ​

只有将 TrackNavigationObserver 注册到 MaterialApp 的 navigatorObservers 后,SDK 才会针对该 Navigator 的命名路由跳转(didPush、didPop、didReplace)调用原生 screen()。它不会扫描其它页面或控件:

dart
MaterialApp(
  title: 'My App',
  navigatorObservers: [
    TrackNavigationObserver(),
  ],
  routes: {
    '/': (context) => const HomeScreen(),
    // 示例中的实际命名路由;Observer 会把数字段归一化为 :id。
    '/order/123': (context) => const OrderDetailScreen(),
  },
);

高基数路由规整保护机制 ​

默认情况下,TrackNavigationObserver 会自动将路径中的动态数字 ID 替换为 :id,将 UUID 替换为 :uuid,减少动态路由带来的属性基数。如需自定义规整逻辑,可传入 routeTransformer:

路径规整不等同于个人信息脱敏;仍需检查路由名称,避免包含敏感数据。

dart
TrackNavigationObserver(
  routeTransformer: (rawName) {
    // 自定义规整逻辑
    return rawName.replaceAll(RegExp(r'/user/\w+'), '/user/:id');
  },
);

2. 声明式点击捕获组件 (TrackWidget) ​

针对按钮、卡片或任意手势交互元素,使用 TrackWidget 包裹记录点击事件,业务操作放在 onTap 回调中:

dart
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)。

调用后没有立即发送 ​

  1. 检查是否开启了 deferredCapture: true;该模式在明确授权前不会创建事件,不是暂存等待上传;
  2. 原生 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,本次调用不会记录事件或更新属性。请精简过长的字段值。

公共属性 ​

公共属性委托给原生运行时,只影响之后创建的事件并保存在内存中;应用重新初始化后需重新设置。账号边界变化时,移除不应继续共享的自定义属性。

dart
final sdk = TrackBusinessFlutter.instance;
await sdk.setGlobalProperties({'appEdition': 'team'});
await sdk.removeGlobalProperties(['appEdition']);

位置快照 ​

dart
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 包与原生依赖是否配套安装。

用户画像 ​

先绑定测试用户,再按需写入画像属性:

dart
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 后,可在测试中观察当前待发范围:

dart
final sdk = TrackBusinessFlutter.instance;
await sdk.track('integration_check');
final report = await sdk.verifyDelivery(timeoutMs: 3000);

根据 report.status 和 report.reason 判断结果。flush() 完成不等于 Collector ACK;结果含义见可靠投递。