Files
life-echo/app-android

岁月留书 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

环境配置

  1. 克隆项目
git clone <repository-url>
cd life-echo/app-android
  1. 使用 Android Studio 打开项目

    • 打开 Android Studio
    • 选择 File -> Open
    • 选择 app-android 目录
    • 等待 Gradle 同步完成
  2. 配置 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 并移除明文流量配置
  3. 确保后端服务运行

    确保后端 API 服务已启动并可以访问(参考 api/README.md

  4. 运行应用

    • 连接 Android 设备或启动模拟器
    • 点击 Run 按钮(或使用快捷键 Shift+F10
    • 选择目标设备
    • 等待应用安装和启动

📱 应用功能

认证功能

  • 用户注册 - 手机号注册,支持昵称和邮箱
  • 用户登录 - 手机号 + 密码登录
  • Token 管理 - 自动管理访问令牌和刷新令牌
  • 自动登录 - 支持记住登录状态

对话功能

  • 实时语音对话 - WebSocket 实时双向通信
  • 语音录制 - 支持实时音频录制和发送
  • 语音播放 - TTS 音频自动播放
  • 对话历史 - 查看历史对话记录
  • 对话管理 - 创建、查看、结束对话

回忆录功能

  • 章节列表 - 查看所有回忆录章节
  • 章节阅读 - 优雅的章节阅读界面
  • 全文阅读 - 查看完整回忆录内容
  • PDF 导出 - 导出回忆录为 PDF 文档
  • 章节整理 - 将对话内容整理为章节

用户中心

  • 账户信息 - 查看和编辑用户信息
  • 套餐管理 - 查看当前套餐,升级套餐
  • 订单查询 - 查看历史订单
  • 数据导出 - 导出所有用户数据
  • 设置 - 语言、主题、通知等设置
  • 常见问题 - FAQ 列表
  • 反馈 - 提交反馈和联系客服

🏗️ 架构设计

MVVM 架构

应用采用 MVVMModel-View-ViewModel 架构模式:

┌─────────────┐
│    View     │  (Compose UI)
│  (Screen)   │
└──────┬──────┘
       │
       │ observe
       ▼
┌─────────────┐
│ ViewModel   │  (状态管理、业务逻辑)
└──────┬──────┘
       │
       │ use
       ▼
┌─────────────┐
│ Repository  │  (数据访问抽象)
└──────┬──────┘
       │
       ├─────────┐
       │         │
       ▼         ▼
┌──────────┐ ┌──────────┐
│   Room   │ │ Network  │
│ Database │ │  API     │
└──────────┘ └──────────┘

数据流

  1. UI 层Compose:使用 @Composable 函数构建界面
  2. ViewModel:管理 UI 状态,处理用户交互
  3. Repository:统一数据访问接口,协调本地数据库和网络 API
  4. 数据源
    • Room Database:本地 SQLite 数据库(离线数据)
    • Network APIREST 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>> {
        // 先从本地数据库获取
        // 然后从网络获取并更新本地数据库
    }
}

🔧 开发指南

添加新的屏幕

  1. ui/screens/ 目录创建新的 Screen Composable
  2. navigation/AppNavigation.kt 中添加路由
  3. 创建对应的 ViewModel如需要
  4. 在导航图中注册新屏幕

添加新的 API 接口

  1. network/ApiService.kt 中添加接口定义
  2. network/models/ 中添加对应的数据模型
  3. 在相应的 Repository 中调用新接口

添加新的数据库表

  1. data/database/ 中创建 Entity 类
  2. 创建对应的 DAO 接口
  3. AppDatabase.kt 中注册 Entity 和 DAO
  4. 更新数据库版本号

添加新的 UI 组件

  1. ui/components/ 目录创建组件
  2. 使用 @Composable 注解
  3. 遵循 Material Design 3 设计规范

🧪 测试

单元测试

./gradlew test

集成测试

./gradlew connectedAndroidTest

📦 构建发布

Debug 构建

./gradlew assembleDebug

Release 构建

  1. 配置签名密钥(在 app/build.gradle.kts 中)
  2. 构建 Release APK
./gradlew assembleRelease
  1. 构建 Release AABGoogle Play
./gradlew bundleRelease

🔒 安全注意事项

  1. 网络配置

    • 开发环境允许明文 HTTP仅用于开发
    • 生产环境必须使用 HTTPS
    • 配置 network_security_config.xml 限制允许的域名
  2. Token 存储

    • Token 存储在 DataStore Preferences 中
    • 不要将 Token 存储在 SharedPreferences 或日志中
  3. API Key

    • 不要在代码中硬编码 API Key
    • 使用 BuildConfig 或环境变量
  4. ProGuard/R8

    • 启用代码混淆Release 构建)
    • 配置 ProGuard 规则保护敏感代码

🐛 常见问题

WebSocket 连接失败

问题:无法连接到 WebSocket 服务器

解决方案

  1. 检查 AppConfig.kt 中的 WS_BASE_URL 是否正确
  2. 确认后端服务正在运行
  3. 检查网络权限(INTERNET)是否已添加
  4. 如果是模拟器,使用 10.0.2.2 代替 localhost

音频录制失败

问题:无法录制音频

解决方案

  1. 检查 RECORD_AUDIO 权限是否已申请
  2. 确认设备支持音频录制
  3. 检查音频格式配置

数据库迁移失败

问题:应用更新后数据库迁移失败

解决方案

  1. 检查数据库版本号是否正确递增
  2. 确认 Migration 类已正确实现
  3. 测试数据库迁移逻辑

📚 相关文档

📄 许可证

MIT License


岁月留书 Android - 让每一段人生故事都被温柔记录 📱