AI翻译
AI翻译(AI Translation)是杰理蓝牙 SDK 应用(btsmart)中基于蓝牙设备 + 云端大模型实现的双向语音/文本翻译能力:设备端录音采集语音,经蓝牙链路回传手机,由 AITranslationImpl 转发至豆包(Doubao)云端翻译服务,再将译文合成音频回传给设备播放,同时将翻译过程持久化到本地 Room 数据库。
Purpose and Scope
本文档介绍 btsmart 中 AI 翻译功能的完整实现链路,涵盖:
- 翻译状态机(
TranslateState)与状态流转 - 逻辑中枢
TranslateViewModel的操作码、依赖与回调 - 设备端翻译能力封装(
TranslationImpl、RecordOpImpl、TranslationMode、AudioData) - 云端 AI 翻译代理(
AITranslationImpl与豆包doubao/translate包:TranslateParam、TranslateAudioParam、TranslateTextParam、请求模型与鉴权) - 翻译记录与会话的本地持久化(
TranslationRepository) - 时间/时长格式化与音频后缀等工具(
TranslateUtil)
与翻译功能平级的其他设备功能(如录音、降噪、EQ 等)不在本文档范围内;蓝牙协议层 TranslationImpl 的底层指令细节亦只做概要说明,详见 SDK 层文档。UI 交互细节(TranslateFragment)仅作入口说明。
Overview
AI 翻译功能解决的核心问题是:在耳机/音箱等低算力设备上实现多语言实时对话翻译。设备本身不具备语音识别与机器翻译能力,因此采用"端-云协同"架构:
- 采集:设备麦克风录音(
RecordOpImpl触发设备录音,OP_DEVICE_RECORD); - 传输:录音音频数据(
AudioData)经蓝牙 RCSP 通道回传到手机; - 云端翻译:
AITranslationImpl将音频/文本以TranslateParam(音频流方式WAY_AUDIO_STREAM或文本方式WAY_TEXT)封装,调用豆包翻译服务; - 回放:译文文本/音频经蓝牙通道下发设备播放;
- 沉淀:翻译记录(
TranslationRecord)与翻译会话(TranslationSession)写入 Room 数据库,支持历史回看。
翻译会话有明确的空闲(STATE_IDLE)/工作中(STATE_WORKING)/暂停(STATE_PAUSE)三种状态,由 TranslateState 枚举表示,TranslateViewModel 通过 MSG_COUNT_WORK_TIME 消息在 Handler 中累计工作时长。
关键概念
| 概念 | 说明 |
|---|---|
TranslationMode | SDK 层翻译模式(如单向/双向等),来自 com.jieli.bluetooth.bean.translation |
AudioData | SDK 层音频数据封装,携带录音 PCM/OPUS 等编码数据 |
TranslationResult | SDK 层翻译结果(译文文本等) |
TranslateState | 应用层翻译状态机:STATE_IDLE / STATE_WORKING / STATE_PAUSE |
AITranslationImpl | 应用层 AI 云翻译代理,负责调用豆包服务并桥接设备回调 |
TranslateParam | 云端翻译请求参数基类,派生 TranslateAudioParam(音频流)与 TranslateTextParam(文本) |
RoleInfo | 角色信息(说话人/语言角色),参与云端请求与记录 |
TranslationRecord / TranslationSession | Room 实体,分别表示单条翻译记录与一次翻译会话 |
Architecture
flowchart TD
subgraph sg_UI["UI 层 (ui/translate)"]
Fragment["TranslateFragment"]
ViewModel["TranslateViewModel<br/>(extends BtBasicVM)"]
end
subgraph sg_Device["设备能力封装 (tool)"]
AITranslation["AITranslationImpl<br/>AI 云翻译代理"]
TranslationImpl["TranslationImpl<br/>(SDK RCSP 翻译)"]
RecordOp["RecordOpImpl<br/>设备录音"]
ConfigureKit["ConfigureKit<br/>配置管理"]
end
subgraph sg_Cloud["豆包云端 (tool/ai/doubao)"]
TranslateParam["TranslateParam<br/>WAY_AUDIO_STREAM / WAY_TEXT"]
AudioParam["TranslateAudioParam"]
TextParam["TranslateTextParam"]
Requests["Request 模型<br/>TranslateDataRequest /<br/>TranslateTextRequest /<br/>StopTranslateRequest"]
Auth["SignSpeechTranslate<br/>签名鉴权"]
end
subgraph sg_Data["数据层"]
Repository["TranslationRepository<br/>(Room)"]
DB[("Room Database<br/>TranslationRecord / Session")]
Util["TranslateUtil<br/>时间/时长/音频后缀"]
end
Fragment --> ViewModel
ViewModel --> AITranslation
ViewModel --> TranslationImpl
ViewModel --> RecordOp
ViewModel --> ConfigureKit
ViewModel --> Repository
AITranslation --> TranslateParam
TranslateParam --> AudioParam
TranslateParam --> TextParam
AudioParam --> Requests
TextParam --> Requests
Requests --> Auth
Repository --> DB
ViewModel --> Util
TranslationImpl -->|"Bluetooth RCSP"| Device["蓝牙设备<br/>录音/播放"]
RecordOp -->|"录音指令"| Device
架构说明:TranslateViewModel 是应用层的逻辑中枢,持有 AITranslationImpl(云端)、TranslationImpl(设备端翻译能力)、RecordOpImpl(录音)、TranslationRepository(持久化)与 ConfigureKit(配置)五个依赖。云端请求参数以 TranslateParam 抽象类为基类,按翻译方式(音频流/文本)分化为 TranslateAudioParam 与 TranslateTextParam,最终经豆包请求模型与签名鉴权发往云端。TranslateUtil 为各层提供时间格式化与音频后缀等公共工具。
翻译状态机
翻译会话的运行时状态由 com.jieli.btsmart.tool.translate.TranslateState 枚举统一表达:
public enum TranslateState {
STATE_IDLE(0),
STATE_WORKING(1),
STATE_PAUSE(2);
private final int value;
TranslateState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Source: TranslateState.java
STATE_IDLE(0):空闲态,无翻译会话或会话已结束,可安全进入翻译模式;STATE_WORKING(1):工作态,设备正在录音、音频正在传输或云端翻译进行中;STATE_PAUSE(2):暂停态,会话保留但暂停采集/翻译,通常由用户手动暂停或设备录音中断触发。
stateDiagram-v2
[*] --> STATE_IDLE
STATE_IDLE --> STATE_WORKING: 进入翻译模式 (OP_ENTER_MODE) / 开始翻译 (OP_AI_TRANSLATION)
STATE_WORKING --> STATE_PAUSE: 暂停翻译 (OP_AI_TRANSLATION)
STATE_PAUSE --> STATE_WORKING: 继续翻译
STATE_WORKING --> STATE_IDLE: 退出翻译模式 (OP_EXIT_MODE) / 会话结束
STATE_PAUSE --> STATE_IDLE: 退出翻译模式 (OP_EXIT_MODE)
设计意图:引入独立状态枚举而非布尔标志,是为了让 UI、设备回调与云端回调三方对会话生命周期有一致的可观察视图,避免"正在录音但云端已完成"这类竞态误判;value 字段可序列化到设备端(如同步到协议层)以便双端状态对齐。
逻辑中枢:TranslateViewModel
TranslateViewModel(位于 ui/translate 包,继承 BtBasicVM)是整个 AI 翻译功能的编排者。它定义了与设备交互的操作码常量:
/** 进入翻译模式操作 */
public static final int OP_ENTER_MODE = 0x20;
/** 退出翻译模式操作 */
public static final int OP_EXIT_MODE = 0x21;
/** 调节音量 */
public static final int OP_ADJUST_VOLUME = 0x22;
/** 设备录音 */
public static final int OP_DEVICE_RECORD = 0x23;
/** AI翻译 */
public static final int OP_AI_TRANSLATION = 0x24;
/** 同步翻译模式 */
public static final int OP_SYNC_TRANSLATION_MODE = 0x25;
/** 工作时间计数消息 */
private static final int MSG_COUNT_WORK_TIME = 0x3211;
private static final int INIT_SESSION_ID = -1;
Source: TranslateViewModel.java
这些常量把"翻译功能"抽象为对设备的一组可下发操作:进入/退出翻译模式、调节音量、触发设备录音、启动/停止 AI 翻译、同步翻译模式。MSG_COUNT_WORK_TIME 通过 Handler 定时消息累计工作时长,INIT_SESSION_ID = -1 表示会话尚未建立。
ViewModel 持有的核心依赖(构造时注入):
/** 操作设备 */
@NonNull
private final BluetoothDevice mDevice;
/** AI云翻译代理实现 */
private final AITranslationImpl mAITranslation;
/** 翻译功能实现 */
private final TranslationImpl mTranslation;
/** 翻译数据库操作 */
private final TranslationRepository mRepository;
/** 配置管理工具 */
private final ConfigureKit mConfigureKit;
/** 录音 */
private RecordOpImpl mRecordOp;
Source: TranslateViewModel.java
对外暴露的 LiveData 回调
| LiveData | 类型 | 含义 |
|---|---|---|
initMLD | MutableLiveData<Integer> | 初始化结果(错误码,0 为成功) |
muteStateMLD | MutableLiveData<Boolean> | 静音状态 |
modeChangeMLD | MutableLiveData<TranslationMode> | 翻译模式切换 |
workTimeMLD | MutableLiveData<Integer> | 本次翻译工作时长(秒) |
UI(TranslateFragment)观察这些 LiveData 驱动界面刷新,而 ViewModel 通过 TranslationStateCallback、TranslationCallback、OnRecordStateCallback 等回调接收设备/云端事件。这种"LiveData 出、回调进"的模型保证所有状态变更都在主线程安全发布,天然适配 MVVM。
设备端能力:TranslationImpl 与录音
TranslationImpl(SDKcom.jieli.bluetooth.impl.rcsp.translation):封装蓝牙 RCSP 协议层的翻译功能,负责下发翻译模式、接收设备返回的AudioData(录音音频)与TranslationResult(译文),并通过TranslationCallback上报。RecordOpImpl(SDKcom.jieli.bluetooth.impl.rcsp.record):负责设备录音控制,通过OnRecordStateCallback上报RecordState,录音参数由RecordParam描述(采样率、编码等)。ConfigureKit(应用层tool.configure):管理设备配置项,用于在进入/退出翻译模式时保存与恢复设备状态(如音量、降噪等),避免翻译会话破坏原有设备配置。
翻译模式下数据流为设备 → 手机(录音上行)与手机 → 设备(译文/音频下行)双向交替:设备端采集的音频以 AudioData 回传,TranslateViewModel 将其交给 AITranslationImpl 送云端;云端译文回传后经 TranslationImpl 下发设备播放。
云端翻译:AITranslationImpl 与豆包请求模型
请求参数基类 TranslateParam
豆包翻译请求参数以抽象类 TranslateParam 为基类,按"翻译方式"区分两条路径:
/**
* 翻译音频流方式
*/
public static final int WAY_AUDIO_STREAM = 1;
/**
* 翻译文本方式
*/
public static final int WAY_TEXT = 2;
@NonNull
private final String mac;
@NonNull
private final RoleInfo roleInfo;
private final boolean isIdAutoInc;
private int recordId;
private TranslationRecord translationRecord;
private int saveRecordId = -1;
public TranslateParam(@NonNull String mac, @NonNull RoleInfo roleInfo, boolean isIdAutoInc, int recordId) {
this.mac = mac;
this.roleInfo = roleInfo;
this.isIdAutoInc = isIdAutoInc;
if (recordId < 0) {
this.recordId = new Random().nextInt(256);
} else {
this.recordId = recordId;
}
}
Source: TranslateParam.java
设计要点:
- 双路径:
WAY_AUDIO_STREAM(1)走音频流实时翻译,WAY_TEXT(2)走纯文本翻译,分别由TranslateAudioParam与TranslateTextParam实现,子类必须实现getTranslationWay(); - recordId 策略:调用方未指定记录 ID(
recordId < 0)时随机生成[0, 256)的 ID,用于云端会话关联;isIdAutoInc控制记录 ID 是否自增,saveRecordId追踪已持久化的记录,避免重复入库; - 上下文绑定:每次请求都携带设备
mac与RoleInfo(角色/语言信息),使云端返回结果能与具体设备、具体说话角色正确对应。
豆包请求/响应模型
tool/ai/doubao/translate 包构成完整的云端接入面:
| 文件 | 职责 |
|---|---|
model/request/TranslateConfigRequest | 翻译配置请求(语言对、采样率等) |
model/request/TranslateDataRequest | 音频流数据请求(增量音频帧) |
model/request/TranslateTextRequest | 文本翻译请求 |
model/request/StopTranslateRequest | 停止翻译请求 |
model/TranslateAudioParam | 音频流方式参数(继承 TranslateParam) |
model/TranslateTextParam | 文本方式参数(继承 TranslateParam) |
auth/SignSpeechTranslate | 云端签名鉴权,为请求生成合法凭证 |
OnTranslateResultCallback | 翻译结果回调接口(成功/失败/中间结果) |
云端接入采用"配置 → 数据流 → 停止"的会话式协议:先以 TranslateConfigRequest 建立会话,再通过多个 TranslateDataRequest 流式上传音频/文本,最后以 StopTranslateRequest 结束会话。SignSpeechTranslate 保证请求经过签名校验,防止未授权调用。
数据模型与持久化
翻译会话与记录的实体位于 data/model/translation(TranslationRecord、TranslationSession、RoleInfo)与 SDK 层(AudioData、TranslationResult、TranslationMode),通过 TranslationRepository(tool/room/repository)访问 Room 数据库:
TranslationSession:一次翻译会话(开始时间、模式、时长、状态);TranslationRecord:会话中的单条翻译记录(原文/译文、角色、时间戳、关联会话 ID);RoleInfo:说话角色信息,随TranslateParam上行,用于区分说话人语言。
erDiagram
TranslationSession ||--o{ TranslationRecord : "包含"
TranslationSession {
int sessionId PK "INIT_SESSION_ID = -1 表示未建立"
string mode "TranslationMode"
datetime startTime
int duration "秒"
int state "TranslateState"
}
TranslationRecord {
int recordId PK "云端关联 ID"
int sessionId FK
string originalText
string translatedText
string role "RoleInfo"
datetime createTime
}
TranslationRecord }o--|| RoleInfo : "说话角色"
RoleInfo {
string language
string speaker
}
TranslateViewModel 借助 saveRecordId 与 INIT_SESSION_ID 的配合,确保:会话未建立(ID 为 -1)时不写记录;同一条云端记录不因回调重入而重复入库。
核心流程:一次完整的 AI 翻译会话
从用户点击"开始翻译"到译文回放,完整时序如下:
sequenceDiagram
participant U as 用户/TranslateFragment
participant VM as TranslateViewModel
participant R as RecordOpImpl
participant D as 蓝牙设备
participant T as TranslationImpl
participant AI as AITranslationImpl
participant Cloud as 豆包云端 (TranslateParam/签名)
U->>VM: 进入翻译模式 (OP_ENTER_MODE)
VM->>T: 下发翻译模式 TranslationMode
T-->>VM: TranslationCallback 确认
VM->>VM: 状态 -> STATE_WORKING<br/>启动 MSG_COUNT_WORK_TIME 计时
VM->>R: 启动设备录音 (OP_DEVICE_RECORD)
R->>D: 录音指令
D-->>T: 回传 AudioData (音频流)
T-->>VM: TranslationCallback(AudioData)
VM->>AI: 请求云端翻译 (TranslateAudioParam)
AI->>Cloud: TranslateConfigRequest + TranslateDataRequest<br/>(SignSpeechTranslate 鉴权)
Cloud-->>AI: 译文结果
AI-->>VM: OnTranslateResultCallback / TranslationResult
VM->>Repository: 保存 TranslationRecord
VM->>T: 下发译文 (文本/音频) 到设备
T->>D: 设备播放译文
U->>VM: 停止翻译 (OP_AI_TRANSLATION)
VM->>Cloud: StopTranslateRequest
VM->>VM: 状态 -> STATE_IDLE<br/>停止计时、保存会话
流程要点:
- 模式先行:必须先通过
OP_ENTER_MODE+TranslationImpl让设备进入翻译模式,之后录音与音频回传才合法; - 状态驱动计时:
STATE_WORKING期间MSG_COUNT_WORK_TIME每单位时间递增并发布到workTimeMLD,暂停(STATE_PAUSE)时计时挂起,避免"暂停仍计费/计时"的体验问题; - 音频即来即译:设备回传的
AudioData不落盘,直接以TranslateAudioParam(WAY_AUDIO_STREAM)流入云端,保证低延迟; - 结果双向落地:译文既下发设备播放,也写入
TranslationRepository,兼顾实时性与可追溯性; - 优雅收尾:停止时先发
StopTranslateRequest结束云端会话,再退出翻译模式、持久化会话并复位状态。
使用示例
1. 状态枚举的使用
public enum TranslateState {
STATE_IDLE(0),
STATE_WORKING(1),
STATE_PAUSE(2);
private final int value;
TranslateState(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Source: TranslateState.java
2. 时间格式化与音频后缀工具
TranslateUtil 集中了翻译功能的时间与文件命名约定:记录文件名使用 yyyyMMddHHmmss,会话展示使用 yyyy-MM-dd HH:mm,音频文件按 PCM / WAV / OPUS / JLA 后缀区分编码:
public static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss", Locale.ENGLISH);
public static final SimpleDateFormat RECORD_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
public static final SimpleDateFormat YEAR_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
public static final SimpleDateFormat MONTH_DATE_FORMAT = new SimpleDateFormat("yyyy-MM", Locale.ENGLISH);
public static final String PCM_SUFFIX = ".pcm";
public static final String WAV_SUFFIX = ".wav";
public static final String OPUS_SUFFIX = ".opus";
public static final String JLA_SUFFIX = ".jla";
Source: TranslateUtil.java
时长展示工具 formatDuration(HH:mm:ss)与 formatDurationToHm(mm:ss)分别用于会话总时长与录音片段时长的 UI 展示;isSameDay / isSameMonth 用于把历史记录按天/月分组,getDayStartTime / getDayEndTime 支撑按日查询。
3. 构造云端翻译参数
public TranslateParam(@NonNull String mac, @NonNull RoleInfo roleInfo, boolean isIdAutoInc, int recordId) {
this.mac = mac;
this.roleInfo = roleInfo;
this.isIdAutoInc = isIdAutoInc;
if (recordId < 0) {
this.recordId = new Random().nextInt(256);
} else {
this.recordId = recordId;
}
}
Source: TranslateParam.java
实际使用时由 TranslateAudioParam 或 TranslateTextParam 提供具体的 getTranslationWay() 实现,AITranslationImpl 依据该方式选择音频流或文本请求通道。
4. ViewModel 操作码定义
public static final int OP_ENTER_MODE = 0x20;
public static final int OP_EXIT_MODE = 0x21;
public static final int OP_ADJUST_VOLUME = 0x22;
public static final int OP_DEVICE_RECORD = 0x23;
public static final int OP_AI_TRANSLATION = 0x24;
public static final int OP_SYNC_TRANSLATION_MODE = 0x25;
Source: TranslateViewModel.java
API Reference(核心接口)
TranslateState(枚举)
| 常量 | value | 语义 |
|---|---|---|
STATE_IDLE | 0 | 空闲,无进行中的会话 |
STATE_WORKING | 1 | 工作中,采集/翻译进行中 |
STATE_PAUSE | 2 | 暂停,会话保留 |
方法:
getValue(): int— 返回状态值,用于序列化或与设备端同步。
TranslateParam(抽象类)
常量:
WAY_AUDIO_STREAM = 1— 音频流翻译方式WAY_TEXT = 2— 文本翻译方式
构造器: TranslateParam(String mac, RoleInfo roleInfo, boolean isIdAutoInc, int recordId)
mac(必填):设备蓝牙地址,绑定云端会话与设备roleInfo(必填):说话角色信息isIdAutoInc:记录 ID 是否自增recordId:指定记录 ID;小于 0 时随机生成[0, 256)
方法:
getTranslationWay(): int(抽象)— 返回翻译方式getMac(): String— 获取设备地址getRoleInfo(): RoleInfo— 获取角色信息
TranslateViewModel(逻辑中枢)
操作码常量: OP_ENTER_MODE(0x20)、OP_EXIT_MODE(0x21)、OP_ADJUST_VOLUME(0x22)、OP_DEVICE_RECORD(0x23)、OP_AI_TRANSLATION(0x24)、OP_SYNC_TRANSLATION_MODE(0x25)。
对外 LiveData: initMLD: MutableLiveData<Integer>、muteStateMLD: MutableLiveData<Boolean>、modeChangeMLD: MutableLiveData<TranslationMode>、workTimeMLD: MutableLiveData<Integer>。
依赖(构造注入): BluetoothDevice mDevice、AITranslationImpl mAITranslation、TranslationImpl mTranslation、TranslationRepository mRepository、ConfigureKit mConfigureKit、RecordOpImpl mRecordOp。
回调接口(应用层 tool/translate): TranslationStateCallback — 翻译状态变化回调;SDK 层 TranslationCallback(音频/结果)、OnRecordStateCallback(录音状态)、OnRcspActionCallback(RCSP 操作结果)。
失败模式、边界情况与并发
蓝牙链路失败
- 设备断开/未连接:
TranslateViewModel持有BluetoothDevice,若会话中蓝牙断开,TranslationImpl与RecordOpImpl的回调将中断。initMLD以错误码(非 0)发布初始化失败,UI 据此提示并回到STATE_IDLE。 - 录音指令失败:
OnRecordStateCallback上报的RecordState非预期时(如设备忙),不应继续上行音频,需提示用户重试并保持会话可恢复。
云端失败与超时
- 鉴权失败:
SignSpeechTranslate签名过期或非法时,豆包请求被拒绝;应重新生成签名后重试。 - 会话中断:云端会话由
TranslateConfigRequest建立、StopTranslateRequest结束。若中途网络异常,云端会话可能悬挂,需要在重连后发送停止请求清理,否则新会话可能被旧会话干扰。 - 重复回调:
saveRecordId机制防止同一条TranslationRecord因回调重入被多次写入;未保存(saveRecordId = -1)前才会写入数据库。
状态与并发
- 状态竞态:
STATE_IDLE / WORKING / PAUSE由 ViewModel 主线程维护,所有回调(设备、云端、录音)都应在主线程转投 LiveData,避免多线程直接修改状态。MSG_COUNT_WORK_TIME经主线程 Handler 派发,保证计时与状态切换有序。 - recordId 冲突:
recordId < 0时随机生成[0, 256),范围较小,极端情况下多设备/多会话可能碰撞;isIdAutoInc为 true 时由调用方保证递增,规避冲突。 - 会话未建立写库:
INIT_SESSION_ID = -1标记会话未建立,此时不落记录,避免"孤儿记录"污染历史列表。
边界情况
- 翻译模式切换(
OP_SYNC_TRANSLATION_MODE/modeChangeMLD)发生在会话中时,需先停止当前云端会话再切换TranslationMode,否则新旧模式数据混流; - 暂停(
STATE_PAUSE)期间设备可能仍在缓冲音频,恢复后需丢弃缓冲,保证译文顺序与真实语音一致; - 时长格式化边界:
formatDuration按 3600/60 取模,超长会话(>99 小时)仍可正确显示,但 UI 布局需预留宽度。
性能与运维考量
- 低延迟优先:音频上行采用流式
TranslateDataRequest,边录边传,避免整段录音完成后再翻译带来的明显延迟;因此音频编码(OPUS/JLA 后缀暗示设备端支持压缩编码)直接影响带宽与延迟。 - 计时开销:
MSG_COUNT_WORK_TIME为常驻 Handler 消息,仅在工作态运行;暂停/退出即移除消息,避免后台空转耗电。 - 持久化策略:记录在翻译结果回调后立即写入 Room,会话在结束时写入;
TranslationRepository统一管理事务,批量回看(按天/月分组)依赖TranslateUtil的日期格式化方法生成索引键。 - 依赖注入:
AITranslationImpl、TranslationImpl、TranslationRepository、ConfigureKit均通过构造注入到 ViewModel,便于单元测试替换为 mock 实现,也便于在 UI 层之外(如通知栏快捷入口)复用翻译会话。
扩展点
- 新增云端服务商:
AITranslationImpl是 AI 翻译代理的抽象边界,豆包实现位于tool/ai/doubao。接入新服务商可平行新增包(如tool/ai/xxx/translate),实现同一组请求/回调约定即可,TranslateParam的WAY_AUDIO_STREAM / WAY_TEXT双方式可复用。 - 新增翻译方式:继承
TranslateParam并实现getTranslationWay(),同时在请求模型侧补充对应 Request 类即可扩展(如字幕式、离线词库式)。 - 新增状态:在
TranslateState枚举中追加状态值需同步更新 ViewModel 的状态迁移逻辑与 UI 状态展示,属于破坏性扩展。 - 历史记录扩展:
TranslationRecord / TranslationSession为 Room 实体,可增加字段并通过TranslationRepository提供按角色、按语言过滤的新查询。
Related Links
- TranslateState.java — 翻译状态枚举
- TranslateViewModel.java — 翻译逻辑中枢
- TranslateFragment.java — 翻译 UI 入口
- TranslateParam.java — 云端翻译参数基类
- TranslateUtil.java — 时间/时长/音频后缀工具
- fragment_translate.xml — 翻译界面布局
相关平级功能页:录音、语音助手、设备配置(ConfigureKit)等请参见各自目录文档;蓝牙协议层
TranslationImpl/RecordOpImpl的底层指令细节参见 SDK(com.jieli.bluetooth)文档。