2026-02-13 23:04:24 +01:00
|
|
|
|
# 岁月留书 Android 应用
|
2026-01-26 11:54:03 +08:00
|
|
|
|
|
|
|
|
|
|
> Life Echo Android 客户端 - 基于 Jetpack Compose 的现代化 Android 应用
|
|
|
|
|
|
|
|
|
|
|
|
## 📱 项目简介
|
|
|
|
|
|
|
2026-02-13 23:04:24 +01:00
|
|
|
|
**岁月留书 Android 应用**是 Life Echo 平台的移动端客户端,提供流畅的语音对话体验和回忆录管理功能。应用采用现代化的 Android 开发技术栈,实现优雅的用户界面和流畅的交互体验。
|
2026-01-26 11:54:03 +08:00
|
|
|
|
|
|
|
|
|
|
### 核心功能
|
|
|
|
|
|
|
|
|
|
|
|
- 🎙️ **实时语音对话** - 通过 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. **克隆项目**
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
git clone <repository-url>
|
|
|
|
|
|
cd life-echo/app-android
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **使用 Android Studio 打开项目**
|
|
|
|
|
|
|
|
|
|
|
|
- 打开 Android Studio
|
|
|
|
|
|
- 选择 `File -> Open`
|
|
|
|
|
|
- 选择 `app-android` 目录
|
|
|
|
|
|
- 等待 Gradle 同步完成
|
|
|
|
|
|
|
|
|
|
|
|
3. **配置 API 地址**
|
|
|
|
|
|
|
|
|
|
|
|
编辑 `app/src/main/java/com/huaga/life_echo/config/AppConfig.kt`:
|
|
|
|
|
|
|
|
|
|
|
|
```kotlin
|
|
|
|
|
|
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 并移除明文流量配置
|
|
|
|
|
|
|
|
|
|
|
|
4. **确保后端服务运行**
|
|
|
|
|
|
|
|
|
|
|
|
确保后端 API 服务已启动并可以访问(参考 [api/README.md](../api/README.md))
|
|
|
|
|
|
|
|
|
|
|
|
5. **运行应用**
|
|
|
|
|
|
|
|
|
|
|
|
- 连接 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 │
|
|
|
|
|
|
└──────────┘ └──────────┘
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 数据流
|
|
|
|
|
|
|
|
|
|
|
|
1. **UI 层(Compose)**:使用 `@Composable` 函数构建界面
|
|
|
|
|
|
2. **ViewModel**:管理 UI 状态,处理用户交互
|
|
|
|
|
|
3. **Repository**:统一数据访问接口,协调本地数据库和网络 API
|
|
|
|
|
|
4. **数据源**:
|
|
|
|
|
|
- **Room Database**:本地 SQLite 数据库(离线数据)
|
|
|
|
|
|
- **Network API**:REST API 和 WebSocket(服务器数据)
|
|
|
|
|
|
|
|
|
|
|
|
### 关键组件
|
|
|
|
|
|
|
|
|
|
|
|
#### TokenManager
|
|
|
|
|
|
|
|
|
|
|
|
管理用户认证令牌:
|
|
|
|
|
|
|
|
|
|
|
|
```kotlin
|
|
|
|
|
|
// 保存 Token
|
|
|
|
|
|
TokenManager.saveTokens(accessToken, refreshToken)
|
|
|
|
|
|
|
|
|
|
|
|
// 获取 Token
|
|
|
|
|
|
val accessToken = TokenManager.getAccessToken()
|
|
|
|
|
|
|
|
|
|
|
|
// 检查登录状态
|
|
|
|
|
|
val isLoggedIn = TokenManager.isLoggedIn
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### WebSocketClient
|
|
|
|
|
|
|
|
|
|
|
|
WebSocket 连接管理:
|
|
|
|
|
|
|
|
|
|
|
|
```kotlin
|
|
|
|
|
|
// 连接 WebSocket
|
|
|
|
|
|
webSocketClient.connect(conversationId, accessToken)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送消息
|
|
|
|
|
|
webSocketClient.sendAudio(audioData)
|
|
|
|
|
|
|
|
|
|
|
|
// 接收消息
|
|
|
|
|
|
webSocketClient.onMessage { message ->
|
|
|
|
|
|
// 处理消息
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### Repository 模式
|
|
|
|
|
|
|
|
|
|
|
|
统一数据访问:
|
|
|
|
|
|
|
|
|
|
|
|
```kotlin
|
|
|
|
|
|
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 设计规范
|
|
|
|
|
|
|
|
|
|
|
|
## 🧪 测试
|
|
|
|
|
|
|
|
|
|
|
|
### 单元测试
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
./gradlew test
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 集成测试
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
./gradlew connectedAndroidTest
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 📦 构建发布
|
|
|
|
|
|
|
|
|
|
|
|
### Debug 构建
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
./gradlew assembleDebug
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Release 构建
|
|
|
|
|
|
|
|
|
|
|
|
1. 配置签名密钥(在 `app/build.gradle.kts` 中)
|
|
|
|
|
|
2. 构建 Release APK:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
./gradlew assembleRelease
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3. 构建 Release AAB(Google Play):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
./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. 测试数据库迁移逻辑
|
|
|
|
|
|
|
|
|
|
|
|
## 📚 相关文档
|
|
|
|
|
|
|
|
|
|
|
|
- [项目根目录 README](../README.md) - 项目总览
|
|
|
|
|
|
- [API 文档](../api/README.md) - 后端 API 文档
|
|
|
|
|
|
- [WebSocket 测试文档](../api/docs/WebSocket快速测试指南.md) - WebSocket 测试指南
|
|
|
|
|
|
|
|
|
|
|
|
## 📄 许可证
|
|
|
|
|
|
|
|
|
|
|
|
MIT License
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-02-13 23:04:24 +01:00
|
|
|
|
**岁月留书 Android** - 让每一段人生故事都被温柔记录 📱✨
|