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

    • 项目简介与核心能力
    • 运行环境与SDK版本
  • 快速开始

    • 工程导入与依赖配置
    • 权限配置与示例运行
  • 平台架构

    • SDK分层架构与RCSP协议
    • 蓝牙连接库
    • 健康SDK核心库 JL_Watch
    • 健康服务器与云端服务
  • 健康与运动数据

    • 健康数据同步
    • 运动数据同步
    • 本地数据持久化
  • 设备管理功能

    • 表盘管理
    • 闹钟与健康提醒
    • 消息与联系人同步
    • 天气同步
    • 设备查找
    • 支付宝集成
  • 传输与媒体处理

    • 文件传输与文件管理
    • 音乐传输与播放控制
    • 图像转换库
    • 音频编解码与解密
  • OTA 升级

    • 固件空中升级流程
    • 4G模块与差分升级
  • AI 能力

    • AI表盘与云服务
    • AI语音助手
  • 示例应用

    • HealthAide 健康助手应用
    • WatchTestTool 测试工具
  • 开发者指南

    • 自定义命令扩展
    • 调试技巧与问题排查
    • 版本历史与兼容性

AI语音助手

AI语音助手(AI Voice Assistant)是 HealthAide 健康助手 App 中基于讯飞(iFlytek)AI 能力与 RCSP 蓝牙协议构建的语音交互子系统,负责语音识别(ASR/IAT)、大模型对话(Chat/SparkChain)、语音合成(TTS)以及 AI 表盘(AI Dial)的端云协同,让用户通过语音与智能手表完成健康问答与交互。

Purpose and Scope

本页面聚焦于 com.jieli.healthaide.tool.aiui 包及其数据层、配置资源,覆盖:

  • AI 能力编排核心:AIManager 门面类如何协调 IAT(语音识别)、Chat(星火大模型对话)、TTS(语音合成)三条 AI 管线;
  • Handler 任务体系:BaseAIHandler 抽象基类及其派生的对话、云端服务、AI 表盘、语音识别四类处理器;
  • 讯飞封装层:IflytekChatWrapper / IflytekIatWrapper / IflytekTtsWrapper / IflytekAIDialStyleHelper;
  • 手表侧 RCSP 通道:AIDialWrapper / AIRecordWrapper / AICloudServeWrapper 及监听器;
  • 消息持久化:AICloudMessageEntity / AICloudMessageDao;
  • 资源与依赖:aiui_phone.cfg 与 SparkChain SDK。

以下内容属于相邻页面、不在本页展开:蓝牙连接管理(RCSP 协议基础)见「WatchManager / RCSP 通信」相关页面;健康数据采集与命令处理见「健康数据」相关页面;App 整体启动流程见「HealthApplication」相关页面。

Overview

AI 语音助手的核心设计意图是:让手表端的语音交互能力由手机端代为完成。智能手表受限于算力、功耗与存储,无法本地运行大模型,因此 HealthAide App 通过蓝牙 RCSP 通道接收手表端录制的语音数据(AIRecordWrapper),在手机端完成三阶段处理:

  1. 听(Listen):IflytekIatWrapper 将录音转为文本(ASR / IAT,Speech-to-Text);
  2. 想(Think):IflytekChatWrapper 基于讯飞星火大模型(SparkChain SDK)生成回答文本;
  3. 说(Speak):IflytekTtsWrapper 将回答文本合成为语音(TTS,Text-to-Speech),再经 RCSP 通道回传手表播放。

同时,系统还支持 AI 表盘(AI Dial) 场景:当手表进入 AI 表盘界面(设备通知 state == 1)时,AIManager 自动启动录音处理,将 IAT 识别结果直接路由给 AIDialHandler 进行对话式问答,并在设备退出表盘(state == 0)时停止处理并清理等待弹窗。

整个子系统采用「门面 + 策略处理器」架构:AIManager 是唯一对外门面,持有具体实现类;BaseAIHandler 体系定义了任务边界;后续接入其他 AI 供应商时只需新增 BaseAIHandler 的实现类并替换 AIManager 中的装配即可,体现了面向接口编程与策略模式的设计意图。

Architecture

下图展示了 AI 语音助手子系统的整体架构与数据流:

flowchart TD
    subgraph sg_Device["手表端 (BLE 对端)"]
        Watch["智能手表<br/>AI 表盘 / 录音 / 播放"]
    end

    subgraph sg_App["HealthAide App (手机端)"]
        subgraph sg_Entry["入口层"]
            HealthApp["HealthApplication.onCreate<br/>IflytekAIDialStyleHelper.init"]
        end

        subgraph sg_Facade["门面层"]
            AIManager["AIManager<br/>AI 管理门面"]
        end

        subgraph sg_Handler["任务处理器层 (handle 包)"]
            BaseAIHandler["BaseAIHandler (抽象基类)"]
            IatHandler["BaseAIIatHandler<br/>IflytekAIIatHandler (语音识别)"]
            ChatHandler["BaseAIChatHandler (对话基类)"]
            DialHandler["BaseAIDialHandler<br/>IflytekAIDialHandler (AI 表盘对话)"]
            CloudHandler["BaseAICloudServeHandler<br/>IflytekAICloudServeHandler (云端服务)"]
        end

        subgraph sg_Iflytek["讯飞 AI 封装层 (iflytek 包)"]
            IatWrapper["IflytekIatWrapper (ASR 识别)"]
            ChatWrapper["IflytekChatWrapper (星火大模型)"]
            TtsWrapper["IflytekTtsWrapper (TTS 合成)"]
            DialStyle["IflytekAIDialStyleHelper (表盘风格)"]
        end

        subgraph sg_Rcsp["RCSP 通道封装层 (rcsp 包)"]
            RecordWrapper["AIRecordWrapper (录音数据)"]
            DialWrapper["AIDialWrapper + AIDialListener (AI 表盘)"]
            CloudWrapper["AICloudServeWrapper + Listener (云端服务)"]
        end

        subgraph sg_Data["数据层"]
            Entity["AICloudMessageEntity"]
            Dao["AICloudMessageDao"]
        end
    end

    subgraph sg_Cloud["云端服务"]
        Spark["讯飞星火大模型 (SparkChain)"]
        IflyCloud["讯飞 AIUI 云端"]
    end

    Watch -->|"BLE / RCSP 录音数据"| RecordWrapper
    RecordWrapper --> IatHandler
    IatHandler --> IatWrapper
    IatWrapper -->|"文本"| ChatHandler
    ChatHandler --> ChatWrapper
    ChatWrapper -->|"对话文本"| Spark
    ChatHandler --> DialHandler
    DialHandler --> TtsWrapper
    TtsWrapper -->|"合成语音"| DialWrapper
    DialWrapper -->|"RCSP 回传"| Watch
    CloudHandler --> CloudWrapper
    CloudWrapper --> IflyCloud
    CloudHandler --> Entity
    Entity --> Dao

    HealthApp --> AIManager
    AIManager --> IatHandler
    AIManager --> ChatHandler
    AIManager --> DialHandler
    AIManager --> CloudHandler
    AIManager --> RecordWrapper
    AIManager --> DialWrapper
    AIManager --> CloudWrapper
    AIManager --> DialStyle
    BaseAIHandler <|-- IatHandler
    BaseAIHandler <|-- DialHandler
    BaseAIHandler <|-- CloudHandler
    BaseAIHandler <|-- ChatHandler

架构分层说明

层次关键类职责
入口层HealthApplication应用启动时调用 IflytekAIDialStyleHelper.init(this) 初始化 AI 表盘风格助手(见 HealthApplication.java)
门面层AIManager持有所有 AI 组件实例,监听设备状态事件,编排录音→识别→对话→合成→回传的完整链路
任务处理器层BaseAIHandler 及四个派生类定义 AI 任务生命周期(release()、isConnected()),按业务域拆分处理器
讯飞封装层Iflytek*Wrapper直接调用讯飞 SDK(IAT/星火/TTS),屏蔽供应商 API 差异
RCSP 通道层AIDialWrapper 等通过 WatchManager 与手表交换录音、表盘状态、云端服务数据
数据层AICloudMessageEntity/Dao云端服务消息的本地持久化

设计意图分析

  • 门面模式(Facade):AIManager 是 UI/Service 层访问 AI 能力的唯一入口,屏蔽了讯飞 SDK 与 RCSP 协议的复杂度;
  • 策略模式(Strategy):BaseAIHandler 抽象出任务契约,Iflytek* 是讯飞策略实现,未来可替换为其他供应商而不影响调用方;
  • 关注点分离:讯飞封装(iflytek 包)与 RCSP 通道(rcsp 包)相互独立,由 AIManager 在中间装配,降低供应商 SDK 与设备协议之间的耦合。

主内容:核心实现详解

AIManager —— AI 能力编排门面

AIManager(类注释描述为"AI管理",作者 ZhangHuanMing,创建于 2023/9/18)是子系统的核心门面,通过组合持有全部 AI 组件:

public class AIManager {
    private static final String TAG = "AIManager";
    private Context mContext;
    private WatchManager mRcspOp;
    private IflytekChatWrapper mIflytekChatWrapper;   // 星火大模型对话
    private IflytekTtsWrapper mIflytekTtsWrapper;     // 语音合成
    private IflytekIatWrapper mIflytekIatWrapper;     // 语音识别
    private AIRecordWrapper mAIRecordWrapper;         // 手表录音数据
    private AICloudServeWrapper mAICloudServeWrapper; // 云端服务
    private AIDialWrapper mAIDialWrapper;             // AI 表盘通道
    private BaseAIIatHandler mAIIatHandler;           // 识别任务
    private BaseAICloudServeHandler mAICloudServeHandler; // 云端任务
    private BaseAIDialHandler mAIDialHandler;         // AI 表盘对话任务
    private TransferWaitingDialog waitingDialog;//断开的时候要更新
    private boolean isTransferring = false;
    private boolean mIsAIDialRunning = false;
    ...
}

Source: AIManager.java

字段分四类,清晰映射到四条职责线:

字段组字段职责线
讯飞 AI 能力mIflytekChatWrapper / mIflytekTtsWrapper / mIflytekIatWrapper听 / 想 / 说三条 AI 管线
RCSP 设备通道mAIRecordWrapper / mAICloudServeWrapper / mAIDialWrapper与手表的蓝牙数据交换
任务处理器mAIIatHandler / mAICloudServeHandler / mAIDialHandler各业务域的处理逻辑
状态与 UIwaitingDialog / isTransferring / mIsAIDialRunning传输等待弹窗与 AI 表盘运行状态

设计意图:mIsAIDialRunning 与 isTransferring 两个布尔状态是并发防护的关键——isTransferring 标记缩略图/表盘文件传输中,避免与 AI 对话流程互相打断;mIsAIDialRunning 标记 AI 表盘会话是否激活,控制录音处理开关。

AI 表盘状态机(AIDialListener)

AIManager 内部通过匿名内部类 AIDialListener 监听设备端 AI 表盘界面状态变化,这是整个语音助手的核心驱动事件:

private final AIDialListener mAIDialListener = new AIDialListener() {
    @Override
    public void onDevNotifyAIDialUIChange(int state) {
        super.onDevNotifyAIDialUIChange(state);
        if (state == 0) {//退出AI表盘界面
            JL_Log.d(TAG, "onDevNotifyAIDialUIChange", "退出AI表盘界面");
            mAIRecordWrapper.stopHandleRecord();//取消处理AI录音数据
            if (waitingDialog != null && !isTransferring) {
                waitingDialog.dismiss();
            }
            mIsAIDialRunning = false;
        } else if (state == 1) {//进入AI表盘界面
            JL_Log.d(TAG, "onDevNotifyAIDialUIChange", "进入AI表盘界面");
            mAIRecordWrapper.startHandleRecord();//开始处理AI录音数据
            mAIIatHandler.setAIChatHandler(mAIDialHandler);
            mIsAIDialRunning = true;
            if (waitingDialog == null) {
                waitingDialog = new TransferWaitingDialog();
            }
            if (!waitingDialog.isShow() && !waitingDialog.isAdded()) {
                AppCompatActivity appCompatActivity = (AppCompatActivity) ActivityManager.getInstance().getCurrentActivity();
                FragmentManager fragmentManager = appCompatActivity.getSupportFragmentManager();
                waitingDialog.show(fragmentManager, waitingDialog.getClass().getCanonicalName());
            }
        }
    }
    ...
};

Source: AIManager.java

关键行为拆解:

  1. state == 1(进入 AI 表盘):调用 mAIRecordWrapper.startHandleRecord() 开始处理录音数据;调用 mAIIatHandler.setAIChatHandler(mAIDialHandler) 将识别结果动态路由到 AI 表盘对话处理器——这是识别与对话解耦的挂接点;随后弹出 TransferWaitingDialog 等待弹窗(复用 ActivityManager 获取当前 Activity 与 FragmentManager)。
  2. state == 0(退出 AI 表盘):stopHandleRecord() 停止录音处理,条件性地关闭弹窗(!isTransferring 保证传输进行中不打断),并将 mIsAIDialRunning 置回 false。

同监听器还处理传输与安装事件:

@Override
public void onTransferThumbStart() {
    super.onTransferThumbStart();
    isTransferring = true;
    if (waitingDialog != null) {
        waitingDialog.updateText(mContext.getString(R.string.transfer_ing));
    }
}

@Override
public void onTransferThumbFinish(boolean isSuccess) {
    super.onTransferThumbFinish(isSuccess);
    isTransferring = false;
    if (waitingDialog != null) {
//                waitingDialog.updateText("AI表盘对话中...");
    }
}

@Override
public void onInstallDialStart() {
    super.onInstallDialStart();
    isTransferring = true;
    if (waitingDialog != null) {
        waitingDialog.updateText(mContext.getString(R.string.transfer_ing));
    }
}

@Override
public void onInstallDialFinish(boolean isSuccess) {
    super.onInstallDialFinish(isSuccess);
    isTransferring = false;
    if (waitingDialog != null) {
//                waitingDialog.updateText("AI表盘对话中...");
    }
}

Source: AIManager.java

设计意图:表盘缩略图(Thumb)与表盘安装(Install Dial)是耗时传输操作,期间 UI 文案更新为 R.string.transfer_ing("传输中"),并用 isTransferring 标志防止传输期间 AI 会话弹窗被误关闭——这是典型的异步任务互斥保护。

BaseAIHandler —— 任务基类契约

所有 AI 任务处理器继承自抽象基类 BaseAIHandler,定义了两项核心契约:

public abstract class BaseAIHandler {
    protected final String TAG = this.getClass().getSimpleName();
    protected WatchManager mRcspOp;
    protected Context mContext;
    public BaseAIHandler(WatchManager rcspOp, Context context) {
        mRcspOp = rcspOp;
        mContext = context;
    }

    public void release() {
    }

    protected boolean isConnected() {
        return mRcspOp.isConnected();
    }
}

Source: BaseAIHandler.java

  • 构造注入:统一注入 WatchManager(RCSP 蓝牙操作对象)与 Context,保证所有子类都能访问设备通道;
  • release():默认为空实现,子类按需覆写释放 AI 资源(如取消识别、断开会话)——这是生命周期管理的扩展点;
  • isConnected():委托给 WatchManager.isConnected(),子类在执行 AI 任务前可用它做连接前置校验,避免蓝牙断开时误操作。

Handler 派生体系

从 BaseAIHandler 派生出四条业务线(位于 tool/aiui/handle/ 包):

抽象基类讯飞实现类职责
BaseAIIatHandlerIflytekAIIatHandler语音识别(IAT),将录音流转换为文本;通过 setAIChatHandler(...) 支持把识别结果交给不同的对话处理器
BaseAIChatHandler(供 Dial/Cloud 复用)AI 对话通用逻辑,定义聊天请求的公共处理流程
BaseAIDialHandlerIflytekAIDialHandlerAI 表盘场景对话:接收 IAT 文本 → 调用星火大模型 → 返回回答
BaseAICloudServeHandlerIflytekAICloudServeHandler云端服务:与 AICloudServeWrapper 协同处理手表侧发起的云端功能请求

设计意图:BaseAIIatHandler.setAIChatHandler(...) 是"识别结果路由器"——同一套录音识别管线可把文本喂给不同下游(AI 表盘对话或普通聊天),无需复制识别逻辑;这正是 AIManager 在 state == 1 时调用 mAIIatHandler.setAIChatHandler(mAIDialHandler) 的原因。

Core Flow:AI 表盘语音对话全流程

以下时序图展示了从手表端进入 AI 表盘到语音回答回传的完整端到端流程:

sequenceDiagram
    participant Watch as 智能手表 (AI 表盘)
    participant RCSP as RCSP 通道 (AIDialWrapper/AIRecordWrapper)
    participant AM as AIManager
    participant IAT as BaseAIIatHandler/IflytekIatWrapper
    participant CHAT as IflytekChatWrapper (星火大模型)
    participant TTS as IflytekTtsWrapper
    participant DIAL as BaseAIDialHandler

    Watch->>RCSP: 进入 AI 表盘 (通知 state=1)
    RCSP->>AM: onDevNotifyAIDialUIChange(1)
    AM->>AM: startHandleRecord() + setAIChatHandler(mAIDialHandler)
    AM->>AM: 弹出 TransferWaitingDialog
    Watch->>RCSP: 录音数据流 (BLE)
    RCSP->>IAT: 语音数据 (AIRecordWrapper)
    IAT->>IAT: ASR 识别为文本
    IAT->>DIAL: 文本 (setAIChatHandler 路由)
    DIAL->>CHAT: 请求回答
    CHAT->>CHAT: 星火大模型生成回答
    CHAT-->>DIAL: 回答文本
    DIAL->>TTS: 合成语音
    TTS->>RCSP: 语音数据 (AIDialWrapper)
    RCSP->>Watch: RCSP 回传语音播放
    Watch->>RCSP: 退出 AI 表盘 (通知 state=0)
    RCSP->>AM: onDevNotifyAIDialUIChange(0)
    AM->>AM: stopHandleRecord() + 关闭弹窗

步骤分解

  1. 进入会话:手表端切换至 AI 表盘界面,通过 RCSP 通知手机端 state=1;AIManager 的 AIDialListener 收到事件后开启录音处理管线,并将 IAT 输出路由到 AIDialHandler,同时展示"等待/传输中"弹窗;
  2. 语音上行:手表采集用户语音,AIRecordWrapper 通过蓝牙持续接收录音数据;
  3. 识别:IflytekIatWrapper(讯飞 IAT/ASR)将录音转写为文本;
  4. 对话:文本经 setAIChatHandler 挂接的 BaseAIDialHandler 送入 IflytekChatWrapper(基于 SparkChain 的星火大模型)生成回答;
  5. 合成与回传:回答文本由 IflytekTtsWrapper 合成为语音,经 AIDialWrapper 通过 RCSP 回传手表播放;
  6. 退出会话:手表退出 AI 表盘(state=0),AIManager 停止录音处理、条件性关闭弹窗,重置 mIsAIDialRunning。

注:上述第 2-5 步的调用链由 AIManager 各字段装配关系与 AIDialListener 行为推导,各 Wrapper 内部与讯飞 SDK 交互的细节需结合对应文件进一步确认。

讯飞封装层(iflytek 包)

tool/aiui/iflytek/ 包封装了讯飞三件套与表盘风格助手,是子系统的"AI 引擎室":

类封装的 AI 能力底层 SDK用途
IflytekIatWrapper语音识别(IAT/ASR)讯飞语音听写将手表录音转文本
IflytekChatWrapper大模型对话讯飞星火 SparkChain生成健康问答回答
IflytekTtsWrapper语音合成(TTS)讯飞语音合成将回答文本转语音
IflytekAIDialStyleHelperAI 表盘风格初始化AIUI 配置加载 aiui_phone.cfg,配置表盘 AI 风格

初始化入口

HealthApplication.onCreate() 在应用启动阶段完成 AI 表盘风格助手的初始化,与 CustomDialManager.init(this) 等初始化并列执行:

CustomDialManager.init(this);
IflytekAIDialStyleHelper.init(this);
BaseUnitConverter.setType(ConfigHelper.getInstance().getUnitType());

Source: HealthApplication.java

设计意图:AI 能力采用"启动时静态初始化 + 使用时门面注入"的两段式生命周期——IflytekAIDialStyleHelper.init(this) 在 Application 中尽早完成 AIUI 配置装载(对应资源 assets/cfg/aiui_phone.cfg 与 libs/SparkChain_V2.0.1_rc1.aar),确保后续 AIManager 创建 Wrapper 时可立即使用,避免首帧对话卡顿。

RCSP 通道封装层(rcsp 包)

tool/aiui/rcsp/ 包负责与手表侧的协议交互:

类方向职责
AIRecordWrapper上行接收/处理手表端 AI 录音数据,startHandleRecord() / stopHandleRecord() 控制处理开关
AIDialWrapper + AIDialListener双向AI 表盘通道:上报表盘 UI 状态(onDevNotifyAIDialUIChange)、缩略图传输(onTransferThumbStart/Finish)、表盘安装(onInstallDialStart/Finish)、语音回传
AICloudServeWrapper + AICloudServeWrapperListener双向云端服务通道:承载手表侧发起的云端功能请求/响应

设计意图:RCSP 层与讯飞层严格隔离。协议报文解析(RCSP 命令)只存在于 rcsp 包,AI 业务逻辑只存在于 handle 包,二者通过 AIManager 与 WatchManager(RCSP 操作入口)衔接,这样讯飞 SDK 升级或 RCSP 协议变更不会互相波及。

数据模型与持久化

AI 云端服务消息通过本地数据库持久化:

erDiagram
    AICloudMessageEntity {
        string id PK
        string message
        int type
        long timestamp
    }
  • AICloudMessageEntity(com.jieli.healthaide.data.entity):云端 AI 消息实体,作为 AICloudServeHandler/AICloudServeWrapper 与本地存储之间的数据载体;
  • AICloudMessageDao(com.jieli.healthaide.data.dao):基于 Room 的 DAO 接口,提供云端消息的增删改查能力。

设计意图:云端服务消息落库的意义在于断连续传与历史追溯——蓝牙连接不稳定时,未完成的消息可保留在本地,重连后由 Handler 层继续处理;同时用户可回看历史 AI 问答记录。实体字段的具体定义需查阅 AICloudMessageEntity.java 确认。

资源与依赖

资源路径说明
AIUI 配置app/src/main/assets/cfg/aiui_phone.cfg讯飞 AIUI 手机端配置文件,被 IflytekAIDialStyleHelper 加载
SparkChain SDKapp/libs/SparkChain_V2.0.1_rc1.aar讯飞星火大模型 Android SDK,IflytekChatWrapper 的底层依赖

配置选项

AI 语音助手的能力开关与行为由代码常量、AIUI 配置与 SDK 初始化共同决定,主要可配置项如下:

配置项类型默认值位置说明
aiui_phone.cfg文件assets/cfg/aiui_phone.cfg资源目录讯飞 AIUI 手机端配置(唤醒词、识别参数等),由 IflytekAIDialStyleHelper.init() 加载
SparkChain SDK 版本AARSparkChain_V2.0.1_rc1.aarapp/libs/星火大模型对话能力版本
R.string.transfer_ing字符串资源"传输中…"res/values/strings.xml缩略图/表盘传输等待文案
state 表盘状态值int0=退出,1=进入设备固件协议触发 onDevNotifyAIDialUIChange 的状态语义

说明:AIManager 及各 Handler 未暴露动态参数化配置(未发现 SharedPreferences/ConfigHelper 中对 AI 行为的开关项);AI 具体识别/合成参数均内嵌于讯飞 Wrapper 与 cfg 文件中,具体键值需查阅 aiui_phone.cfg 与对应 Wrapper 源码。

API Reference

AIManager(门面类)

成员类型说明
mAIDialListenerAIDialListener设备 AI 表盘状态/传输/安装事件监听,驱动录音管线开关与弹窗管理
mAICloudServeWrapperListenerAICloudServeWrapperListener云端服务响应监听
mAIIatHandler.setAIChatHandler(handler)BaseAIIatHandler 方法设置识别文本的下游对话处理器(运行时路由)

BaseAIHandler(抽象基类)

public BaseAIHandler(WatchManager rcspOp, Context context)
  • 参数:rcspOp — RCSP 蓝牙操作对象(WatchManager);context — 应用上下文;
  • 说明:所有 AI 任务处理器的统一构造入口,注入设备通道与上下文。
public void release()
  • 说明:释放 AI 资源,默认空实现,子类覆写。在关闭 AI 会话/退出页面时调用。
protected boolean isConnected()
  • 返回:mRcspOp.isConnected() 的结果;
  • 用途:任务执行前的连接前置校验,避免蓝牙断开时向设备发送无效请求。

AIDialListener(接口回调)

回调参数触发时机
onDevNotifyAIDialUIChange(int state)0=退出 AI 表盘,1=进入手表端 AI 表盘界面切换
onTransferThumbStart()—表盘缩略图开始传输
onTransferThumbFinish(boolean isSuccess)是否成功表盘缩略图传输结束
onInstallDialStart()—表盘安装开始
onInstallDialFinish(boolean isSuccess)是否成功表盘安装结束

Failure Modes、边界情况与并发

连接状态异常

BaseAIHandler.isConnected() 提供统一连接检查,但若在蓝牙断开瞬间发起 AI 请求,AIDialWrapper/AIRecordWrapper 的 RCSP 发送会失败。代码中未见显式重试机制——失败处理依赖 RCSP 层的错误回调(JL_Log 日志体系)与上层 TransferWaitingDialog 的状态提示,属于"快速失败 + 用户可见反馈"的策略。

AI 表盘状态与传输互斥

AIManager 用两个布尔状态处理并发:

  • isTransferring:缩略图/表盘安装传输期间置 true,此时即使收到 state=0 退出事件也不会 dismiss 等待弹窗(if (waitingDialog != null && !isTransferring)),防止"退出弹窗打断传输"的竞态;
  • mIsAIDialRunning:标记 AI 表盘会话激活,控制录音处理开关与弹窗展示,避免重复 show 弹窗(!waitingDialog.isShow() && !waitingDialog.isAdded() 双保险)。

弹窗生命周期风险

TransferWaitingDialog 通过 FragmentManager.show() 展示,若宿主 Activity 在弹窗展示期间被销毁(如用户按 Home 或旋转屏幕),可能存在 Fragment 状态丢失风险——代码通过 isAdded()/isShow() 双重判断降低重复添加异常(IllegalStateException)的概率。

语音数据边界

手表录音为持续数据流,若用户长时间说话或录音包过大,AIRecordWrapper 的内存与蓝牙带宽压力上升;退出表盘时 stopHandleRecord() 必须及时调用以释放资源——该调用在 onDevNotifyAIDialUIChange(0) 中同步执行,保证退出即清理。

性能与运维注意

  • 链路延迟:一条语音问答的端到端延迟 = 蓝牙上行传输 + IAT 识别 + 星火生成 + TTS 合成 + 蓝牙下行传输,任一环节超时都会放大体感延迟;TransferWaitingDialog 的"传输中"文案即用于掩盖这一异步等待;
  • AI 资源生命周期:IflytekChatWrapper/IflytekIatWrapper/IflytekTtsWrapper 均在 AIManager 中长期持有,属于重量级对象,不应在页面级频繁创建销毁,应复用门面实例;
  • 依赖 AAR 体积:SparkChain_V2.0.1_rc1.aar 为本地依赖,增大 APK 体积,是 AI 能力上手机端的固有成本。

扩展点

  1. 替换/新增 AI 供应商:实现 BaseAIHandler 的新子类(如 BaiduAIIatHandler),在 AIManager 中替换对应字段装配即可,调用方(UI/Service)无感知;
  2. 新增对话下游:BaseAIIatHandler.setAIChatHandler(...) 允许把同一识别管线路由到任意 BaseAIChatHandler 实现,可扩展"普通聊天""健康咨询"等新场景;
  3. 新增设备侧 AI 功能:仿照 AIDialWrapper 模式新增 RCSP 包装器 + 监听器,并在 AIManager 中装配;
  4. 云端消息扩展:通过 AICloudMessageEntity/AICloudMessageDao 扩展消息类型(type 字段)实现更多云端 AI 服务。

测试情况

仓库中未发现针对 tool/aiui 包的专项单元测试;相关测试文件(ExampleUnitTest、MessageFormatTest、ReceiveHealthDataCmdTest 等)主要覆盖工具类与数据解析逻辑。AI 语音链路依赖真实讯飞 SDK 与蓝牙设备,通常以真机联调验证,单元测试覆盖有限。

Related Links

  • HealthApplication.java(AI 初始化入口)
  • AIManager.java(AI 管理门面)
  • BaseAIHandler.java(任务基类)
  • AICloudMessageEntity.java(云端消息实体)
  • AICloudMessageDao.java(云端消息 DAO)
  • aiui_phone.cfg(AIUI 配置)
  • 相关相邻主题:RCSP 蓝牙通信(WatchManager)、健康数据采集、App 启动流程(HealthApplication)
Prev
AI表盘与云服务