Files
DadaoTask/android/README.md
T
steven 29805bd61e
CI / backend (push) Canceled after 0s
feat(android): 登录改手机号/邮箱+密码并支持邮箱注册,知识分类可改名配色删除
- 生产已关短信登录,登录页先读 /auth/methods 再决定入口:默认手机号/邮箱+密码,
  后端开着短信时才出现验证码登录;邮箱账号 phone 为空,User.phone 改可空
- 新增邮箱验证码注册(一步建号即登录态)
- 知识:分类色点/选中描边/加载态,管理面板可改名、选色(10 色板或手填 hex)、
  建子分类、删除(知识回到未分类),卡片上边线用分类色
- 正文 16sp / 行高 1.7,列表标题 SemiBold,与 Web 阅读排版对齐
- README 更新登录方式与结构说明
2026-11-05 15:55:31 +08:00

132 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 安卓端
Kotlin + Jetpack Compose。功能与 Web 端同构:登录 → 工作区 → 任务 / 工单 / 知识。
## 它已经能编译出 APK 了(本机实测)
```
BUILD SUCCESSFUL in 38s
app/build/outputs/apk/debug/app-debug.apk 9.94 MB
```
而且**真的在模拟器上跑通了**:登录 → 建工作区 → 任务列表(中文标题、状态、截止日、勾选完成)→ 工单列表 → 知识列表,全部打到真实后端。
| 登录 | 任务列表 |
|---|---|
| ![登录](../2.Design/screens/android-login.png) | ![任务](../2.Design/screens/android-tasks.png) |
一键起模拟器 + 装包(环境变量都替你设好了):
```bash
pwsh -File android/scripts/emulator.ps1 -Install
```
本机从零把编译链搭起来踩过的坑都固化在仓库里了,别再走一遍:
| 现象 | 原因 | 仓库里的解法 |
|---|---|---|
| `Failed to load native library 'native-platform.dll'` | 旧 `~/.gradle` 缓存坏了 | 用独立 `GRADLE_USER_HOME`(我用的 `.local/gradle-home`) |
| `validateSigningDebug: AccessDeniedException debug.keystore.lock` | 沙箱/受限用户对 `~/.android` 无写权限 | 工程内 keystore:`android/keystore/debug.keystore`,`app/build.gradle.kts` 显式指向 |
| `compileDebugKotlin: AccessDeniedException %TEMP%\kotlin-compiler-*.alive` | `%TEMP%` 不可写 | 构建前把 `TEMP`/`TMP` 指到工程内可写目录 |
| `Could not connect to Kotlin compile daemon` | 受限环境里 Kotlin 编译守护进程连不回来 | `gradle.properties` 里 `kotlin.compiler.execution.strategy=in-process` |
| 依赖下载极慢(5 分钟 2MB) | Google Maven 直连慢 | `settings.gradle.kts` 先走阿里云镜像,再回落 google/mavenCentral |
需要:**JDK 17**(`JAVA_HOME`)、Android SDK **platform 35** + build-tools。
```bash
cd android
gradle :app:assembleDebug # 或 ./gradlew(wrapper 需 Android Studio 补齐)
```
## 连不上后端?先看这三件事
1. **后端要监听所有网卡**:`uvicorn app.main:app --host 0.0.0.0 --port 8100`。
默认的 `127.0.0.1` 只有本机可见,手机连不上。
2. **地址要填对**:包里的默认值是模拟器地址 `http://10.0.2.2:8100`。
真机在登录页点「改地址」填电脑的局域网 IP(如 `http://192.168.8.151:8100`),
点「测试连接」看到「连得通」再登录。改一次会记住,不用重新打包。
3. **防火墙**:Windows 没弹过「允许访问」的话,手机包会被丢。管理员 PowerShell 执行
`New-NetFirewallRule -DisplayName "DadaoTask backend 8100" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8100 -Profile Private`。
还有一个容易查半天的点:主清单配了 `network_security_config`(白名单只有
`10.0.2.2/127.0.0.1/localhost`),这种情况下 `android:usesCleartextTraffic="true"` **不生效**,
真机连 `http://192.168.8.x` 会被系统拦成 "CLEARTEXT communication not permitted",
表现就是"点了登录没反应/登录不上去",而模拟器一切正常。
所以 `android/app/src/debug/res/xml/network_security_config.xml` 单独给 debug 放开了明文,
release 依旧只走 HTTPS 白名单。
## 连哪个后端
`android/local.properties`(不入库):
```properties
dadao.apiBase=http://10.0.2.2:8100 # 模拟器访问宿主机
# dadao.apiBase=http://192.168.8.160:8100 # 真机走局域网
```
真机调试时后端必须监听 `0.0.0.0` 而不是 `127.0.0.1`:
```bash
uvicorn app.main:app --host 0.0.0.0 --port 8100
```
`app/src/debug/AndroidManifest.xml` 对 debug 变体放开了明文 HTTP——
release 仍然只允许 `network_security_config.xml` 里列出的域,别把这条挪到 main。
## 安装到手机
```bash
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
首次打开 → **手机号或邮箱 + 密码**登录(短信验证码登录默认关闭;开发环境需要验证码登录时,
后端设 `INTERNAL_TEST_LOGIN=true`,固定验证码 `123456`,登录页会自动出现「验证码登录」切换)。
没有账号就点「用邮箱注册」:收邮箱验证码 → 设密码 → 直接进工作区。
## 结构
```
app/src/main/java/com/dadao/task/
├── MainActivity.kt 入口 + Splash/Login/Home/Tasks/Knowledge 路由
├── data/
│ ├── Api.kt OkHttp + kotlinx.serialization;信封解包、业务码抛 ApiException
│ └── TokenStore.kt 令牌本地存储(TODO:换 EncryptedSharedPreferences)
└── ui/
├── Theme.kt 与 Web 一致的靛蓝 #4F46E5 + 陶土色板
├── LoginScreen.kt 手机号/邮箱 + 密码(短信登录只在后端开启时出现)、邮箱验证码注册
├── HomeScreen.kt 工作区列表 / 新建 / 生成邀请码
├── TaskListScreen.kt 任务视图切换、快速新建、勾选完成、详情与评论
└── KnowledgeScreen.kt 知识四态 tab、手记、按状态给动作(发布需 owner/admin)、分类管理与配色
```
## 模拟器(本机搭建记录,别重复踩)
`sdkmanager` 在这台机器上拉不到远端仓库索引(`Failed to download any source lists!`,但直连
`dl.google.com` 的 zip 是通的),所以系统镜像是**手动装的**:
1. 下 `https://dl.google.com/android/repository/sys-img/google_apis/x86_64-35_r09.zip`(1.66 GB),
解压到 `%LOCALAPPDATA%\Android\Sdk\system-images\android-35\google_apis\x86_64`
—— 注意压缩包里还有一层 `x86_64/`,要**把内容提上一层**,否则 AGP 找不到 `system.img`。
2. 建 AVD 时把用户目录指到工程内(`~/.android` 在受限用户下不可写):
```powershell
$env:ANDROID_USER_HOME="$repo\.local\android-user"
$env:ANDROID_AVD_HOME="$repo\.local\android-avd"
avdmanager create avd -n dadao -k "system-images;android-35;google_apis;x86_64" -d pixel_6 --force
```
3. 启动必须带 `-no-window -gpu swiftshader_indirect`(无头环境下 GL 走软件渲染);
`emulator -accel-check` 应显示 `WHPX ... installed and usable`。
驱动模拟器点按不要凭截图猜坐标——`adb shell input tap` 用的是**物理像素**,而截图常被降采样。
用 `adb shell uiautomator dump` 拿 `bounds` 最稳。另外 `adb shell input text` 打不了中文(会 NPE),
中文数据走接口造。
## 已知待办
- 工单页还没做(Web 已有):需要"我指派的 / 我发起的"两栏 + 接收/开工/提交/验收按钮;
接口在 `Api.kt` 里已经齐了(`tickets` / `ticketAction` / `verifyTicket` / `promote`)。
- 明文令牌存储(`TokenStore` 里已标 TODO)。
- 无离线缓存,弱网直接报错——与产品 D7「在线优先」一致。
- 邀请链接 `https://dadaotask.com/join/<wsId>/<code>` 已在 Manifest 注册,落地处理尚未实现。
- 未在本机跑过模拟器(无 system-image、无连接设备),端到端只验证到"能编译、能装"。