错误码参考
本文档汇总 Android-JL_Bluetooth 工程中出现的错误码定义与错误处理约定,涵盖应用层自定义错误码(SConstant)、SDK 层错误码(com.jieli.bluetooth.constant.ErrorCode)及设备回复状态码的使用方式。
Purpose and Scope
本页面面向接入杰理 RCSP 蓝牙 SDK 的开发者,集中说明:
- 应用层(btsmart 模块)自定义的连接类错误码(定义于
SConstant); - SDK 层
ErrorCode错误码常量与BaseError错误对象的用法(通过工程内 demo/test 代码实证); - 设备回复状态码(
StateCode.STATUS_SUCCESS)与错误码的配合判断逻辑; - 错误码如何通过回调(
onErrCode、onInit的 state 等)从设备端一路传递到业务层。
注意:
com.jieli.bluetooth.constant.ErrorCode与com.jieli.bluetooth.bean.base.BaseError属于外部 SDK(以 aar 形式提供),其完整常量表不在本仓库源码中。本页只收录仓库内可实证的错误码与使用约定;完整 SDK 常量表请以 SDK 文档/反编译的 aar 为准。设备协议相关的透传错误码(如设备回复的业务错误码)属于设备端协议范畴,不在本页展开。
Overview
在 RCSP 蓝牙控制链路中,错误可能发生在多个层次:
- 应用层前置检查失败——例如设备正在连接、蓝牙未开启、EDR 连接数已达上限。这类错误由应用自身定义(
SConstant中的ERR_*常量),用于连接流程的快速失败判断。 - SDK 层协议交互失败——例如设备回复的状态码非成功、回复数据为空或格式错误。SDK 使用
ErrorCode.SUB_ERR_*常量构造BaseError对象,并通过onErrCode回调上报。 - 设备端状态异常——RCSP 命令回复中携带设备状态码,应用需与
StateCode.STATUS_SUCCESS比对,不一致即视为业务异常。
错误码的取值分为两大体系:0xe0xx 形式的应用层自定义错误码,以及 SDK 内部使用的 SUB_ERR_* 子错误码。二者都会最终包装进 BaseError(含 subCode 与 message)传递给上层回调。
Architecture
下图展示错误码的产生、包装与传递链路:
flowchart TD
subgraph sg_Device["设备端"]
Dev["蓝牙设备<br/>(回复状态码/异常数据)"]
end
subgraph sg_Sdk["SDK 层 (com.jieli.bluetooth)"]
StateCode["StateCode<br/>STATUS_SUCCESS 等"]
ErrorCode["ErrorCode<br/>SUB_ERR_* 常量"]
BaseError["BaseError<br/>subCode + message"]
end
subgraph sg_App["应用层 (btsmart)"]
SConstant["SConstant<br/>ERR_DEV_CONNECTING 等"]
Callback["错误回调<br/>onErrCode / onInit(state)"]
Demo["业务代码 / Demo"]
end
Dev -->|"回复命令与状态"| StateCode
StateCode -->|"状态 != STATUS_SUCCESS"| ErrorCode
ErrorCode -->|"构造错误对象"| BaseError
BaseError -->|"错误码+描述上报"| Callback
Callback --> Demo
SConstant -->|"连接前置检查失败"| Callback
各节点职责说明:
- 设备端:对 RCSP 命令返回响应,响应中携带状态码(
StateCode)。当设备端自身逻辑异常时,会返回非STATUS_SUCCESS的状态。 - StateCode:SDK 定义的回复状态常量。业务代码通过
cmd.getStatus() != StateCode.STATUS_SUCCESS判断设备回复是否异常(见 BtRcspControlDemo.java)。 - ErrorCode:SDK 层子错误码常量(如
SUB_ERR_RESPONSE_BAD_STATUS、SUB_ERR_DATA_FORMAT),用于标识 SDK 侧检测到的错误类型。 - BaseError:统一错误载体,携带
subCode(错误码)与message(错误描述),通过回调传给上层。 - SConstant:应用层自定义的
0xe0xx系列错误码,用于蓝牙连接场景的前置校验。 - Demo/业务代码:消费错误码,依据错误码决定提示文案与后续流程(重试、跳转设置页等)。
应用层错误码(SConstant)
应用层在 SConstant 中定义了三个与蓝牙连接流程相关的错误码,均以 0xe0xx 形式命名,用于区分不同连接失败原因:
//error code
public final static int ERR_DEV_CONNECTING = 0xe001;
public final static int ERR_BLUETOOTH_NOT_ENABLE = 0xe002;
public final static int ERR_EDR_MAX_CONNECTION = 0xe003;
Source: SConstant.java
| 常量名 | 值 | 含义 | 典型触发场景 |
|---|---|---|---|
ERR_DEV_CONNECTING | 0xe001 | 设备正在连接中 | 对已处于连接流程的设备再次发起连接 |
ERR_BLUETOOTH_NOT_ENABLE | 0xe002 | 蓝牙未开启 | 系统蓝牙开关关闭时尝试连接 |
ERR_EDR_MAX_CONNECTION | 0xe003 | EDR 连接数已达上限 | 经典蓝牙(EDR)并发连接数超过设备能力 |
设计意图:这些错误码把「连接动作无法开始」的前置条件失败与「连接过程中的协议失败」区分开。前置失败不需要与设备交互,由应用层直接判断并快速返回,避免向 SDK 发起无效连接请求,也便于 UI 层给出针对性提示(如引导用户开启蓝牙)。
SDK 层错误码体系(ErrorCode / BaseError)
SDK 层错误码定义在 com.jieli.bluetooth.constant.ErrorCode,错误对象为 com.jieli.bluetooth.bean.base.BaseError。两者均来自外部 SDK(aar),仓库内通过 demo 代码可实证以下常量与用法:
| 常量名 | 含义 | 实证位置 |
|---|---|---|
ErrorCode.SUB_ERR_RESPONSE_BAD_STATUS | 设备回复状态异常 | BtRcspControlDemo.java |
ErrorCode.SUB_ERR_DATA_FORMAT | 回复数据格式错误/为空 | BtRcspControlDemo.java |
BaseError 对象通过回调对外暴露两个读取接口(注释实证于 ChargingCaseDemo.java):
error.getSubCode()—— 返回错误码(int)error.getMessage()—— 返回错误描述(String)
设备回复状态码(StateCode)
RCSP 命令回复对象携带 status 字段,业务层必须用 StateCode.STATUS_SUCCESS 校验。这是错误码体系中最先触发的判断点:状态码不合格即终止流程,不再解析数据。
if (cmd.getStatus() != StateCode.STATUS_SUCCESS) { //设备状态异常,进行异常处理
onErrCode(device, new BaseError(ErrorCode.SUB_ERR_RESPONSE_BAD_STATUS, "Device reply an bad status: " + cmd.getStatus()));
return;
}
Source: BtRcspControlDemo.java
设计意图:将「状态校验」与「数据解析」解耦——设备回复的业务状态决定命令是否成功,而 SUB_ERR_DATA_FORMAT 等错误码只在状态通过后仍发现数据异常时使用。这样上层可以根据错误码归属(协议状态 vs 数据内容)分别处理。
错误回调约定
错误码通过多种回调形态暴露,仓库内可实证的形态包括:
onErrCode(device, BaseError)回调:通用错误回调,携带BaseError(见 BtRcspControlDemo.java)。- 初始化回调的 state 参数:
onInit(BluetoothDevice device, int state)中0表示成功,其他数值即错误码(见 ChargingCaseDemo.java)。 - 大文件传输回调:以
code(错误码)与message(错误描述)成对返回(见 FileOpDemo.java)。
错误码判定流程
flowchart TD
Start([发起RCSP操作]) --> Pre{"应用层前置检查"}
Pre -->|"失败: 蓝牙未开启/连接中/EDR满"| E1["返回 SConstant ERR_* 错误码"]
Pre -->|"通过"| Send["向设备发送命令"]
Send --> Resp{"收到设备回复"}
Resp -->|"无回复/数据为空"| E2["SUB_ERR_DATA_FORMAT<br/>BaseError上报"]
Resp -->|"有回复"| Status{"status == STATUS_SUCCESS?"}
Status -->|"否"| E3["SUB_ERR_RESPONSE_BAD_STATUS<br/>BaseError上报"]
Status -->|"是"| Parse["解析业务数据"]
Parse --> OK["业务成功回调"]
E1 --> End([结束])
E2 --> End
E3 --> End
OK --> End
判定顺序说明:错误处理遵循「前置 → 协议 → 数据」的严格顺序。应用层前置检查最先执行(失败即返回 0xe0xx);随后 SDK 等待设备回复,无回复或回复为空时产生数据格式错误;有回复则先校验 status,再进入数据解析。这样每一层只对自己负责的错误给出精确的错误码,避免错误码含义模糊。
Core Flow:错误码传递时序
sequenceDiagram
participant App as 应用/业务代码
participant SDK as SDK (RCSPController)
participant Dev as 蓝牙设备
App->>SDK: 发起 RCSP 命令操作
SDK->>Dev: 下发命令
Dev-->>SDK: 回复命令(含 status 与数据)
alt 回复状态 != STATUS_SUCCESS
SDK-->>App: onErrCode(BaseError(SUB_ERR_RESPONSE_BAD_STATUS, "bad status"))
else 回复数据为 null
SDK-->>App: onErrCode(BaseError(SUB_ERR_DATA_FORMAT, "Response data is error."))
else 状态与数据均正常
SDK-->>App: onSuccess / 业务数据回调
end
App->>App: 依据 error.getSubCode() 分支处理<br/>提示文案 / 重试 / 跳转设置
时序要点:
- 业务层调用 SDK 操作接口后,命令经 RCSP 通道下发至设备;
- 设备回复后,SDK 先检查
status,再检查数据完整性; - 任一步骤失败,SDK 都构造
BaseError(subCode+message)并通过onErrCode上报,业务层在回调内用error.getSubCode()与error.getMessage()区分错误并决策后续动作; - 全部通过才进入成功回调。错误路径与成功路径严格分离,保证业务层不会在错误状态下处理半截数据。
Usage Examples
示例一:校验设备回复状态并构造错误
设备回复状态异常时,终止流程并上报 SUB_ERR_RESPONSE_BAD_STATUS;回复数据为空时上报 SUB_ERR_DATA_FORMAT:
if (cmd.getStatus() != StateCode.STATUS_SUCCESS) { //设备状态异常,进行异常处理
onErrCode(device, new BaseError(ErrorCode.SUB_ERR_RESPONSE_BAD_STATUS, "Device reply an bad status: " + cmd.getStatus()));
return;
}
//...
if (null == response) {
onErrCode(device, new BaseError(ErrorCode.SUB_ERR_DATA_FORMAT, "Response data is error."));
return;
}
Source: BtRcspControlDemo.java
该模式揭示了两个要点:错误码应当携带上下文(将设备返回的原始 status 拼入 message 便于排查),且出现错误后应 return 立即终止,避免继续执行后续解析。
示例二:初始化回调中按 state 区分成功与错误
onInit 回调的 state 参数中,0 表示成功,其他数值为错误码:
@Override
public void onInit(BluetoothDevice device, int state) {
//回调初始化状态
//0 --- 成功
//其他数值为错误码, 参考【错误码】章节
}
Source: ChargingCaseDemo.java
示例三:从错误回调中读取错误码与描述
操作失败时统一通过错误回调返回 BaseError,业务侧按 getSubCode() / getMessage() 读取:
//回调操作失败 和 错误信息
//error.getSubCode() --- 错误码
//error.getMessage() --- 错误描述
Source: ChargingCaseDemo.java
大文件传输场景采用同样的「错误码 + 错误描述」成对回调约定:
//回调大文件传输异常
//code --- 错误码
//message --- 错误描述
Source: FileOpDemo.java
API Reference
BaseError.getSubCode(): int
返回错误码(子错误码)。业务层用它做错误分支判断(如区分 SUB_ERR_RESPONSE_BAD_STATUS 与 SUB_ERR_DATA_FORMAT)。
Returns: 错误码整数值(ErrorCode.SUB_ERR_* 或设备/应用自定义错误码)。
BaseError.getMessage(): String
返回人类可读的错误描述,通常附带触发错误的上下文信息(如设备返回的原始状态值)。
Returns: 错误描述字符串,可用于日志与 UI 提示。
注:
BaseError类位于外部 SDK(com.jieli.bluetooth.bean.base.BaseError),本仓库不包含其源码;以上签名由 demo 注释实证(ChargingCaseDemo.java)。
错误回调签名(仓库内实证)
| 回调 | 错误载体 | 说明 |
|---|---|---|
onErrCode(BluetoothDevice device, BaseError error) | BaseError | 通用 RCSP 操作错误回调 |
onInit(BluetoothDevice device, int state) | int state | 初始化结果:0 成功,其余为错误码 |
| 大文件传输异常回调 | code + message | 成对返回错误码与描述 |
Failure Modes、边界情况与并发
设备回复状态异常(bad status)
设备端逻辑异常时返回非 STATUS_SUCCESS 状态。处理要点:必须在解析数据之前校验状态并 return,否则可能把错误状态下的数据当作正常业务数据处理。
回复数据为空 / 格式错误
命令有响应但数据为 null 或格式不合法时,上报 SUB_ERR_DATA_FORMAT。这类错误往往由固件版本不一致、协议不匹配引起,排查时优先核对 SDK 版本与设备固件版本的兼容性。
应用层连接前置失败
0xe001(连接中)、0xe002(蓝牙未开启)、0xe003(EDR 连接数上限)属于应用层快速失败错误,不涉及设备交互。UI 层应对这三类错误给出差异化引导:开启蓝牙、等待连接完成、断开其他 EDR 设备。
回调时机与并发
RCSP 命令采用请求-响应模型,错误回调与成功回调互斥;业务层不应在收到 onErrCode 后继续访问预期数据。多命令并发场景下,回调携带 device 参数用于区分设备,处理多设备时应以 device 为准做上下文隔离,避免串号。
使用建议与扩展说明
- 错误码即契约:新增业务功能时,优先复用
ErrorCode.SUB_ERR_*与StateCode.STATUS_SUCCESS既有约定;应用自定义错误沿用0xe0xx区段并保持注释,避免与 SDK 常量冲突。 - 上下文入 message:构造
BaseError时将原始状态值、设备信息拼入 message(见 BtRcspControlDemo.java),便于线上问题定位。 - 统一错误出口:SDK 交互统一经
onErrCode/BaseError出口,业务层在出口处集中做错误码到提示文案的映射,避免散落判断。 - 完整常量表:
ErrorCode的完整常量清单位于外部 SDK aar,不在本仓库;如需全量表格,请解包 SDK aar 或查阅 SDK 发布文档。
Related Links
- SConstant.java — 应用层错误码定义
- BtRcspControlDemo.java — 状态校验与错误构造示例
- ChargingCaseDemo.java — onInit state 与 BaseError 读取示例
- FileOpDemo.java — 大文件传输错误码回调
- 相关主题:RCSP 控制流程(设备状态码校验)、充电仓功能开发(初始化 state 错误码)、文件传输(大文件异常回调)