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

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

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

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

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

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

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

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

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

蓝牙连接与状态管理

本页介绍 Flutter-JL_Home 中蓝牙设备连接与状态管理的完整链路:Dart 侧的连接指令入口 BleConnectionManager、连接状态模型 DeviceConnection、事件流处理器 BleDeviceConnectionProcessor,以及应用层全局状态管理 ConnectionStateManager,涵盖从扫描、连接、断开到状态回调的端到端机制。

Purpose and Scope

本页覆盖「蓝牙连接与状态管理」这一能力边界内的全部实现:

  • 连接指令:扫描启动/停止、按索引连接/断开设备的指令下发(BleConnectionManager)。
  • 连接状态模型:原生侧回传的连接状态数据的 Dart 表示(DeviceConnection)。
  • 事件流处理:将原生事件转换为 Dart Stream 的扫描状态、设备列表、连接状态流(BleDeviceConnectionProcessor)。
  • 应用层状态:example 工程中基于 ChangeNotifier 的全局连接状态单例(ConnectionStateManager)及其配套的全局监听工具(global_connection_listener.dart)。

以下主题属于兄弟页面,不在本页展开:音频播放与解码、文件管理、OTA 升级、扫描发现之外的设备服务(如通话、音乐控制)等。若相关目录页存在,请参见对应页面。

概述

Flutter-JL_Home 采用「Dart 插件层 + Android 原生 SDK」的双端架构。蓝牙连接的典型旅程是:用户在 UI 中触发扫描 → 原生 BLE 协议栈回报扫描结果 → 用户选择设备并下发连接指令 → 原生层建立 GATT 连接 → 连接状态以事件形式回传 Dart 层 → 应用刷新全局状态并驱动界面。

这套能力被刻意设计为无状态命令式入口 + 事件流式回调的组合:

  • 指令方向(Dart → Native):所有动作都通过 BleBaseManager.invokeMethod() 走 Flutter MethodChannel,方法名集中在 BleMethodConstants。
  • 事件方向(Native → Dart):原生层把扫描结果、连接状态等通过事件通道推回,BleBaseEventProcessor 负责按事件类型过滤,BleDeviceConnectionProcessor 再将其映射为类型安全的 Stream。

应用层拿到这些 Stream 后,既可以直接订阅驱动 UI,也可以通过 ConnectionStateManager 这类单例把「最新状态」集中缓存,避免多个页面各自维护状态副本。这种「命令 + 事件流」的分工,使得连接逻辑与 UI 解耦,且天然支持多页面共享同一连接会话。

架构

flowchart TD
    subgraph sg_UI["Flutter 应用层 (example)"]
        UI["UI Widgets"]
        CSM["ConnectionStateManager<br/>(ChangeNotifier 单例)"]
        GCL["GlobalConnectionListener"]
    end

    subgraph sg_Dart["Dart 插件层 (lib)"]
        BCM["BleConnectionManager<br/>(静态指令)"]
        BCP["BleDeviceConnectionProcessor<br/>(静态事件流)"]
        BBM["BleBaseManager<br/>(MethodChannel invokeMethod)"]
        BEP["BleBaseEventProcessor<br/>(事件过滤/解析)"]
    end

    subgraph sg_Native["Android 原生层 (Kotlin/Java)"]
        DCM["DeviceConnectionManager.kt"]
        DC["DeviceConnection.java"]
        DCS["DoubleConnectionSp.java<br/>(双连接配置持久化)"]
        BLE["Android BLE 协议栈"]
    end

    UI -->|"订阅/刷新"| CSM
    CSM -->|"updateConnectState"| GCL
    GCL -->|"订阅事件流"| BCP
    UI -->|"startScan/connectDevice"| BCM
    BCM -->|"invokeMethod"| BBM
    BBM -->|"MethodChannel"| DCM
    DCM --> BLE
    DCM --> DC
    DCM --> DCS
    BLE -->|"原生事件回调"| BEP
    BEP -->|"filterByType + 解析"| BCP
    BCP -->|"类型安全 Stream"| GCL

各组件职责

组件所在文件职责
BleConnectionManagerlib/manager/ble_connection_manager.dart连接能力对外的指令入口,全部为静态方法,仅负责把动作翻译成 MethodChannel 调用
BleBaseManagerlib/ble_base_manager.dart底层通道封装,提供 invokeMethod,是 Dart 与原生通信的唯一通道(本页通过引用确认其存在,具体实现见其源码)
BleDeviceConnectionProcessorlib/processor/ble_device_connection_processor.dart把 BleBaseEventProcessor 的原始事件转换为 Stream<String> / Stream<List<ScanDevice>> / Stream<DeviceConnection>
BleBaseEventProcessorlib/processor/ble_base_event_processor.dart事件总线过滤与取值工具,提供 filterByType 与 getValueFromEvent
DeviceConnectionlib/model/device_connection.dart连接状态模型,核心字段 state(int),提供 fromMap/toMap 双向转换
ConnectionStateManagerexample/lib/utils/connection_state_manager.dart应用层全局连接状态缓存,ChangeNotifier 单例,供 UI 监听刷新
DeviceConnectionManager.kt / DeviceConnection.java / DoubleConnectionSp.javaandroid/.../sdk/data/manager/ 等原生侧连接管理、状态模型与双连接配置持久化(本页仅确认其存在与命名,具体实现属于原生 SDK 范围)

设计意图

  • 静态方法而非实例:BleConnectionManager 与 BleDeviceConnectionProcessor 全部使用静态成员,说明 SDK 采用全局单例式通道设计——蓝牙连接本质上是设备级(而非页面级)资源,不需要为每个调用者创建独立实例。
  • Stream 而非回调:事件流天然支持多订阅者,扫描列表、连接状态可以被任意多个页面同时监听,且可以组合(map、where、listen 等操作符),比一次性回调更灵活。
  • 状态集中缓存:ConnectionStateManager 在收到新状态时先做相等性判断再 notifyListeners(),避免无意义的 UI 重建;同时提供静态 currentState,让非 Widget 代码也能读取最新状态。

主内容:连接链路的实现剖析

1. 指令入口:BleConnectionManager

该管理器是 Dart 侧向原生发起连接动作的唯一入口,全部为静态 Future<void> 方法,内部统一委托给 BleBaseManager.invokeMethod:

/// Connect to device
static Future<void> connectDevice(int index) async {
  await BleBaseManager.invokeMethod(
    BleMethodConstants.methodConnectDevice,
    arguments: {BleMethodConstants.argIndex: index},
  );
}

/// Disconnect from device
static Future<void> disconnectBtDevice(int index) async {
  await BleBaseManager.invokeMethod(
    BleMethodConstants.methodDisconnectBtDevice,
    arguments: {BleMethodConstants.argIndex: index},
  );
}

Source: ble_connection_manager.dart

要点解读:

  • 按索引寻址设备:connectDevice(int index) / disconnectBtDevice(int index) 均以扫描列表中的索引定位设备,而不是设备地址或 UUID。这意味着调用方必须先完成扫描并持有扫描列表(scanDeviceListStream),索引与设备的对应关系由调用方负责维护——这是 SDK 为简化跨端参数传递而做的取舍。
  • 参数键集中管理:argIndex 等参数键与方法名一样集中在 BleMethodConstants,避免字符串散落各处造成拼写不一致。
  • 扫描控制:startScan() / stopScan() 无参数,扫描结果不在此处返回,而是通过 scanStateStream / scanDeviceListStream 事件流异步送达——指令与数据分离。

2. 连接状态模型:DeviceConnection

原生侧回传的每一个连接状态事件,都会被映射为 DeviceConnection 对象。模型极简,核心只有一个 state 字段:

factory DeviceConnection.fromMap(Map<dynamic, dynamic> map) {
  assert(map.containsKey(_keyState),
  'DeviceConnection map must contain state key');

  return DeviceConnection(
    state: map[_keyState] as int,
  );
}

Source: device_connection.dart

要点解读:

  • assert 前置校验:fromMap 要求事件数据必须包含 state 键,否则在调试模式下立即失败。这是对「原生事件契约」的强约束——宁可快速失败,也不允许静默解析出脏数据。
  • 值语义相等:重写了 operator == 与 hashCode,只要 state 相同即视为相等。这使 Stream.distinct() 或 ChangeNotifier 的去重判断可以直接工作。
  • state 的语义:具体数值(如连接成功、失败、断开)由原生 SDK 定义,Dart 侧仅透传 int;example 工程中 AppConstants.connectionFailed 用作默认/失败兜底值。精确的状态枚举值定义在常量文件中,本页未展开。

3. 事件流处理:BleDeviceConnectionProcessor

该处理器把 BleBaseEventProcessor 提供的原始事件转换为三个类型安全的 Stream:

/// Device connection status stream
static Stream<DeviceConnection> get deviceConnectionStream {
  return BleBaseEventProcessor.filterByType(BleEventConstants.typeDeviceConnection)
      .map((event) {
    final data = BleBaseEventProcessor.getValueFromEvent(event);
    return DeviceConnection.fromMap(data);
  });
}

Source: ble_device_connection_processor.dart

三个 Stream 的语义与来源:

Stream元素类型过滤的事件类型解析字段
scanStateStreamStringtypeScanDeviceListkeyState(扫描进行中/停止等状态字符串)
scanDeviceListStreamList<ScanDevice>typeScanDeviceListkeyList(原始 Map 列表,逐个 ScanDevice.fromMap)
deviceConnectionStreamDeviceConnectiontypeDeviceConnection整个事件数据交给 DeviceConnection.fromMap

设计要点:

  • 静态 getter + 延迟求值:每次访问 getter 都基于 filterByType(...) 返回的流重新 .map,但底层事件源是同一个,因此多个页面订阅同一条流不会丢失事件,也不会重复触发原生逻辑。
  • 容错解析:扫描列表解析时对 keyList 缺失做了兜底(?? []),并只用 whereType<Map>() 过滤出合法的设备 Map,非法条目被静默跳过——原生数据与 Dart 类型系统之间的边界防御。
  • 关注点分离:BleDeviceConnectionProcessor 只负责「转换」,不负责「分发」;分发由应用层决定(直接订阅或汇入 ConnectionStateManager)。

4. 应用层全局状态:ConnectionStateManager

example 工程通过一个 ChangeNotifier 单例把「最新连接状态」集中管理,供全局 UI 监听:

class ConnectionStateManager extends ChangeNotifier {
  static ConnectionStateManager? _instance;

  ConnectionStateManager._internal();

  factory ConnectionStateManager() {
    _instance ??= ConnectionStateManager._internal();
    return _instance!;
  }

  int _connectState = AppConstants.connectionFailed;

  int get connectState => _connectState;

  void updateConnectState(int newState) {
    if (_connectState != newState) {
      _connectState = newState;
      notifyListeners();
    }
  }

  static int get currentState => _instance?._connectState ?? AppConstants.connectionFailed;
}

Source: connection_state_manager.dart

要点解读:

  • 单例工厂:私有构造 + 懒加载静态实例,保证全应用共享同一份连接状态;currentState 静态 getter 让非 Widget 代码(如业务服务)无需持有实例即可读取。
  • 变更去重:updateConnectState 先比较新旧值,只有真正变化才 notifyListeners()——这是对 Flutter 重建开销的主动优化。
  • 默认失败态:初始状态为 AppConstants.connectionFailed,语义上「未连接即失败态」,UI 无需为 null 状态单独写分支。
  • 配套监听器:同目录下的 global_connection_listener.dart 负责把 BleDeviceConnectionProcessor 的事件流桥接进此类状态管理(本页通过文件清单确认其存在,具体桥接细节见其源码)。

核心流程:一次完整的连接生命周期

sequenceDiagram
    participant UI as Flutter UI
    participant CSM as ConnectionStateManager
    participant BCM as BleConnectionManager
    participant BBM as BleBaseManager
    participant DCM as Android DeviceConnectionManager
    participant BLE as BLE 协议栈
    participant BEP as BleBaseEventProcessor
    participant BCP as BleDeviceConnectionProcessor

    UI->>BCM: startScan()
    BCM->>BBM: invokeMethod(methodStartScan)
    BBM->>DCM: MethodChannel 调用
    DCM->>BLE: 启动扫描
    BLE-->>DCM: 扫描结果/状态回调
    DCM-->>BEP: 派发 typeScanDeviceList 事件
    BEP-->>BCP: filterByType + getValueFromEvent
    BCP-->>UI: scanStateStream / scanDeviceListStream
    UI->>BCM: connectDevice(index)
    BCM->>BBM: invokeMethod(methodConnectDevice, {argIndex: index})
    BBM->>DCM: MethodChannel 调用
    DCM->>BLE: 发起 GATT 连接
    BLE-->>DCM: 连接结果回调
    DCM-->>BEP: 派发 typeDeviceConnection 事件
    BEP-->>BCP: 映射为 DeviceConnection
    BCP-->>CSM: deviceConnectionStream 推送
    CSM-->>UI: updateConnectState + notifyListeners() 刷新
    UI->>BCM: disconnectBtDevice(index)
    BCM->>BBM: invokeMethod(methodDisconnectBtDevice, {argIndex: index})
    BBM->>DCM: MethodChannel 调用
    DCM->>BLE: 断开 GATT 连接

状态流转决策图

flowchart TD
    Start(["用户发起连接"]) --> Scan["startScan() 指令"]
    Scan --> List["scanDeviceListStream 收到设备列表"]
    List --> Pick["按 index 选择目标设备"]
    Pick --> Connect["connectDevice(index) 指令"]
    Connect --> Wait{"等待 deviceConnectionStream"}
    Wait -->|"state 表示连接成功"| OK["ConnectionStateManager 更新成功态"]
    Wait -->|"state 表示连接失败"| Fail["更新失败态<br/>(connectionFailed 兜底)"]
    Wait -->|"state 表示已断开"| Disc["更新断开态"]
    OK --> Data(["连接就绪,可收发数据"])
    Fail --> Retry(["提示用户,可重新连接"])
    Disc --> Retry
    Data -->|"用户退出/异常"| Disc

流程要点

  1. 扫描与连接解耦:扫描指令(startScan/stopScan)与连接指令(connectDevice/disconnectBtDevice)在 BleConnectionManager 中分属不同方法,中间通过事件流传递设备列表——这正是「指令下发、事件回报」双通道设计的体现。
  2. 索引是连接上下文:connectDevice(index) 的 index 必须与 scanDeviceListStream 中的列表位置一致;如果列表在两次事件之间发生变化,调用方需要自行保证索引有效性。
  3. 状态收敛到单例:无论原生层上报多少次状态,最终都通过 ConnectionStateManager.updateConnectState 的相等性判断收敛为「最新一次有效状态」,UI 只对变化做出反应。

使用示例

示例一:发起扫描并订阅设备列表与连接状态

以下代码展示了「指令 + 事件流」的典型组合用法(片段来自处理器与管理器源码):

// 订阅扫描状态(String:扫描中/停止等)
static Stream<String> get scanStateStream {
  return BleBaseEventProcessor.filterByType(BleEventConstants.typeScanDeviceList)
      .map((event) {
    final data = BleBaseEventProcessor.getValueFromEvent(event);
    return data[BleEventConstants.keyState] as String? ?? '';
  });
}

// 订阅连接状态,映射为 DeviceConnection
static Stream<DeviceConnection> get deviceConnectionStream {
  return BleBaseEventProcessor.filterByType(BleEventConstants.typeDeviceConnection)
      .map((event) {
    final data = BleBaseEventProcessor.getValueFromEvent(event);
    return DeviceConnection.fromMap(data);
  });
}

Source: ble_device_connection_processor.dart

调用方使用模式:

// 1. 订阅事件流(任意页面/任意次数,互不干扰)
BleDeviceConnectionProcessor.deviceConnectionStream.listen((conn) {
  ConnectionStateManager().updateConnectState(conn.state);
});

// 2. 下发指令
await BleConnectionManager.startScan();
// ... 收到 scanDeviceListStream 后展示列表 ...
await BleConnectionManager.connectDevice(index);

Source: ble_connection_manager.dart

示例二:监听全局连接状态驱动 UI

example 工程中所有需要感知连接状态的页面,只需监听 ConnectionStateManager:

final _connectionStateManager = ConnectionStateManager();

@override
void initState() {
  super.initState();
  _connectionStateManager.addListener(_onConnectionStateChanged);
}

void _onConnectionStateChanged() {
  final state = _connectionStateManager.connectState;
  // 根据 state 刷新连接指示、按钮可用性等
  setState(() {});
}

Source: connection_state_manager.dart

说明:updateConnectState 只在状态真正变化时触发 notifyListeners(),因此上面的监听回调天然避免了无效重建。

示例三:解析原生连接状态事件

DeviceConnection.fromMap 是原生事件进入 Dart 类型系统的唯一入口,调试时可借助 toString 直接打印:

final conn = DeviceConnection.fromMap({'state': 0x100});
print(conn); // DeviceConnection(state: 256)

// 相等性基于 state 值语义
assert(conn == DeviceConnection(state: 0x100));
assert(conn.hashCode == DeviceConnection(state: 0x100).hashCode);

Source: device_connection.dart

配置选项

本能力的「配置面」由常量类与原生侧持久化共同构成。Dart 侧方法名、参数键、事件类型集中在常量类中,改动一处即可全局生效;原生侧的双连接配置通过 SharedPreferences 持久化。

Dart 侧常量(配置面)

常量类关键成员类型用途
BleMethodConstantsmethodStartScan / methodStopScanStringMethodChannel 方法名:开始/停止扫描
BleMethodConstantsmethodConnectDevice / methodDisconnectBtDeviceStringMethodChannel 方法名:连接/断开设备
BleMethodConstantsargIndexString设备索引参数键,随连接/断开指令传递
BleEventConstantstypeScanDeviceList / typeDeviceConnectionString事件类型:扫描列表事件 / 连接状态事件
BleEventConstantskeyState / keyListString事件数据字段键:状态字符串 / 设备列表
AppConstantsconnectionFailedintexample 应用默认/兜底连接状态值

注:具体常量取值定义于各常量文件(lib/constant/ble_method_constants.dart、lib/constant/ble_event_constants.dart、lib/constant/constants.dart),本页未逐一读取,取值以源码为准。

原生侧配置:双连接持久化

Android 原生层通过 DoubleConnectionSp.java 持久化双连接(同时连接两台设备)的相关配置,例如上次连接过的设备索引/地址,供下次启动恢复会话使用。具体键名与默认值见原生源码:

Source: DoubleConnectionSp.java

API 参考

BleConnectionManager(静态类,lib/manager/ble_connection_manager.dart)

static Future<void> startScan()

开始扫描周围蓝牙设备。无参数;扫描结果不在此返回,通过 scanDeviceListStream 异步推送。

static Future<void> stopScan()

停止扫描。通常在拿到目标设备列表或页面退出时调用,以节省电量与信道资源。

static Future<void> connectDevice(int index)

按扫描列表索引连接设备。

参数:

  • index (int):目标设备在扫描列表中的索引。

说明: 索引必须与 scanDeviceListStream 最近一次推送的列表位置一致;连接结果通过 deviceConnectionStream 异步回报,本方法只保证指令送达原生层。

static Future<void> disconnectBtDevice(int index)

断开指定索引设备的连接。

参数:

  • index (int):目标设备在扫描列表中的索引。

异常行为: 各方法均 await BleBaseManager.invokeMethod,若 MethodChannel 尚未初始化或原生调用失败,异常沿 Future 向上抛出,由调用方处理。

DeviceConnection(lib/model/device_connection.dart)

成员签名说明
构造const DeviceConnection({required int state})仅需 state 字段
属性final int state原生连接状态值(语义由原生 SDK 定义)
工厂factory DeviceConnection.fromMap(Map<dynamic, dynamic> map)从事件数据解析;assert 要求必须含 state 键
方法Map<String, dynamic> toMap()序列化为 {'state': state}
重写operator == / hashCode值语义相等,仅比较 state
重写String toString()输出 DeviceConnection(state: N) 便于调试

BleDeviceConnectionProcessor(静态类,lib/processor/ble_device_connection_processor.dart)

成员签名说明
scanStateStreamstatic Stream<String>扫描状态流(基于 typeScanDeviceList 事件的 keyState 字段)
scanDeviceListStreamstatic Stream<List<ScanDevice>>扫描设备列表流(keyList 字段逐个映射为 ScanDevice)
deviceConnectionStreamstatic Stream<DeviceConnection>设备连接状态流(typeDeviceConnection 事件映射为 DeviceConnection)

ConnectionStateManager(example/lib/utils/connection_state_manager.dart)

成员签名说明
工厂factory ConnectionStateManager()懒加载单例;私有 _internal 构造
属性int get connectState当前连接状态,初始为 AppConstants.connectionFailed
方法void updateConnectState(int newState)更新状态;值未变化时不通知
静态static int get currentState无实例也可读取最新状态;未初始化时返回 connectionFailed

失败模式、边界情况与并发

事件契约被破坏(缺少 state 键)

DeviceConnection.fromMap 通过 assert 强制要求事件数据包含 state 键。在调试模式(assert 生效)下,原生事件契约被破坏会立即抛错,帮助开发者第一时间发现两端协议不一致;但在发布模式下 assert 会被剥离,缺失键将导致 map[_keyState] as int 对 null 做类型转换而抛出 TypeError。设计意图:宁可快速失败,也不允许把脏数据悄悄带入业务层。

扫描列表索引漂移

connectDevice(index) / disconnectBtDevice(index) 依赖调用方维护的索引。若在两次 scanDeviceListStream 推送之间列表顺序变化(设备移出范围、去重合并等),旧索引可能指向错误设备。调用方应在连接前重新确认索引,或在 UI 上禁用「已过期」的列表项。

重复订阅与流生命周期

scanDeviceListStream 等 getter 每次访问都会基于同一事件源重新构造映射流。如果页面在 dispose 时未取消订阅(StreamSubscription.cancel()),会产生泄漏的监听器。此外,多页面同时订阅时,每个订阅者都会独立收到事件——这是 Stream 多播语义的预期行为,但业务上需要注意幂等处理(例如重复的「连接成功」状态不应触发重复逻辑,ConnectionStateManager 的相等性判断恰好提供了这层保护)。

并发与单例线程安全

  • ConnectionStateManager 是应用内单例,所有更新都发生在 Dart 单线程事件循环中,updateConnectState 的「读-比较-写」不存在跨线程竞争;但要注意调用顺序:多个来源(页面 A、页面 B、后台服务)都可能调用 updateConnectState,最后一个调用者决定最终状态,这与「全局最新状态」的语义一致。
  • 原生侧 DeviceConnectionManager 与 DoubleConnectionSp 属于 SDK 线程模型(连接状态回调通常来自 BLE 回调线程),由原生层负责串行化后再通过事件通道回传 Dart;Dart 侧无需加锁。

连接失败与重试

初始状态即 connectionFailed,连接失败/断开后状态回落到失败或断开值。SDK 不提供自动重连,重试策略由应用层决定(重新 connectDevice(index))。DoubleConnectionSp 的双连接配置可在应用重启后恢复上次会话,属于原生侧的会话恢复机制。

性能与运维注意

  • 避免过度重建:ConnectionStateManager.updateConnectState 的相等性短路保证了只有状态真正变化才触发 notifyListeners,配合 ChangeNotifier 的监听方(如 AnimatedBuilder/ListenableBuilder)可将重建范围限制在依赖该状态的子树。
  • 扫描功耗:startScan/stopScan 是显式成对调用,长时间保持扫描会持续占用 BLE 广播信道与电量;建议页面在拿到目标设备后立即 stopScan()。
  • 事件解析成本:scanDeviceListStream 每次事件都会把整个列表重新 ScanDevice.fromMap。设备数量大时(数十台以上)应避免在 UI 构建路径中同步做繁重处理,必要时在 map 之后追加 where/distinct 收窄。
  • 双连接资源:原生侧支持双连接(DoubleConnectionSp),同时维持两条 GATT 链路会占用更多系统资源,应用中需管理好每个连接的索引与状态,避免互相覆盖 ConnectionStateManager 的全局状态。

扩展点

  1. 自定义连接状态机:DeviceConnection.state 是 int 透传,可在应用层定义自己的状态枚举并映射原生值,例如把成功/失败/断开/连接中映射为业务状态,保持 UI 与 SDK 数值解耦。
  2. 多页面状态分发:除了 ConnectionStateManager(最新值缓存),也可直接订阅 deviceConnectionStream 做流式分发(如路由到多个页面的独立状态模块),两者可共存。
  3. 指令扩展:新增连接相关操作(如获取连接参数、查询已连接设备列表)时,按 BleConnectionManager 的模式在 BleMethodConstants 增加方法名与参数键,再补一个静态方法即可,无需改动事件流结构。
  4. 重连策略:在 deviceConnectionStream 上组合 retryWhen/timeout 等 Rx 式操作(或手写重试逻辑),即可在不改 SDK 的前提下实现自动重连。

测试情况

本页覆盖的源码未发现针对连接管理器的独立测试文件(搜索范围限于连接相关文件)。事件流与模型的纯函数特性(fromMap/toMap/==/Stream 映射)适合用 Dart 单元测试覆盖:构造原生格式的 Map,验证 DeviceConnection 解析、scanDeviceListStream 的列表映射与容错(非法条目被 whereType 过滤)以及 ConnectionStateManager 的去重通知行为。assert 路径可在调试模式下用缺失 state 键的 Map 验证契约校验。

相关链接

  • BleConnectionManager(lib/manager/ble_connection_manager.dart)
  • BleDeviceConnectionProcessor(lib/processor/ble_device_connection_processor.dart)
  • DeviceConnection 模型(lib/model/device_connection.dart)
  • ConnectionStateManager(example/lib/utils/connection_state_manager.dart)
  • GlobalConnectionListener(example/lib/utils/global_connection_listener.dart)
  • Android 原生 DeviceConnectionManager.kt
  • Android 原生 DoubleConnectionSp.java
  • SDK 发布版连接管理器(libs/Send Interface/ble_connection_manager.dart)

兄弟页面指引:设备扫描与发现流程、设备能力服务(音频/通话/文件)、OTA 升级等话题请参见对应目录页;本页仅聚焦连接指令、状态模型、事件流与应用层状态管理。

Next
设备信息、配置与按键设置