杰理 SDK 文档中心
首页
首页
  • 概述与快速开始

    • 项目简介与功能总览
    • 运行环境与快速开始
    • 工程结构与文档布局
  • 架构与核心机制

    • 插件架构与原生平台桥接
    • 基类管理器与常量体系
    • 事件流与接收通知机制
  • 蓝牙连接与设备管理

    • 蓝牙连接与状态管理
    • 设备信息、配置与按键设置
    • 双设备连接与多链路管理
    • 数据传输与自定义命令
  • 音乐与媒体控制

    • 设备音乐与手机音乐播放控制
    • 音量与音频输出管理
  • 音效与音频模式

    • 均衡器与音效调节
    • 音频模式与降噪(ANC)设置
    • Auracast 音频广播
  • 设备功能控制

    • 闹钟管理
    • FM 收音机控制
    • 灯光控制
    • 充电仓与彩屏仓管理
  • 示例应用:杰理之家 Demo

    • 应用框架与交互组件
    • 设置、多语言与调试
  • 接口参考与文档中心

    • 发送接口参考
    • 接收接口与事件参考
    • 官方文档与集成指南

基类管理器与常量体系

本文档介绍 JieLi_Home 项目中支撑整个 App 架构的两大基础体系:lib/constant/ 下的常量体系(AppConstants、BleMethodConstants、BleEventConstants)与 lib/manager/ 下的管理器体系(一组 Ble*Manager 静态方法类)。它们是页面层与底层 JL BLE SDK 之间的桥梁,定义了全局配置值、连接状态机语义、BLE 指令方法名与事件名,以及所有 BLE 业务操作的统一调用入口。

Purpose and Scope

本页覆盖以下内容:

  • 常量体系的设计意图与分类:应用级常量(AppConstants)、BLE 方法常量(BleMethodConstants)、BLE 事件常量(BleEventConstants);
  • 管理器体系的统一模式:为何采用"纯静态方法类"而非继承式基类(源码中未发现 BaseManager 显式基类,统一模式即事实上的"基类约定");
  • 代表性管理器(BleConnectionManager、BleConfigManager、BleCustomCmdManager、BleEqManager 等)的职责划分;
  • 页面 → 管理器 → BLE SDK → 设备的端到端控制流;
  • 常量表的完整清单、管理器的 API 形态、失败模式与扩展点。

以下主题属于相邻页面,不在本页展开:BLE 协议栈底层实现、具体设备功能的协议细节(如 EQ、闹钟、AuraCast 各自的指令编码)、UI 页面布局与状态管理(Provider/Bloc)、OTA 升级流程。若目录中存在对应页面,请优先参阅那些页面。

Overview

为什么需要"常量 + 管理器"双体系

JL 智能硬件 App 需要与多种蓝牙耳机/音箱设备通信。底层 SDK 暴露的是字节级 BLE 指令通道,而业务层需要的是语义化的操作("获取 EQ 数据"、"设置闹钟"、"进入充电盒消息页")。为了在这两层之间建立稳定契约,项目引入了两个基础设施:

  1. 常量体系把魔法字符串/魔法数字集中管理,避免散落各处导致不一致。例如连接状态用 0/1/2/3 表示,通信方式用 'BLE'/'SPP' 表示——这些语义都收敛在 AppConstants 中。
  2. 管理器体系把每一类设备能力封装为独立的管理器类,页面只依赖管理器的方法签名,不接触 SDK 细节。所有管理器统一采用静态方法类模式(见下文分析),这构成了项目事实上的"基类约定"。

关键概念

概念说明
AppConstants应用级全局常量(URL、连接状态、UI 尺寸、推送开关键名、语言键名等)
BleMethodConstantsBLE 指令方法名常量(管理器构造指令时引用)
BleEventConstantsBLE 事件名常量(SDK 回调 → 页面分发时引用)
Ble*Manager静态方法类,按设备功能域划分(连接、信息、EQ、闹钟、音乐、设置等)
静态方法类模式所有管理器不持有实例状态,通过 static Future<...> 方法提供能力

Architecture

flowchart TD
    subgraph sg_UI["页面与业务层 (lib/pages, lib/widgets)"]
        Page["页面 / Dialog / Widget"]
    end

    subgraph sg_Manager["管理器体系 (lib/manager)"]
        Conn["BleConnectionManager"]
        Info["BleDeviceInfoManager"]
        Config["BleConfigManager"]
        Music["BleDeviceMusicManager"]
        EQ["BleEqManager"]
        Others["BleAlarmManager / BleCustomCmdManager / BleDeviceSettingManager / ..."]
    end

    subgraph sg_Constant["常量体系 (lib/constant)"]
        App["AppConstants"]
        Method["BleMethodConstants"]
        Event["BleEventConstants"]
    end

    subgraph sg_SDK["JL BLE SDK 层"]
        Sdk["BLE 协议栈 / 设备连接通道"]
        Device["硬件设备"]
    end

    Page --> Conn
    Page --> Info
    Page --> Config
    Page --> Music
    Page --> EQ
    Page --> Others

    Conn --> App
    Info --> App
    Config --> App
    Music --> Method
    EQ --> Method
    Others --> Method

    Method --> Sdk
    Sdk --> Event
    Event --> Page
    Sdk --> Device

架构说明:

  • 页面层只面向管理器,不直接拼装 BLE 指令。这保证了业务代码的可读性与可替换性——即使底层 SDK 更换,页面的调用代码不变。
  • 管理器层是唯一允许触碰 BleMethodConstants 的层:每个管理器的静态方法内部把业务参数编码为指令数据,再交给 BLE SDK 发送。
  • 常量体系是"读多写少"的共享契约:AppConstants 供全 App 使用(含页面 UI 与存储键名),BleMethodConstants 供管理器使用,BleEventConstants 则承载 SDK 上行事件名,页面据此分发回调。
  • 分层方向是单向的:页面 → 管理器 → SDK → 设备;事件反向:设备 → SDK → 页面。常量层被各层读取,但不反向依赖任何业务代码。

该设计把"易变的设备协议细节"隔离在管理器内部,把"稳定的全局语义"收敛到常量类,是典型的分层 + 单一职责组合,适合多设备型号共存的场景。

常量体系详解(lib/constant)

lib/constant/ 目录下有三个文件,分别承载不同粒度的常量:constants.dart(应用级)、ble_method_constants.dart(BLE 指令方法名)、ble_event_constants.dart(BLE 事件名)。它们的共同特征是:全部为 static const,编译期确定、零运行时开销,且集中在单一文件中便于全局审计。

AppConstants:应用级常量

AppConstants 定义在 constants.dart,把散落在各处的魔法值收敛为带文档注释的命名常量。按其语义可划分为以下几组:

1) 法务与协议 URL

/// User agreement URL for the application
static const String userAgreementUrl = 'https://cam.jieliapp.com/app/app.user.service.protocol.html';

/// Privacy policy URL for the application
static const String privacyPolicyUrl = 'https://cam.jieliapp.com/app/JL_OTA_app_privacy_policy.html';

/// Icp number
static const String icpNumber = '粤ICP备18069041号-15A';

/// Icp url
static const String icpUrl = 'https://beian.miit.gov.cn/';

Source: constants.dart

2) 通信方式标识:'BLE' 与 'SPP' 两个字符串常量,用于标识设备当前采用的通信通道,避免在多处硬编码字符串导致拼写不一致:

/// Constant representing BLE communication method
static const String communicationWayBle = 'BLE';

/// Constant representing SPP communication method
static const String communicationWaySpp = 'SPP';

Source: constants.dart

3) 连接状态机语义:用整数表达 BLE 连接的五个状态。状态值从 -1 到 3,语义清晰且与 SDK 层约定一致:

/// Connection state: Default value
static const int connectDefaultState = -1;

/// Connection state: Disconnected
static const int connectionDisconnect = 0;

/// Connection state: Successfully connected
static const int connectionOK = 1;

/// Connection state: Connection failed
static const int connectionFailed = 2;

/// Connection state: Currently connecting
static const int connectionConnecting = 3;

Source: constants.dart

把状态集中定义的意义在于:连接状态会在"设备列表页、连接管理器、SDK 回调、全局状态管理"多处流转,若不统一,0 究竟表示"断开"还是"默认值"极易产生歧义。这里用 connectDefaultState = -1 明确区分"尚未初始化"与"已断开"两种语义,是避免状态机误判的关键设计。

4) UI 尺寸与平台阈值:dialogButtonHeight = 45.0、returnIconSizeValue = 28.0 统一对话框按钮高度与返回图标尺寸;tiramisu = 33 标记 Android 13 的 API level,供权限/行为分支判断使用。

5) 存储键名与推送开关:agreePolicy、filterContent、otaPath、storageStatus、updateFileName(默认 'upgrade.ufw')等键名用于本地存储与 OTA 文件操作;messagePushEnabled、messagePushSmsState、messagePushWechatState 等一组常量对应消息推送各渠道的开关状态键,配套的 keyAppSms/keyAppWechat/keyAppQQ/keyAppDingTalk/keyAppLark 标识各 App 的存储键。这类键名若在读写处各自硬编码,一旦改名会静默丢失用户设置,集中定义即为此服务。

6) 语言键名:keyLanguageChinese = 'zh'、keyLanguageEnglish = 'en'、keyLanguageJapanese = 'ja' 等,与 App 多语言支持联动。

BleMethodConstants:BLE 指令方法名

ble_method_constants.dart 与 ble_event_constants.dart 是 BLE 协议侧的专属常量文件,与管理器体系一一对应:管理器在构造指令时引用方法名常量,SDK 上行事件通过事件名常量回传。详细枚举项未在本页读取预算内逐条展开,直接查阅源文件即可获得完整清单;其存在本身印证了"管理器引用方法名、页面引用事件名"的分层契约。

常量体系关系图

classDiagram
    class AppConstants {
        +static const String userAgreementUrl
        +static const String communicationWayBle
        +static const String communicationWaySpp
        +static const int connectDefaultState
        +static const int connectionDisconnect
        +static const int connectionOK
        +static const int connectionFailed
        +static const int connectionConnecting
        +static const int tiramisu
        +static const double dialogButtonHeight
        +static const double returnIconSizeValue
        +static const String messagePushEnabled
        +static const String keyLanguageChinese
    }
    class BleMethodConstants {
        +static const ... BLE 指令方法名
    }
    class BleEventConstants {
        +static const ... BLE 上行事件名
    }

    BleMethodConstants --> AppConstants : 同目录、供管理器引用
    BleEventConstants --> AppConstants : 同目录、供页面分发引用

设计意图:一个常量类不足以承载所有语义。AppConstants 面向全 App(含 UI 与存储),BleMethodConstants 面向管理器(指令编码),BleEventConstants 面向事件分发(SDK 回调)。三者按"使用者"切分,避免单个巨型常量类被无关页面误引,也让 BLE 协议相关常量可以整体替换(例如适配新 SDK 时只需改常量映射层)。

管理器体系详解(lib/manager)

lib/manager/ 目录按设备功能域拆分为十余个管理器:BleConnectionManager(连接)、BleConfigManager(配置/总线占用)、BleDeviceInfoManager(设备信息)、BleDeviceMusicManager(设备音乐)、BleDeviceSettingManager(按键设置)、BleEqManager(EQ)、BleAlarmManager(闹钟)、BleAuraCastManager(AuraCast 投播)、BleChargingCaseManager(充电盒)、BleCustomCmdManager(自定义指令)、BleDoubleDeviceManager(双设备)等。

关键发现:事实上的"基类"是统一模式,而非继承

在 lib/ 与 example/lib/ 中检索 class BaseManager、abstract class Base 等显式基类声明,未发现任何管理器继承自基类(implementation details not found in source)。取而代之的是完全一致的代码约定,这正是本项目"基类管理器"的真实形态:

  1. 每个管理器是一个纯静态方法类:无实例字段、无构造函数、不持有状态;
  2. 方法签名统一为 static Future<...> xxx() 形态,异步返回操作结果;
  3. 类名统一为 Ble<功能域>Manager,文件名统一为 ble_<功能域>_manager.dart;
  4. 类注释一行概括职责,方法注释描述具体能力。

这种"约定优于继承"的选择在 Dart/Flutter 场景下是合理的:管理器不需要共享实例状态,也没有模板方法需要子类覆写;静态方法类避免了单例的初始化顺序问题,调用即所得,天然线程(isolate)安全,也便于单元测试时直接打桩。

代表性管理器分析

BleCustomCmdManager — 自定义指令通道,暴露最底层的能力:把原始字节数据直接发送给设备:

class BleCustomCmdManager {
  static Future<void> sendCustomCommand(Uint8List data) async {

Source: ble_custom_cmd_manager.dart

它是其他管理器的"兜底"入口:当某个新功能尚未封装成专用管理器时,业务方可以先用 sendCustomCommand 透传指令验证协议,再沉淀为正式管理器方法。

BleChargingCaseManager — 页面级能力封装,返回 Future<bool> 表达操作成败,体现"管理器不直接操作 UI、但可为页面流程提供引导"的边界:

class BleChargingCaseManager {
  static Future<bool> enterMessagePage() async {

Source: ble_charging_case_manager.dart

BleAuraCastManager — 纯异步任务,用于获取投播记录列表:

class BleAuraCastManager {
  static Future<void> auraCastGetRecordList() async {

Source: ble_aura_cast_manager.dart

BleConnectionManager(ble_connection_manager.dart,职责注释 "Device Connection Manager")负责开始扫描、建立/断开连接,是设备列表页的核心依赖;BleConfigManager(ble_config_manager.dart)提供 "Check if BLE communication is currently being used" 的总线占用检查,供页面在发起新指令前判断通道是否繁忙;BleDeviceInfoManager(ble_device_info_manager.dart)暴露 "Get current device type" 等查询能力;BleDeviceSettingManager(ble_device_setting_manager.dart)对应 "Update key function settings" 的按键功能设置。

管理器分工总览

管理器职责(依据类注释)入口文件
BleConnectionManagerDevice Connection Manager(扫描/连接)ble_connection_manager.dart
BleConfigManagerBluetooth Configuration Manager(总线占用检查)ble_config_manager.dart
BleDeviceInfoManagerDevice Information Manager(设备类型等)ble_device_info_manager.dart
BleDeviceMusicManagerDevice Music Manager(音乐信息)ble_device_music_manager.dart
BleDeviceSettingManagerDevice Settings Manager(按键功能设置)ble_device_setting_manager.dart
BleEqManagerEQ Manager(EQ 数据读写)ble_eq_manager.dart
BleAlarmManagerAlarm Manager(闹钟列表/设置)ble_alarm_manager.dart
BleAuraCastManagerAuraCast Manager(投播记录)ble_aura_cast_manager.dart
BleChargingCaseManagerBle charging case manager(充电盒消息页)ble_charging_case_manager.dart
BleCustomCmdManager自定义指令透传ble_custom_cmd_manager.dart
BleDoubleDeviceManagerBle double device manager(双设备)ble_double_device_manager.dart

Core Flow:端到端控制流

一次典型操作的完整链路如下:页面调用管理器静态方法 → 管理器编码指令(引用 BleMethodConstants)→ SDK 写入 BLE 特征值 → 设备应答/主动上报 → SDK 触发事件 → 页面依据 BleEventConstants 分发并刷新 UI。

sequenceDiagram
    participant UI as 页面
    participant M as Ble*Manager
    participant SDK as JL BLE SDK
    participant DEV as 设备

    UI->>M: 调用静态方法<br/>(如 sendCustomCommand(data))
    activate M
    M->>SDK: 编码并发送指令<br/>(引用 BleMethodConstants)
    activate SDK
    SDK->>DEV: 写入 BLE 特征值
    DEV-->>SDK: 设备应答 / 主动上报
    SDK-->>M: 回调结果
    deactivate SDK
    M-->>UI: Future 结果 (bool/void/数据)
    deactivate M
    UI->>UI: 依据 BleEventConstants 分发事件并刷新

流程要点:

  • 异步契约:管理器一律返回 Future,页面用 await 串行等待结果;设备不在线时由 SDK 层超时并向下传递错误,管理器不吞异常(失败模式见下文)。
  • 指令编码点:指令组装只发生在管理器内部,页面永远传"业务参数"而非"字节流",唯一的例外是 BleCustomCmdManager.sendCustomCommand 显式暴露字节通道。
  • 上行事件点:设备主动上报(如闹钟提醒、连接断开)不经过管理器的返回值,而是走 SDK 事件 → BleEventConstants 事件名 → 页面监听的旁路,保证"请求-应答"与"主动推送"两条路径互不阻塞。

用法示例

示例一:从页面调用管理器(连接/信息查询)

页面不感知 SDK,只面向管理器静态方法:

// 连接管理器:开始扫描
class BleConnectionManager {
  /// Start scanning
  static Future<void> startScan() async { ... }
}

Source: ble_connection_manager.dart

// 设备信息管理器:获取当前设备类型
class BleDeviceInfoManager {
  /// Get current device type
  static Future<void> getCurrentDeviceType() async { ... }
}

Source: ble_device_info_manager.dart

示例二:自定义指令透传

当新协议尚未封装时,业务层可直接发送原始字节:

class BleCustomCmdManager {
  static Future<void> sendCustomCommand(Uint8List data) async {

Source: ble_custom_cmd_manager.dart

示例三:依赖连接状态常量做分支

页面在显示连接状态时引用 AppConstants 而非魔法数字:

switch (state) {
  case AppConstants.connectionOK:        // 1
    // 已连接:展示设备信息
    break;
  case AppConstants.connectionConnecting: // 3
    // 连接中:展示 loading
    break;
  case AppConstants.connectionFailed:     // 2
    // 连接失败:引导重试
    break;
}

Source: constants.dart

配置选项(常量清单节选)

以下为 AppConstants 中已核实的关键常量;完整清单见 constants.dart。

常量类型默认值说明
userAgreementUrlStringhttps://cam.jieliapp.com/app/app.user.service.protocol.html用户协议 URL
privacyPolicyUrlStringhttps://cam.jieliapp.com/app/JL_OTA_app_privacy_policy.html隐私政策 URL
communicationWayBleString'BLE'BLE 通信方式标识
communicationWaySppString'SPP'SPP 通信方式标识
icpNumberString'粤ICP备18069041号-15A'ICP 备案号
icpUrlString'https://beian.miit.gov.cn/'备案查询 URL
connectDefaultStateint-1连接状态默认值(未初始化)
connectionDisconnectint0已断开
connectionOKint1已连接
connectionFailedint2连接失败
connectionConnectingint3连接中
tiramisuint33Android 13 API level
dialogButtonHeightdouble45.0对话框底部按钮高度
returnIconSizeValuedouble28.0返回图标尺寸
updateFileNameString'upgrade.ufw'OTA 升级文件名
keyLanguageChineseString'zh'中文语言键
messagePushEnabledString'message_push_enabled'消息推送总开关存储键

API Reference

本体系的公开 API 形态统一为管理器静态方法,签名约定如下:

static Future<T> <operation>([参数])

参数: 各方法按需接收业务参数(如 BleCustomCmdManager.sendCustomCommand(Uint8List data) 接收原始指令字节)。

返回:

  • Future<void>:纯触发型操作(发送指令、获取列表),结果经事件旁路回传;
  • Future<bool>:成败型操作(进入消息页等),true 表示成功;
  • 其他数据型操作返回对应数据对象。

Throws: 未发现管理器层统一捕获异常的代码;设备离线、指令超时等错误由底层 SDK 以异常/Future 错误形式向上传播,由页面按需处理。

BleEventConstants / BleMethodConstants

常量类全部为 static const 字段,无方法;通过 BleMethodConstants.xxx / BleEventConstants.xxx 直接读取。

失败模式、边界与并发

  • 设备离线/超时:管理器方法依赖设备在线的 BLE 链路,指令超时表现为 Future 异常。由于管理器不做重试,页面需要捕获错误并提供重试入口;连接状态常量中的 connectionFailed = 2 即用于此分支。
  • BLE 总线占用:BleConfigManager 提供 "Check if BLE communication is currently being used" 检查,说明项目采用"单通道串行指令"模型——并发下发多条指令可能互相覆盖,业务方应在发送前检查总线占用、发送后等待应答。
  • 静态方法的并发安全:管理器无实例状态,天然免疫共享可变状态问题;但这也意味着"正在进行的操作"无法从管理器内部查询,需要页面自行维护(或依赖 SDK 回调事件)。
  • 常量误用边界:connectDefaultState = -1 与 connectionDisconnect = 0 是两种语义,若误用默认值判断"是否已连接"会导致首帧状态误判;统一走常量可最大限度降低此类风险。

性能与运维

  • 常量为 static const,编译期内联,零运行时开销,可放心在热路径(列表渲染、状态刷新)中引用。
  • 管理器为静态方法,无对象分配与 DI 开销;每次调用仅产生一次 Future 与指令数据分配。
  • 运维关注点集中在 BLE 通道:指令串行化、超时阈值、事件去重均由 SDK 层与管理器协作完成;如需诊断,可从 BleCustomCmdManager 透传通道抓取原始指令对比协议文档。

扩展点

  1. 新增设备能力:在 lib/manager/ 下新建 ble_xxx_manager.dart,遵循 Ble<功能域>Manager + 静态 Future 方法约定即可,无需改动现有管理器;如指令协议复用,可将方法名常量补充进 BleMethodConstants,事件名补充进 BleEventConstants。
  2. 协议适配:更换/升级 SDK 时,只需调整管理器内部编码与 BleMethodConstants/BleEventConstants 映射,页面层零改动。
  3. 临时调试:利用 BleCustomCmdManager.sendCustomCommand 透传新协议字节,验证通过后再沉淀为正式方法——这是项目预留的"快速验证"扩展口。

测试

未在本页读取预算内发现针对管理器/常量的独立测试文件。从设计形态看,静态方法类与 static const 常量天然便于测试:常量可被直接断言,管理器方法可在无 UI 环境下调用(配合 SDK mock)。若仓库中存在测试目录,建议按"常量语义不回归、管理器指令编码正确"两个维度补充用例。

Related Links

  • BLE 事件常量 ble_event_constants.dart
  • BLE 方法常量 ble_method_constants.dart
  • 连接管理器 ble_connection_manager.dart
  • 配置管理器 ble_config_manager.dart
  • 自定义指令管理器 ble_custom_cmd_manager.dart
  • 设备信息管理器 ble_device_info_manager.dart
  • EQ 管理器 ble_eq_manager.dart
  • 相邻主题:连接状态机与扫描流程(BleConnectionManager 详页)、EQ/闹钟/音乐等具体功能协议页、OTA 升级流程页
Prev
插件架构与原生平台桥接
Next
事件流与接收通知机制