# voice-notes **Repository Path**: henryong/voice-notes ## Basic Information - **Project Name**: voice-notes - **Description**: 一个支持“语音创建任务、即时播报、定时语音提醒”的 Android 应用。识别中文语音,解析时间与优先级,保存到本地数据库,并在预设时间通过前台服务进行语音播报。 - **Primary Language**: Kotlin - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-16 - **Last Updated**: 2025-11-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # VoiceNotes 语音待办 一个支持“语音创建任务、即时播报、定时语音提醒”的 Android 应用。识别中文语音,解析时间与优先级,保存到本地数据库,并在预设时间通过前台服务进行语音播报。 **项目概览** - 语音输入创建待办,支持中文自由说话。 - 通过大模型解析“标题/时间/优先级”,并带本地时间推断兜底。 - 识别后立即播报任务标题,提升交互反馈。 - 任务持久化与到期提醒(含“提前提醒”)。 - Jetpack Compose 构建 UI,架构清晰、易于学习与扩展。 **核心功能** - 语音创建待办:长按覆盖层按钮说话,松开结束识别。 - 智能解析:`Parser.parseSpeechToTask` 强化系统提示,注入当前时间/时区;若 LLM 未给出时间,使用本地中文时间规则自动补全。 - 即时播报:识别后调用 `SpeechUtils.speakNow` 播报解析的标题。 - 定时提醒:通过 `ReminderScheduler` 设置精确闹钟,触发前台服务播报预提醒与到期提醒。 - 列表与筛选:Room 持久化,支持优先级、完成状态、日期范围(今日/本周/逾期)。 **架构设计** - UI 层 - `app/src/main/java/com/liuqi/voicenotes/MainActivity.kt`:入口、设置面板、列表展示、全局状态与语音覆盖层调用。 - `app/src/main/java/com/liuqi/voicenotes/ui/VoiceChatOverlay.kt`:“按住说话”覆盖层,封装 SpeechRecognizer 回调与兜底策略。 - `app/src/main/java/com/liuqi/voicenotes/ui/TasksViewModel.kt`:任务流与添加逻辑,提供 `addParsedTask` 与 `addFromSpeech`。 - `app/src/main/java/com/liuqi/voicenotes/ui/VoiceNotesTheme.kt`:主题封装(如存在)。 - Domain 层 - `app/src/main/java/com/liuqi/voicenotes/domain/Parser.kt`:LLM 解析与本地时间推断。强化系统提示,注入“设备当前时间/时区/默认规则”,并在失败时记录详细异常。 - Reminder 层 - `app/src/main/java/com/liuqi/voicenotes/reminder/ReminderScheduler.kt`:读取“提前提醒分钟数”,创建精确闹钟并调度。 - `app/src/main/java/com/liuqi/voicenotes/reminder/ReminderReceiver.kt`:接收闹钟广播并启动前台服务。 - `app/src/main/java/com/liuqi/voicenotes/reminder/ReminderSpeakService.kt`:前台服务进行 TTS 播报,完成后释放资源。 - `app/src/main/java/com/liuqi/voicenotes/reminder/SpeechUtils.kt`:简化 TTS 初始化与播报。 - 数据层 - `app/src/main/java/com/liuqi/voicenotes/data/*`:`TaskRepository`、Room (`TaskDao`, `TaskEntity`, `AppDatabase`) 等。 - Utils 层 - `app/src/main/java/com/liuqi/voicenotes/DateTimeUtils.kt`:集中 `formatMillisPretty`、`isToday`、`isThisWeek` 等时间辅助函数。 **关键调用关系** - 语音输入流程 - `MainActivity` → 显示 `VoiceChatOverlay` → 按住说话 → `SpeechRecognizer` 返回结果 → 回调 `onFinalText(text)`。 - `App` 组件中接收文本:记录日志 → 调用 `Parser.parseSpeechToTask(context, text, ...)`。 - `SpeechUtils.speakNow(context, parsed.title)` 进行即时播报。 - 若有解析结果:`TasksViewModel.addParsedTask(parsed)`;否则回退 `addFromSpeech(text)`。 - `TaskRepository.add(task)` 持久化;`ReminderScheduler.scheduleForTask(...)` 调度提醒。 - 提醒播报流程 - 到期前或到期时触发 `ReminderReceiver` → 启动 `ReminderSpeakService` 前台服务。 - 服务初始化 TTS → 设置语言 → 播报“提醒:...”,完成后 `stopSelf()`。 **语音解析与时间推断** - 系统提示包含:`当前设备时间`、`时区`、以及无日期仅给时间时的默认规则: - 若只说时间(如“下午5点”),优先解释为“最近的未来时间”;当天未过去用“今天”,已过去用“明天”。 - 中文时间修饰(“上午/下午/晚上”)映射到 24 小时制。 - 兜底策略:若 LLM 返回 `dueAtMillis = null`,使用 `inferDueMillisFromText` 本地规则补全,并记录日志便于调试。 **提醒与播报** - 提前提醒分钟数:`ReminderScheduler.getLeadMinutes(Context)`,键 `lead_time_minutes`。 - 精确闹钟:`AlarmManager` + `PendingIntent` 指向 `ReminderReceiver`。 - 前台服务:`ReminderSpeakService` 中通过 TTS 播报,兼容中文语音数据。 **运行与权限** - 录音:`RECORD_AUDIO`(语音识别)。 - 通知:Android 13+ 需 `POST_NOTIFICATIONS`。 - 精确闹钟:Android 12 (S)+ 需在系统设置中允许,代码已检测与提示。 **调试与日志** - 关键 Tag:`MainActivity`、`SpeechUtils`、`ReminderSpeakService`、`Parser`。 - 验证流程: - 语音识别日志显示最终文本 → 解析日志显示 `title/due/priority`。 - 即时播报日志显示 `speakNow` → 预提醒/到期提醒在服务中 `onStart/onDone`。 - 重复解析防护:`addParsedTask` 优先,避免在 ViewModel 里再次请求 LLM。 - 覆盖层最小展示约 `900ms`,便于日志观察与体验优化。 **配置项** - 在设置界面输入并保存:`DeepSeek API Key` 与 `DeepSeek API Base`。 - 偏好键:`deepseek_api_key`、`deepseek_api_base`,保存在 `SharedPreferences`。 **目录结构(摘录)** - `app/src/main/java/com/liuqi/voicenotes/MainActivity.kt` - `app/src/main/java/com/liuqi/voicenotes/ui/VoiceChatOverlay.kt` - `app/src/main/java/com/liuqi/voicenotes/ui/TasksViewModel.kt` - `app/src/main/java/com/liuqi/voicenotes/domain/Parser.kt` - `app/src/main/java/com/liuqi/voicenotes/reminder/*` - `app/src/main/java/com/liuqi/voicenotes/data/*` - `app/src/main/java/com/liuqi/voicenotes/DateTimeUtils.kt` **学习建议** - 跟踪一次完整“语音 → 解析 → 播报 → 持久化 → 调度”的调用链,理解各层职责划分。 - 修改 `Parser` 的系统提示与本地推断规则,观察解析与日志变化,理解“提示工程 + 本地兜底”的组合策略。 - 在 `TasksViewModel` 中对添加逻辑做扩展(如分类、标签),练习与 Room 交互与提醒联动。 - 为关键函数添加单元测试(如时间推断),确保边界场景稳定。