Files
DadaoTask/android/README.md
T
steven d7c9670880
CI / backend (push) Canceled after 0s
feat(design): 主色改靛蓝 #4F46E5,Web 与安卓及 Logo 同步
- primary 换成 Indigo 阶(600 即 #4F46E5),中性色转 Slate 轴、纸面更冷更白
- 实心主色面(主按钮、工作区选中)用 600,链接/浅底文字仍用 700 保对比度
- 信息色 sky 调深到 #16697C,与靛蓝同屏能分清
- Logo / favicon / PWA 图标 / 安卓自适应图标统一为靛蓝底 + 白线 + 淡紫点,tools/make-icons.py 重新生成
- 文档与 e2e 断言同步(主题色 #4f46e5)
2026-11-02 15:33:26 +08:00

130 lines
6.5 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
```
首次打开 → 手机号登录(开发环境验证码在接口响应里回显,形如 `开发环境验证码: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、无连接设备),端到端只验证到"能编译、能装"。