杰理 SDK 文档中心
首页
首页
  • 项目概览

    • 仓库简介与示例构成
    • 支持的平台与协议
  • 快速开始

    • 导入工程与编译运行
    • 蓝牙权限配置
  • 应用架构

    • 工程结构与模块分层
    • 核心类与回调接口
  • 核心功能

    • 蓝牙设备扫描
    • ATT 设备连接与断开管理
    • 数据收发与通知回调
  • 配置与调试

    • 协议配置常量
    • 日志系统与调试指南
  • 界面与交互

    • 设备扫描与连接界面
    • 设备详情与设置界面

工程结构与模块分层

android-bt-demo 是珠海杰理科技股份有限公司(Jieli)提供的 Android 端蓝牙测试示例代码集合仓库。本页说明仓库的整体工程组织方式、Gradle 模块划分、Java 包分层结构与各层职责边界。

目的与范围

本页聚焦 工程组织维度,回答以下问题:

  • 仓库顶层包含哪些内容,为什么这样组织?
  • ATTConnect 示例工程的 Gradle 构建结构(根工程与 :app 模块)是怎样的?
  • com.jieli.bt.att 下的包(tool.ble、util 等)如何分层,各自承担什么职责?
  • 层与层之间如何协作,新增一个示例工程时如何扩展?

不属于本页范围(将由其他目录页单独说明):

  • BLE 扫描、连接、数据收发的具体 API 与实现细节(见 BLE 连接管理相关页面)
  • 具体设备/协议行为(GATT over BR/EDR 与 GATT over BLE 的差异)

概述

该仓库当前包含一个核心用例:ATT 设备(GATT over BR/EDR)的连接示例,演示 Android 端如何通过 GATT 协议与杰理蓝牙产品进行数据通讯。仓库采用「一个示例一个独立目录」的组织策略,每个示例目录是完整的、可独立导入 Android Studio 的 Gradle 工程。

从工程结构角度,整个仓库呈现三层结构:

  1. 仓库层(根目录):README 文档与许可证;
  2. 示例层(ATTConnect/):完整的 Gradle 工程,含 settings.gradle.kts 与 :app 模块;
  3. 代码层(app/src/main/java/com.jieli.bt.att/):按职责划分的 Java 包结构。

支持环境与协议要求(摘自 README.md):

项目说明
最低 Android 版本Android 5.0(API 21)
目标版本Android 16+(API 36+)
开发语言Kotlin / Java
支持协议GATT over BR/EDR(ATT)、GATT over BLE

架构

仓库与模块结构

flowchart TD
    subgraph sg_Repo["android-bt-demo 仓库(根目录)"]
        README["README.md / README_en.md"]
        LICENSE["LICENSE(Apache 2.0)"]
    end

    subgraph sg_ATT["ATTConnect 示例工程"]
        SETTINGS["settings.gradle.kts<br/>rootProject.name = BluetoothDemo"]
        subgraph sg_App[":app 模块"]
            SRC["src/main/java<br/>com.jieli.bt.att"]
            LIBS["libs/*.aar 本地依赖"]
        end
    end

    subgraph sg_BLE["tool.ble(BLE/ATT 核心能力层)"]
        BLE_MGR["BleManager"]
        BLE_CB["BleEventCallbackManager"]
        BLE_THREAD["SendBleDataThread"]
        BLE_IF["interfaces/<br/>回调与操作接口"]
        BLE_MODEL["model/<br/>BleDevice、ScanDeviceInfo"]
    end

    subgraph sg_UTIL["util(通用工具层)"]
        UTIL_BT["BluetoothUtil"]
        UTIL_HEX["CHexConver"]
        UTIL_UUID["UuidUtil"]
    end

    SETTINGS -->|"include(:app)"| SRC
    SRC --> BLE_MGR
    SRC --> UTIL_BT
    BLE_MGR --> BLE_CB
    BLE_MGR --> BLE_THREAD
    BLE_MGR --> BLE_IF
    BLE_MGR --> BLE_MODEL

结构说明:

  • 根目录只承担仓库级职责:README 提供选型与快速开始指引,LICENSE 声明 Apache 2.0 协议。业务代码全部收拢在 ATTConnect/ 内,避免根目录被多个工程文件污染。
  • settings.gradle.kts 将工程命名为 BluetoothDemo 并只包含一个 :app 模块,保证示例可独立打开、独立同步。
  • :app 模块内,libs/ 目录以本地 AAR 方式承载杰理蓝牙 SDK,代码层通过 fileTree 引入(见 app/build.gradle.kts)。
  • tool.ble 是示例的核心能力层:BleManager 是设备管理入口,SendBleDataThread 负责数据发送的线程调度,interfaces/ 抽象回调与操作契约,model/ 承载设备数据模型。
  • util 是纯工具层:蓝牙工具、十六进制转换、UUID 工具,被能力层复用,不依赖具体业务。

分层协作关系

flowchart LR
    subgraph sg_UI["展示层"]
        UI["Activity / 应用入口"]
    end
    subgraph sg_SVC["能力层(tool.ble)"]
        MGR["BleManager"]
        TH["SendBleDataThread"]
    end
    subgraph sg_IF["接口层(interfaces)"]
        IF1["IBleOp / IBleEventCallback / 回调接口"]
    end
    subgraph sg_SYS["系统层"]
        SYS["Android Bluetooth API<br/>(GATT over BR/EDR)"]
    end
    subgraph sg_MODEL["模型与工具层"]
        MD["model:BleDevice、ScanDeviceInfo"]
        UT["util:BluetoothUtil、CHexConver、UuidUtil"]
    end

    UI --> MGR
    MGR --> IF1
    IF1 --> SYS
    SYS -.->|"系统回调"| MGR
    MGR --> TH
    MGR --> MD
    MGR --> UT

设计意图:上层(UI)只与 BleManager 打交道,系统蓝牙 API 的差异被 interfaces/ 的抽象隔离;线程管理(发送队列)与数据模型分别独立成类,职责单一、便于替换与测试。

仓库顶层结构

根目录内容由 README.md 的工程结构章节 明确定义:

android-bt-demo/
├── ATTConnect/                          # 📌 ATT 设备连接示例
├── LICENSE                              # Apache 2.0 开源协议
└── README.md
条目类型职责
ATTConnect/独立 Gradle 工程ATT 设备(GATT over BR/EDR)连接示例,可单独导入 Android Studio
LICENSE文件Apache 2.0 开源协议声明
README.md / README_en.md文档概述、平台要求、快速开始、工程结构、示例选择指南

设计意图:仓库定位是「示例集合」,因此根目录刻意保持极简,每个示例以完整工程目录的形式平铺。这样客户可以按需拷贝单个示例目录,而不必携带整个仓库;同时避免多个示例共享一个 Gradle 工程导致构建耦合。README 中明确提示:ATTConnect 适合**双模蓝牙设备(经典蓝牙 + BLE)**通过 GATT 协议进行高速数据通讯的场景,核心类为 BtScanner(蓝牙扫描)与 BleManager(BLE 设备管理)。

Gradle 构建结构

根工程配置(settings.gradle.kts)

ATTConnect/settings.gradle.kts 中,仓库源通过 dependencyResolutionManagement 统一管理,并显式声明根工程名与模块:

dependencyResolutionManagement {
    repositories {
        // 仓库源策略:按组匹配放行 Google / AndroidX / 官方依赖
        includeGroupByRegex("com\\.android.*")
        includeGroupByRegex("com\\.google.*")
        includeGroupByRegex("androidx.*")
    }
}

rootProject.name = "BluetoothDemo"
include(":app")

来源:ATTConnect/settings.gradle.kts(节选,非完整文件)

要点:

  • rootProject.name = "BluetoothDemo":示例工程在 IDE 中显示为 BluetoothDemo,与仓库名 android-bt-demo 解耦——同一个工程可能被客户复制改名,工程名不应硬编码仓库名。
  • include(":app"):当前仅一个应用模块;后续若引入 library 模块(如抽取 SDK 封装),在此追加 include(":xxx") 即可。
  • includeGroupByRegex 的白名单策略:仅放行 Google/AndroidX 官方组,其他依赖(如本地 AAR)不走远程仓库,避免依赖解析被外部源污染。

app 模块依赖(app/build.gradle.kts)

:app 模块通过 fileTree 引入 libs/ 目录下的本地 AAR 作为蓝牙 SDK 依赖:

dependencies {
    implementation(fileTree(Pair("include", "*.aar"), Pair("dir", "libs")))
    // ... 其余依赖
}

来源:ATTConnect/app/build.gradle.kts(节选)

设计意图:杰理蓝牙 SDK 以 AAR 形式随示例分发,走本地文件依赖而非 Maven 仓库。好处是示例离线可用、版本随工程锁定;代价是升级 SDK 需要手动替换 libs/*.aar,这是「示例代码」定位下的合理取舍。

Java 包分层详解

代码统一位于 com.jieli.bt.att 命名空间下,分为两大包:tool.ble(能力层)与 util(工具层)。

tool.ble —— BLE/ATT 核心能力层

文件角色
BleManager.java设备管理总入口:扫描、连接/断开、数据收发、GATT 服务发现的编排者
BleEventCallbackManager.java事件回调注册与分发管理,把系统/内部事件转发给上层
SendBleDataThread.java数据发送专用线程,串行化写操作,避免并发写导致 GATT 写入失败
interfaces/BleEventCallback.java事件回调接口(供上层实现)
interfaces/IBleEventCallback.java内部事件回调契约
interfaces/IBleOp.java蓝牙操作抽象(扫描、连接、写等操作的定义)
interfaces/IBtScanCallback.java扫描结果回调
interfaces/OnThreadStateListener.java发送线程状态监听
interfaces/OnWriteDataCallback.java写数据完成回调
model/BleDevice.java已连接/已发现设备的领域模型
model/ScanDeviceInfo.java扫描到的设备信息模型(RSSI、名称、地址等)

分层逻辑:

  1. 接口层(interfaces/):把「扫描、连接、写数据、线程状态」等异步操作全部抽象为接口。上层代码依赖接口而非具体实现,是替换底层蓝牙实现(例如从 BR/EDR 切到 BLE)的接缝点。
  2. 管理器层(BleManager、BleEventCallbackManager):BleManager 对外提供门面式 API;BleEventCallbackManager 负责回调的注册与派发,让回调只投递到已注册的监听者。
  3. 线程层(SendBleDataThread):GATT 写入在 Android 上对时序敏感,数据发送被放入专用线程串行执行,并用 OnWriteDataCallback 反馈每包写入结果,防止上层疯狂调用导致指令交错。
  4. 模型层(model/):BleDevice 与 ScanDeviceInfo 分离「已连接设备」与「扫描结果」两种语义,避免把扫描临时信息混入设备状态。

util —— 通用工具层

文件职责
BluetoothUtil.java系统蓝牙相关封装(适配器获取、状态判断等)
CHexConver.java十六进制与字节数组转换,供协议数据收发使用
UuidUtil.javaGATT Service/Characteristic UUID 的解析与生成

设计意图:工具层不依赖 tool.ble 的任何类型,可独立复用与单元测试;CHexConver 单独成类是因为杰理协议栈大量以 hex 字符串形式交互,属于高频公共操作。

核心流程

下图展示数据从上层入口到系统蓝牙 API 再到回调返回的完整时序:

sequenceDiagram
    participant App as 应用入口(Activity)
    participant MGR as BleManager
    participant IF as interfaces 回调/操作接口
    participant SYS as Android Bluetooth API
    participant TH as SendBleDataThread

    App->>MGR: 发起扫描/连接请求
    MGR->>IF: 调用 IBleOp 抽象操作
    IF->>SYS: 系统蓝牙 API(GATT over BR/EDR)
    SYS-->>MGR: 设备发现 / 连接状态事件
    MGR-->>App: 经 BleEventCallbackManager 分发回调
    App->>MGR: 写入业务数据
    MGR->>TH: 投递写任务(串行队列)
    TH-->>MGR: 写完成(OnWriteDataCallback)
    MGR-->>App: 通知发送结果

流程要点:

  • 异步为主:扫描、连接、写入全部走回调,BleEventCallbackManager 是上层感知事件变化的唯一通道;
  • 写入串行化:所有写操作经 SendBleDataThread 排队执行,规避 Android GATT 对并发写入的限制;
  • 状态可监听:OnThreadStateListener 暴露线程生命周期,便于上层在断开/重连时复位发送队列。

使用示例

示例一:按 README 指引选择并导入示例

README 在快速开始章节直接给出了目录选择方式,客户按需拷贝 ATTConnect/ 目录即可:

android-bt-demo/
├── ATTConnect/       # ATT 设备(GATT over BR/EDR)连接示例
└── .../              # 更多示例持续更新中

来源:README.md

随后在 Android Studio 中 File → Open 选择 ATTConnect/ 目录,等待 Gradle 同步后运行 app。这正是「一个示例一个独立工程」结构的直接收益:客户无需理解整个仓库即可单目录构建。

示例二:声明模块与工程名

新增或确认模块时,在 ATTConnect/settings.gradle.kts 中维护:

rootProject.name = "BluetoothDemo"
include(":app")

来源:ATTConnect/settings.gradle.kts(节选)

rootProject.name 独立于目录名设计,使客户把 ATTConnect/ 复制重命名后(如 MyBluetoothDemo/)工程显示名依然稳定。

示例三:引入本地蓝牙 SDK

在 :app 模块的 dependencies 块中引入 libs/ 下的 AAR:

dependencies {
    implementation(fileTree(Pair("include", "*.aar"), Pair("dir", "libs")))
}

来源:ATTConnect/app/build.gradle.kts(节选)

该写法将 app/libs/ 目录下所有 .aar 一次性纳入编译,升级 SDK 只需替换文件并重新同步。

配置项

以下配置均来源于仓库内实际文件(README 与 Gradle 脚本):

配置项类型默认值/当前值说明
最低 Android 版本系统要求Android 5.0(API 21)仓库支持的设备下限
目标 Android 版本系统要求Android 16+(API 36+)编译与运行目标
开发语言系统要求Kotlin / Java示例以 Java 实现(com.jieli.bt.att 下为 .java 文件)
rootProject.nameGradleBluetoothDemo示例工程显示名称
模块列表Gradle:app当前唯一模块
SDK 依赖方式Gradlelibs/*.aar 本地文件implementation(fileTree(...)) 引入
远程仓库策略Gradle仅放行 com.android.*、com.google.*、androidx.*includeGroupByRegex 白名单
支持协议功能GATT over BR/EDR(ATT)、GATT over BLE当前示例侧重 ATT

说明:compileSdk / minSdk / targetSdk 的具体数值声明位于 ATTConnect/app/build.gradle.kts 的 android {} 块中;由于本次取证未展开该文件全部内容,上表以 README 声明的系统要求为准。详细配置请直接查看 app/build.gradle.kts。

失败模式与边界情况

  • ATT 协议兼容性风险:README 明确提示「Android 端对 ATT(GATT over BR/EDR)功能的支持可能存在兼容性问题,建议在目标设备上进行充分测试」。因此工程将蓝牙操作全部抽象到 interfaces/,正是为了在系统行为不一致时能够替换底层实现而不用改动上层。
  • 异步回调丢失:扫描/连接/写入均为异步回调,若上层在回调到达前销毁(如页面退出),BleEventCallbackManager 需要保证监听器解绑,避免空引用或事件泄漏——这是所有管理器类共有的边界约束。
  • 并发写入冲突:Android GATT 不保证并发写安全,工程以 SendBleDataThread 串行化写操作规避;若上层绕过该线程直接写,可能触发 GattStatus 写入失败。
  • 依赖解析边界:settings.gradle.kts 用正则白名单限制远程仓库,若未来引入非 Google/AndroidX 的远程依赖(如第三方 Maven 库),需要显式补充放行规则,否则同步失败。

扩展点

  1. 新增示例工程:在仓库根目录新建独立目录(如 BleConnect/),复制 ATTConnect 的工程骨架(settings.gradle.kts、app/),保持「一目录一工程」约定即可,无需改动现有示例。
  2. 替换/扩展蓝牙实现:interfaces/ 下的 IBleOp、IBleEventCallback、IBtScanCallback 等接口即接缝;若要支持新的传输类型或自定义协议栈,实现这些接口并在 BleManager 中切换即可。
  3. 升级 SDK:替换 app/libs/*.aar 文件,Gradle 同步后自动生效;CHexConver、UuidUtil 等工具类可保持稳定,降低升级成本。
  4. 增加模块:若将 SDK 封装抽取为独立库,在 settings.gradle.kts 追加 include(":sdk"),并在 :app 中声明项目依赖。

相关链接

  • README.md(仓库总览与快速开始)
  • ATTConnect/settings.gradle.kts(模块声明与仓库策略)
  • ATTConnect/app/build.gradle.kts(模块配置与依赖)
  • BleManager.java(能力层入口)
  • interfaces 回调接口目录
  • ATTConnect 详细说明(示例级文档,见 README 引用)

注:能力层(tool.ble)中各类的具体方法签名与调用时序,请参阅 BLE 连接管理与数据收发相关目录页;本页仅从工程结构与分层角度进行说明。

Next
核心类与回调接口