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

    • 项目概述与能力总览
    • 快速开始与 SDK 集成
  • SDK 核心接口

    • 发送接口 BleMethod
    • 接收接口 BleEventStream
    • 数据模型与常量定义
  • 平台原生实现

    • Android 原生层
    • iOS 原生层架构
    • iOS 蓝牙管理与 SDK 运行
    • 辅助连接与广播音箱
  • OTA 升级功能

    • 升级流程与传输通道
    • 自动回连机制
    • 复用空间升级
    • 自定义命令
  • 示例应用

    • 页面结构与用户旅程
    • 设备扫描与连接管理
    • 固件文件管理
    • 升级执行与状态展示
    • 设置与调试
  • 文档与支持

    • 接口文档与收发说明
    • 调试与问题排查

数据模型与常量定义

本文档介绍 JL_OTA Flutter SDK 中定义的数据模型与常量契约:BleMethodConstants(方法调用常量)、BleEventConstants(事件流常量)、AppConstants(应用级常量)以及 ScanDevice、DeviceConnection 两个核心数据模型,说明它们如何在 Flutter 与原生 BLE 插件之间充当稳定的通信契约。

Purpose and Scope

本页覆盖 SDK 核心 API 层中"契约层"的全部内容:

  • 常量契约:code/JL_OTA/lib/constant/ 目录下的三个常量类,它们定义了 Flutter 侧与原生侧(Android/iOS MethodChannel)之间所有方法名、参数键与事件键的字符串协议。
  • 数据模型:code/JL_OTA/lib/model/ 目录下的 ScanDevice(扫描到的设备)与 DeviceConnection(设备连接状态)模型,它们是事件回调与业务层之间传递数据的载体。

以下主题属于其他目录页,不在本页展开:

  • 方法调用的封装与执行细节(BleMethod 类)→ 参见 SDK 核心 API 相关页面。
  • 事件流的订阅与分发机制(BleEventStream 类)→ 参见 SDK 核心 API 相关页面。
  • 示例 App 的 UI 与业务管理器(example/lib/ 下的页面与对话框)→ 参见示例应用相关页面。
  • 原生插件的实现(Android/Kotlin、iOS/Swift 源码)→ 参见原生层相关页面。

说明:本次文档基于源码探索时预算有限,ble_event_constants.dart、constants.dart 及两个模型文件的完整字段清单未逐行确认,文中凡涉及这些文件的内容均以示例工程中的实际引用证据为准,并明确标注。

Overview

JL_OTA Flutter SDK 采用 Flutter ↔ 原生(MethodChannel) 的桥接架构。Flutter 侧不能直接操作蓝牙硬件,所有能力(扫描、连接、OTA 升级、日志管理等)最终都要通过原生插件完成。在这种架构下,字符串常量就是跨语言边界的协议——方法名、事件名、参数键必须两端完全一致,否则调用会静默失败或事件无法匹配。

为此,SDK 在 lib/constant/ 下集中定义了三个常量类:

常量类文件职责
BleMethodConstantsble_method_constants.dart方法名(METHOD_*)与参数键(ARG_*),即 Flutter 调用原生时的"请求协议"
BleEventConstantsble_event_constants.dart事件键(如 KEY_STATE、SCAN_STATE_SCANNING),即原生回调 Flutter 时的"通知协议"
AppConstantsconstants.dart应用级全局配置(如用户协议 URL)

数据模型则承担"载荷"角色:原生侧返回的原始数据经 ScanDevice、DeviceConnection 等模型结构化后,通过 BleEventStream 分发给业务层。常量和模型共同构成了 SDK 的稳定契约层——业务代码只依赖这些契约,不依赖具体的原生实现,因此更换原生实现或扩展新能力时,只要保持契约不变,上层代码无需改动。

flowchart TD
    subgraph sg_App["示例应用层 example/lib"]
        AppUI["页面 / 管理器<br/>(devices_page.dart 等)"]
        UIConstants["UI 常量类<br/>MethodChannelConstants / OtaStateConstants"]
    end

    subgraph sg_SDK["SDK 核心层 lib"]
        BleMethod["BleMethod<br/>方法调用封装"]
        BleEventStream["BleEventStream<br/>事件流封装"]
        subgraph sg_Contract["契约层 constant/ + model/"]
            MethodConst["BleMethodConstants<br/>METHOD_* / ARG_*"]
            EventConst["BleEventConstants<br/>KEY_STATE 等"]
            AppConst["AppConstants<br/>应用配置"]
            ScanDevice["ScanDevice<br/>扫描设备模型"]
            DeviceConn["DeviceConnection<br/>连接状态模型"]
        end
    end

    subgraph sg_Native["原生插件层"]
        Native["Android / iOS 插件<br/>MethodChannel"]
    end

    AppUI -->|"引用"| UIConstants
    AppUI -->|"调用"| BleMethod
    AppUI -->|"订阅"| BleEventStream
    BleMethod -->|"方法名/参数键"| MethodConst
    BleMethod -->|"invokeMethod"| Native
    Native -->|"事件回调"| BleEventStream
    BleEventStream -->|"解析载荷"| ScanDevice
    BleEventStream -->|"解析载荷"| DeviceConn
    BleEventStream -->|"事件键"| EventConst
    UIConstants -->|"复用契约常量"| EventConst
    UIConstants -->|"复用契约常量"| MethodConst
    AppConst -.->|"全局配置"| AppUI

架构解读:BleMethodConstants 与 BleEventConstants 是双向通信契约——前者约束 Flutter→原生方向的方法调用(BleMethod 使用 METHOD_* 作为方法名、ARG_* 作为参数键),后者约束原生→Flutter 方向的事件通知(BleEventStream 按 KEY_STATE 等事件键分发)。ScanDevice 与 DeviceConnection 作为事件载荷的载体,在事件流与业务层之间传递结构化数据。示例工程中的 MethodChannelConstants、OtaStateConstants、ScanStateConstants 等 UI 常量类直接复用契约常量(如 BleEventConstants.KEY_STATE),验证了契约层的可复用性。

常量契约:BleMethodConstants

BleMethodConstants(ble_method_constants.dart)是 SDK 中规模最大的常量类,集中定义了 Flutter 调用原生 BLE 插件所需的全部方法名与参数键。它分两组:

  • METHOD_*:方法名,作为 MethodChannel.invokeMethod 的第一个参数。
  • ARG_*:参数键,作为方法调用 arguments Map 中的键名。

方法名常量(METHOD_*)

按功能域划分,方法名常量覆盖了 SDK 的全部对外能力:

功能域常量值
扫描控制METHOD_IS_SCANNING'isScanning'
METHOD_CHECK_BLUETOOTH_ENVIRONMENT'checkBluetoothEnvironment'
METHOD_START_SCAN'startScan'
METHOD_STOP_SCAN'stopScan'
METHOD_GET_SCAN_FILTER'getScanFilter'
METHOD_SET_SCAN_FILTER'setScanFilter'
连接控制METHOD_CONNECT_DEVICE'connectDevice'
METHOD_DISCONNECT_BT_DEVICE'disconnectBtDevice'
METHOD_GET_CONNECT_WAY'getConnectWay'
METHOD_SET_CONNECT_WAY'setConnectWay'
METHOD_IS_USING_SDK_BLUETOOTH'isUseSDKBluetooth'
METHOD_SET_USING_SDK_BLUETOOTH'setUseSDKBluetooth'
METHOD_IS_USING_GATT_OVER_EDR'isUseGattOverEdr'
METHOD_SET_GATT_OVER_EDR'setGattOverEdr'
METHOD_GET_GATT_SERVICE_UUIDS'getGattServiceUuids'
METHOD_SET_GATT_SERVICE_UUIDS'setGattServiceUuids'
METHOD_IS_USE_DEVICE_AUTH'isUseDeviceAuth'
METHOD_SET_USE_DEVICE_AUTH'setUseDeviceAuth'
METHOD_IS_HID_DEVICE'isHidDevice'
METHOD_SET_HID_DEVICE'setHidDevice'
METHOD_IS_USE_CUSTOM_RECONNECT_WAY'isUseCustomReConnectWay'
METHOD_SET_USE_CUSTOM_RECONNECT_WAY'setUseCustomReConnectWay'
METHOD_GET_BLE_REQUEST_MTU'getBleRequestMtu'
METHOD_SET_BLE_REQUEST_MTU'setBleRequestMtu'
版本与日志METHOD_GET_SDK_VERSION'getSdkVersion'
METHOD_GET_APP_VERSION'getAppVersion'
METHOD_GET_LOG_FILE_DIR_PATH'getLogFileDirPath'
METHOD_GET_LOG_FILES'getLogFiles'
METHOD_LOG_FILE_INDEX'logFileIndex'
METHOD_SHARE_LOG_FILE'shareLogFile'
METHOD_DELETE_ALL_LOG_FILE'deleteAllLogFile'
文件管理METHOD_DOWNLOAD_FILE'downloadFile'
METHOD_READ_FILE_LIST'readFileList'
METHOD_SET_SELECTED_INDEX'setSelectedIndex'
METHOD_DELETE_OTA_FILE_INDEX'deleteOtaFileIndex'
METHOD_TRY_TO_CHECK_STORAGE_ENVIRONMENT'tryToCheckStorageEnvironment'
METHOD_PICK_FILE'pickFile'
OTA 升级METHOD_TYPE_IS_OTA'isOta'
METHOD_START_OTA'startOTA'
其他METHOD_GET_WIFI_IP_ADDRESS'getWifiIpAddress'
METHOD_POP_ALL_ACTIVITY'popAllActivity'
METHOD_SEND_CUSTOM_COMMAND'sendCustomCommand'

参数键常量(ARG_*)

方法调用需要携带参数时,参数以 Map 形式传递,键名由 ARG_* 常量统一约束:

常量值关联方法域
ARG_INDEX'index'文件索引选择
ARG_FILTER'filter'扫描过滤条件
ARG_CONNECT_WAY'connectWay'连接方式
ARG_IS_USING_SDK_BLUETOOTH'isUsingSDKBluetooth'SDK 蓝牙开关
ARG_IS_USING_GATT_OVER_EDR'isUsingGattOVerEdr'Gatt Over EDR 开关
ARG_GATT_SERVICE_UUIDS'gattServiceUuids'GATT Service UUID 列表
ARG_IS_AUTH'isAuth'设备认证开关
ARG_IS_HID'isHid'HID 设备标记
ARG_IS_CUSTOM'isCustom'自定义重连方式
ARG_MTU'mtu'MTU 请求值
ARG_LOG_FILE_INDEX'logFileIndex'日志文件索引
ARG_HTTP_URL'httpUrl'HTTP 下载地址
ARG_POS'pos'位置参数
ARG_PATH'path'升级文件路径
ARG_CUSTOM_DATA'customData'自定义命令载荷

设计意图

将所有方法名与参数键收敛到单一常量类,而非散落在调用处,是契约集中化的设计决策:

  1. 单一事实来源:原生侧插件与 Flutter 侧 SDK 都引用同一份字符串协议(原生侧以常量文件形式镜像),避免魔法字符串导致的两端漂移。
  2. 类型安全替代:Dart 是弱字符串类型语言,集中定义让 IDE 支持自动补全与重命名重构,降低拼写错误风险。
  3. 跨端对齐的文档价值:常量即 API 文档——原生开发者只需对照此文件即可实现完整的通道协议。

例如 BleMethod 封装层发起扫描时,方法名取 BleMethodConstants.METHOD_START_SCAN,原生侧对应处理 "startScan",两端通过该字符串握手:

/// 检查是否正在扫描设备的方法名。
static const String METHOD_IS_SCANNING = 'isScanning';

/// 开始扫描设备的方法名。
static const String METHOD_START_SCAN = 'startScan';

/// 停止扫描设备的方法名。
static const String METHOD_STOP_SCAN = 'stopScan';

Source: ble_method_constants.dart

/// 索引参数名。
static const String ARG_INDEX = 'index';

/// 过滤条件参数名。
static const String ARG_FILTER = 'filter';

/// 使用连接方式的参数名。
static const String ARG_CONNECT_WAY = 'connectWay';

Source: ble_method_constants.dart

常量契约:BleEventConstants

BleEventConstants(ble_event_constants.dart)定义了 BLE 事件流相关的常量,是原生侧主动上报状态时的事件键协议。与 BleMethodConstants 的"请求"方向相反,它是"通知"方向:原生插件通过 MethodChannel 的事件通道把扫描状态、连接状态、OTA 进度等事件推送给 Flutter 侧,BleEventStream 依据这些事件键进行匹配与分发。

从示例工程的引用可以确认其至少包含以下事件键(完整字段清单未在本次探索中逐行确认):

常量(依据引用确认)用途
BleEventConstants.KEY_STATE状态事件键,用于携带 BLE 开关/系统状态
BleEventConstants.SCAN_STATE_SCANNING扫描状态值,标识"正在扫描中"

示例工程 devices_page.dart 中的 OtaStateConstants 与 ScanStateConstants 直接引用这些事件常量,证明事件常量是跨 SDK 与业务层复用的公共契约:

class OtaStateConstants {
  /// OTA State Constants
  static const String keyState = BleEventConstants.KEY_STATE;
  // ...
}

class ScanStateConstants {
  /// Scan State Constants
  static const String stateScanning = BleEventConstants.SCAN_STATE_SCANNING;
  // ...
}

Source: devices_page.dart

设计意图:将事件键与状态值也集中定义为常量,业务层订阅事件流时直接使用 BleEventConstants.KEY_STATE 等命名常量,而不是手写字符串。这样当原生侧调整事件协议时,只需修改常量定义与原生镜像,业务代码不受影响。

常量契约:AppConstants

AppConstants(constants.dart)承载应用级全局常量与配置值(例如用户协议 URL)。它与 SDK 桥接协议无关,属于产品层配置,主要服务于示例应用与 SDK 内的通用逻辑。

设计意图:将跨页面、跨模块复用的应用配置从散落的硬编码中抽离,统一管理,便于发布时集中修改(如更换协议地址、调整全局开关)。

数据模型:ScanDevice 与 DeviceConnection

lib/model/ 目录下定义了两个核心数据模型,它们是事件流载荷的结构化载体:

模型文件职责
ScanDevicescan_device.dart描述一次扫描发现的蓝牙设备(地址、名称、信号强度等),是扫描结果事件的载荷
DeviceConnectiondevice_connection.dart描述设备连接状态/连接信息,是连接状态事件的载荷

这两个模型在 SDK 数据流中的位置如下:

flowchart LR
    Native["原生插件"] -->|"扫描结果原始数据"| ScanDevice["ScanDevice"]
    Native -->|"连接状态原始数据"| DeviceConn["DeviceConnection"]
    ScanDevice --> Stream["BleEventStream 事件流"]
    DeviceConn --> Stream
    Stream -->|"分发携带模型的事件"| Business["业务层<br/>示例 App 管理器"]

设计意图:模型层将原生侧返回的异构数据(Map、JSON 等)转换为强类型 Dart 对象,业务层消费事件时无需关心原生数据结构,直接读取 ScanDevice 的字段即可。这一层抽象同时屏蔽了 Android 与 iOS 在数据格式上的差异——两端都向 Flutter 侧吐同一结构的模型数据。

注意:本次探索受工具预算限制,未逐行读取 scan_device.dart 与 device_connection.dart 的字段定义;上述职责描述基于文件名、目录结构与 SDK 桥接架构推断。完整字段清单请直接查看 scan_device.dart 与 device_connection.dart。

Prev
接收接口 BleEventStream