岁月留书 Android 应用
Life Echo Android 客户端 - 基于 Jetpack Compose 的现代化 Android 应用
📱 项目简介
岁月留书 Android 应用是 Life Echo 平台的移动端客户端,提供流畅的语音对话体验和回忆录管理功能。应用采用现代化的 Android 开发技术栈,实现优雅的用户界面和流畅的交互体验。
核心功能
- 🎙️ 实时语音对话 - 通过 WebSocket 实现实时语音交互
- 💬 智能对话引导 - AI Agent 引导用户进行回忆录访谈
- 📚 回忆录管理 - 查看和管理生成的回忆录章节
- 📄 PDF 导出 - 导出回忆录为 PDF 文档
- 👤 用户中心 - 账户管理、套餐升级、订单查询
- 💾 离线存储 - 使用 Room 数据库实现本地数据存储
- 🌙 深色模式 - 支持深色主题和浅色主题切换
🛠️ 技术栈
| 技术 | 版本/说明 | 用途 |
|---|---|---|
| Kotlin | 1.9+ | 编程语言 |
| Jetpack Compose | Latest | 声明式 UI 框架 |
| Ktor | Latest | HTTP 客户端和 WebSocket |
| Room | Latest | 本地数据库(SQLite) |
| Coroutines + Flow | Latest | 异步编程和响应式数据流 |
| DataStore Preferences | 1.0.0 | 键值对存储(Token 管理) |
| Coil | Latest | 图片加载库 |
| Navigation Compose | Latest | 导航管理 |
| ViewModel | Latest | MVVM 架构支持 |
| Material 3 | Latest | Material Design 3 组件 |
📁 项目结构
app-android/
├── app/
│ ├── build.gradle.kts # 应用级构建配置
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/com/huaga/life_echo/
│ │ ├── MainActivity.kt # 主 Activity
│ │ │
│ │ ├── config/
│ │ │ └── AppConfig.kt # 应用配置(API 地址等)
│ │ │
│ │ ├── data/ # 数据层
│ │ │ ├── auth/
│ │ │ │ └── TokenManager.kt # Token 管理
│ │ │ ├── database/ # Room 数据库
│ │ │ │ ├── AppDatabase.kt
│ │ │ │ ├── Book.kt
│ │ │ │ ├── Chapter.kt
│ │ │ │ ├── Conversation.kt
│ │ │ │ └── ...
│ │ │ ├── preferences/
│ │ │ │ └── TokenPreferences.kt
│ │ │ └── repository/ # Repository 模式
│ │ │ ├── ChapterRepository.kt
│ │ │ ├── ConversationRepository.kt
│ │ │ └── ...
│ │ │
│ │ ├── network/ # 网络层
│ │ │ ├── ApiService.kt # REST API 服务
│ │ │ ├── AuthService.kt # 认证服务
│ │ │ ├── WebSocketClient.kt # WebSocket 客户端
│ │ │ ├── interceptors/
│ │ │ │ └── AuthInterceptor.kt
│ │ │ └── models/ # 数据模型
│ │ │ ├── AuthModels.kt
│ │ │ ├── ConversationModels.kt
│ │ │ └── ...
│ │ │
│ │ ├── ui/ # UI 层
│ │ │ ├── screens/ # 屏幕组件
│ │ │ │ ├── LoginScreen.kt
│ │ │ │ ├── RegisterScreen.kt
│ │ │ │ ├── CreateMemoryScreen.kt
│ │ │ │ ├── MyMemoirScreen.kt
│ │ │ │ ├── ProfileScreen.kt
│ │ │ │ └── ...
│ │ │ ├── components/ # 可复用组件
│ │ │ │ ├── chat/ # 聊天相关组件
│ │ │ │ ├── memoir/ # 回忆录相关组件
│ │ │ │ ├── payment/ # 支付相关组件
│ │ │ │ └── common/ # 通用组件
│ │ │ ├── theme/ # 主题配置
│ │ │ │ ├── Color.kt
│ │ │ │ ├── Theme.kt
│ │ │ │ └── Type.kt
│ │ │ └── viewmodel/ # ViewModel
│ │ │ ├── AuthViewModel.kt
│ │ │ ├── CreateMemoryViewModel.kt
│ │ │ └── ...
│ │ │
│ │ ├── navigation/ # 导航管理
│ │ │ ├── AppNavigation.kt
│ │ │ └── NavigationTransitions.kt
│ │ │
│ │ ├── feature/ # 功能模块
│ │ │ └── voice/
│ │ │ └── VoiceRecorder.kt # 语音录制
│ │ │
│ │ └── utils/ # 工具类
│ │ ├── AnimationUtils.kt
│ │ ├── PaymentUtils.kt
│ │ └── ...
│ │
│ └── res/ # 资源文件
│ ├── values/
│ │ ├── strings.xml # 字符串资源
│ │ ├── colors.xml # 颜色资源
│ │ └── themes.xml # 主题资源
│ └── xml/
│ └── network_security_config.xml
│
├── build.gradle.kts # 项目级构建配置
├── settings.gradle.kts # 项目设置
├── gradle.properties # Gradle 属性
└── README.md # 本文档
🚀 快速开始
前置要求
- Android Studio Hedgehog | 2023.1.1 或更高版本
- JDK 11 或更高版本
- Android SDK API 24 (Android 7.0) 或更高版本
- Gradle 8.0+(项目已包含 Gradle Wrapper)
环境配置
- 克隆项目
git clone <repository-url>
cd life-echo/app-android
-
使用 Android Studio 打开项目
- 打开 Android Studio
- 选择
File -> Open - 选择
app-android目录 - 等待 Gradle 同步完成
-
配置 API 地址
编辑
app/src/main/java/com/huaga/life_echo/config/AppConfig.kt:object AppConfig { // 开发环境配置 // 物理机测试:使用实际的内网IP地址(如 192.168.10.9) const val BASE_URL = "http://192.168.10.9:8000" const val WS_BASE_URL = "ws://192.168.10.9:8000" // Android模拟器测试:使用 10.0.2.2 来访问主机 // const val BASE_URL = "http://10.0.2.2:8000" // const val WS_BASE_URL = "ws://10.0.2.2:8000" // 生产环境配置:公网地址 // const val BASE_URL = "https://api.lifeecho.com" // const val WS_BASE_URL = "wss://api.lifeecho.com" }注意事项:
- 从 Android 9 (API 28) 开始,默认禁止明文 HTTP 流量
- 开发环境已在
network_security_config.xml中配置允许明文流量 - 生产环境应使用 HTTPS 并移除明文流量配置
-
确保后端服务运行
确保后端 API 服务已启动并可以访问(参考 api/README.md)
-
运行应用
- 连接 Android 设备或启动模拟器
- 点击
Run按钮(或使用快捷键Shift+F10) - 选择目标设备
- 等待应用安装和启动
📱 应用功能
认证功能
- 用户注册 - 手机号注册,支持昵称和邮箱
- 用户登录 - 手机号 + 密码登录
- Token 管理 - 自动管理访问令牌和刷新令牌
- 自动登录 - 支持记住登录状态
对话功能
- 实时语音对话 - WebSocket 实时双向通信
- 语音录制 - 支持实时音频录制和发送
- 语音播放 - TTS 音频自动播放
- 对话历史 - 查看历史对话记录
- 对话管理 - 创建、查看、结束对话
回忆录功能
- 章节列表 - 查看所有回忆录章节
- 章节阅读 - 优雅的章节阅读界面
- 全文阅读 - 查看完整回忆录内容
- PDF 导出 - 导出回忆录为 PDF 文档
- 章节整理 - 将对话内容整理为章节
用户中心
- 账户信息 - 查看和编辑用户信息
- 套餐管理 - 查看当前套餐,升级套餐
- 订单查询 - 查看历史订单
- 数据导出 - 导出所有用户数据
- 设置 - 语言、主题、通知等设置
- 常见问题 - FAQ 列表
- 反馈 - 提交反馈和联系客服
🏗️ 架构设计
MVVM 架构
应用采用 MVVM(Model-View-ViewModel) 架构模式:
┌─────────────┐
│ View │ (Compose UI)
│ (Screen) │
└──────┬──────┘
│
│ observe
▼
┌─────────────┐
│ ViewModel │ (状态管理、业务逻辑)
└──────┬──────┘
│
│ use
▼
┌─────────────┐
│ Repository │ (数据访问抽象)
└──────┬──────┘
│
├─────────┐
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ Room │ │ Network │
│ Database │ │ API │
└──────────┘ └──────────┘
数据流
- UI 层(Compose):使用
@Composable函数构建界面 - ViewModel:管理 UI 状态,处理用户交互
- Repository:统一数据访问接口,协调本地数据库和网络 API
- 数据源:
- Room Database:本地 SQLite 数据库(离线数据)
- Network API:REST API 和 WebSocket(服务器数据)
关键组件
TokenManager
管理用户认证令牌:
// 保存 Token
TokenManager.saveTokens(accessToken, refreshToken)
// 获取 Token
val accessToken = TokenManager.getAccessToken()
// 检查登录状态
val isLoggedIn = TokenManager.isLoggedIn
WebSocketClient
WebSocket 连接管理:
// 连接 WebSocket
webSocketClient.connect(conversationId, accessToken)
// 发送消息
webSocketClient.sendAudio(audioData)
// 接收消息
webSocketClient.onMessage { message ->
// 处理消息
}
Repository 模式
统一数据访问:
class ConversationRepository(
private val apiService: ApiService,
private val conversationDao: ConversationDao
) {
suspend fun getConversations(): Flow<List<Conversation>> {
// 先从本地数据库获取
// 然后从网络获取并更新本地数据库
}
}
🔧 开发指南
添加新的屏幕
- 在
ui/screens/目录创建新的 Screen Composable - 在
navigation/AppNavigation.kt中添加路由 - 创建对应的 ViewModel(如需要)
- 在导航图中注册新屏幕
添加新的 API 接口
- 在
network/ApiService.kt中添加接口定义 - 在
network/models/中添加对应的数据模型 - 在相应的 Repository 中调用新接口
添加新的数据库表
- 在
data/database/中创建 Entity 类 - 创建对应的 DAO 接口
- 在
AppDatabase.kt中注册 Entity 和 DAO - 更新数据库版本号
添加新的 UI 组件
- 在
ui/components/目录创建组件 - 使用
@Composable注解 - 遵循 Material Design 3 设计规范
🧪 测试
单元测试
./gradlew test
集成测试
./gradlew connectedAndroidTest
📦 构建发布
Debug 构建
./gradlew assembleDebug
Release 构建
- 配置签名密钥(在
app/build.gradle.kts中) - 构建 Release APK:
./gradlew assembleRelease
- 构建 Release AAB(Google Play):
./gradlew bundleRelease
🔒 安全注意事项
-
网络配置:
- 开发环境允许明文 HTTP(仅用于开发)
- 生产环境必须使用 HTTPS
- 配置
network_security_config.xml限制允许的域名
-
Token 存储:
- Token 存储在 DataStore Preferences 中
- 不要将 Token 存储在 SharedPreferences 或日志中
-
API Key:
- 不要在代码中硬编码 API Key
- 使用 BuildConfig 或环境变量
-
ProGuard/R8:
- 启用代码混淆(Release 构建)
- 配置 ProGuard 规则保护敏感代码
🐛 常见问题
WebSocket 连接失败
问题:无法连接到 WebSocket 服务器
解决方案:
- 检查
AppConfig.kt中的WS_BASE_URL是否正确 - 确认后端服务正在运行
- 检查网络权限(
INTERNET)是否已添加 - 如果是模拟器,使用
10.0.2.2代替localhost
音频录制失败
问题:无法录制音频
解决方案:
- 检查
RECORD_AUDIO权限是否已申请 - 确认设备支持音频录制
- 检查音频格式配置
数据库迁移失败
问题:应用更新后数据库迁移失败
解决方案:
- 检查数据库版本号是否正确递增
- 确认 Migration 类已正确实现
- 测试数据库迁移逻辑
📚 相关文档
- 项目根目录 README - 项目总览
- API 文档 - 后端 API 文档
- WebSocket 测试文档 - WebSocket 测试指南
📄 许可证
MIT License
岁月留书 Android - 让每一段人生故事都被温柔记录 📱✨