# App Update Check Protocol 本文档定义移动端应用更新检查协议,适用于 Android/iOS。 ## 1. Endpoint - Method: `GET` - Path: `/api/v1/app/check-updates` ## 2. Request Query | 字段 | 类型 | 必填 | 说明 | |---|---|---|---| | `platform` | `android` \| `ios` | 否 | 默认 `ios` | | `channel` | `string` | 否 | 发布渠道,默认 `release` | | `current_version_code` | `int` | 是 | 当前构建号(Android versionCode / iOS buildNumber) | | `current_version_name` | `string` | 否 | 当前展示版本号(如 `0.1.1`) | ## 3. Response ```json { "has_update": true, "update_type": "optional", "latest_version_name": "0.1.1", "latest_version_code": 2, "min_supported_version_code": 1, "download_url": "https://example.com/releases/social-app-android-v0.1.1+2-release.apk", "release_notes": "问题修复和体验优化", "file_name": "social-app-android-v0.1.1+2-release.apk", "file_size": 59768832, "sha256": "" } ``` ## 4. Update Decision Algorithm 后端必须按以下顺序判定: 1. `current_version_code >= latest_version_code` -> `update_type = none` 2. `current_version_code < min_supported_version_code` -> `update_type = required` 3. 其他且 `< latest_version_code` -> `update_type = optional` `has_update = (update_type != "none")` ## 5. Release Manifest 发布清单文件位置:`deploy/static/releases/manifest.json` ```json { "releases": [ { "platform": "android", "channel": "release", "version_name": "0.1.1", "version_code": 2, "min_supported_version_code": 1, "file_name": "social-app-android-v0.1.1+2-release.apk", "release_notes": "问题修复和体验优化", "file_size": 59768832, "sha256": "" } ] } ``` 同一 `platform + channel` 可存在多条记录,服务端按 `version_code` 最大值选最新版。 ## 6. Package Naming Convention Android 安装包命名规范: `social-app-android-v{versionName}+{versionCode}-{channel}.apk` 示例: - `social-app-android-v0.1.1+2-release.apk` - `social-app-android-v0.1.2+3-beta.apk` 规则: - `versionName` 给用户展示(如 `0.1.1`) - `versionCode` 必须严格递增 - `channel` 建议使用 `release` / `beta` 推荐打包命令: ```bash ./deploy/build-android-release.sh \ --backend-host 115.190.63.157 \ --channel release \ --release-notes "问题修复和体验优化" ``` 该脚本会: - 按命名规范生成 APK 文件到 `deploy/static/releases/` - 每次打包自动将 `apps/pubspec.yaml` 的 `buildNumber` 递增 1 并写回 - 自动更新 `deploy/static/releases/manifest.json` - 输出版本号、文件路径和 SHA256 注意: - `versionName`(如 `0.1.0`)由开发者手动维护 - `buildNumber`(如 `+2`)由打包脚本自动递增 ## 7. Android Production Signing And Upgrade Strategy 为了保证 APK 升级是覆盖安装(保留应用数据和登录态),生产环境必须满足以下条件: 1. `applicationId` 保持不变(当前为 `com.xunmee.xisocial`) 2. 所有 `release` 包使用同一套正式签名证书(固定 keystore) 3. `versionCode` 严格递增 若证书变化,Android 通常无法覆盖安装,会要求先卸载旧包再安装新包,导致本地 token/缓存数据丢失。 ### 7.1 Signing Files - 签名配置文件:`apps/android/key.properties`(本地文件,不入库) - 模板文件:`apps/android/key.properties.example` - 证书文件建议:`apps/android/release.jks`(本地文件,不入库) `key.properties` 示例: ```properties storeFile=release.jks storePassword= keyAlias= keyPassword= ``` ### 7.2 Release Build Contract - `apps/android/app/build.gradle.kts` 的 `release` 构建必须使用 `signingConfigs.release` - 当 `apps/android/key.properties` 缺失时,构建必须失败(禁止回退到 debug 签名) ### 7.3 Production Packaging Command ```bash bash deploy/build-android-release.sh \ --backend-host \ --channel release \ --release-notes "" ``` 产物位置: - APK:`deploy/static/releases/social-app-android-v{versionName}+{versionCode}-release.apk` - 清单:`deploy/static/releases/manifest.json` ### 7.4 First Migration To Stable Signing 如果历史版本使用 debug 签名,而新版本改为正式签名: - 首次升级通常需要卸载旧包后安装新包(一次性迁移) - 迁移完成后,后续版本在同签名条件下可覆盖安装并保留登录态 ### 7.5 Operational Checklist (Mandatory) 1. 确认 `applicationId` 未变 2. 确认 `release` 签名证书与上个生产版本一致 3. 确认 `versionCode` 大于上个生产版本 4. 在测试机执行一次覆盖安装验证(旧版登录 -> 升级 -> 登录态保留) 5. 上传新 APK 到 `deploy/static/releases/` 并校验 `manifest.json` 对应条目