167 lines
8.0 KiB
Markdown
167 lines
8.0 KiB
Markdown
# duobibi-android
|
||
|
||
多比比(占坑版)Android 客户端。
|
||
|
||
跨平台比价工具:输入商品名,在「比价擂台」里把 淘宝 / 京东 / 拼多多 / 抖音 的到手价
|
||
拉到一张表对比、自动标最低;另配「降价雷达」盯价提醒与「值不值得买」AI 评分。
|
||
也保留在 7 个购物 App 内的悬浮「比价」按钮一键记价(本地存储,喂给擂台)。
|
||
|
||
> **占坑期**:与姊妹品牌「傻瓜比价」复用同一套底层引擎(无障碍+浮窗、Room、Retrofit、
|
||
> 心跳、推送、一键登录),但包名 / 签名 / 配色 / 导航 / 文案 / 功能组合全部独立重做,
|
||
> 通过应用市场"套壳/重复"检测与"功能过于简单"审核。
|
||
|
||
## 技术栈
|
||
|
||
- Kotlin 2.1 + Jetpack Compose(Material3,BOM 2024.12)
|
||
- minSdk 26 / targetSdk 34 / compileSdk 36
|
||
- JDK 17(`sourceCompatibility = VERSION_17`)
|
||
- Room + Hilt + Retrofit(kotlinx.serialization)+ OkHttp
|
||
- AGP 8.9 / Gradle Wrapper 内置
|
||
- 包名 `com.jishisongfu.duobibi`,版本 `1.0.0` (versionCode 1)
|
||
- 小米推送 SDK 7.9.2 + 极光 jverification 3.1.7(ABI:armeabi-v7a / arm64-v8a)
|
||
|
||
## 工程结构
|
||
|
||
```
|
||
app/src/main/java/com/jishisongfu/duobibi/
|
||
├── DuobibiApplication.kt # @HiltAndroidApp
|
||
├── MainActivity.kt # 单 Activity:隐私同意 → onboarding → AppNavHost
|
||
├── di/ # Hilt: DatabaseModule / NetworkModule
|
||
├── data/
|
||
│ ├── db/ # Room v1: Cluster / PriceRecord / PriceAlert + DAO
|
||
│ ├── api/ # Retrofit: Parse / Ocr / Protect / Auth / Arena / WorthBuy
|
||
│ └── repo/PriceRepository.kt # 业务编排:记价入库 + 擂台 + 值不值 + 雷达查价
|
||
├── service/
|
||
│ ├── PriceBotAccessibilityService # 监听窗口切换 + 抓取页面控件树
|
||
│ └── FloatingWindowService # 前台服务,承载比价浮窗(自我修复)
|
||
├── floating/ # AccessibilityServiceHolder / FloatingButtonView / TreeSerializer
|
||
├── heartbeat/ # 心跳上报(AlarmManager,占位 PoC)
|
||
├── push/ # 小米推送 bootstrap + receiver
|
||
├── auth/ # 极光一键登录(JgInit / OneClickLogin / PhoneBindViewModel)
|
||
├── ui/
|
||
│ ├── theme/ # DbbColors(蓝青)+ DuobibiTheme
|
||
│ ├── nav/AppNavHost.kt # 5 Tab + 详情路由
|
||
│ ├── arena/ # 比价擂台(首屏 Hero)
|
||
│ ├── alert/ # 降价雷达(想买的 / 已买的)
|
||
│ ├── worth/ # AI 值不值得买
|
||
│ ├── records/ # 记录列表 / 商品组详情 / 趋势图 / 手动记一笔
|
||
│ ├── mine/ # 我的:账号绑定 / 权限 / 自检 / 关于
|
||
│ ├── onboarding/ + privacy/ # 首启引导 + 隐私同意/政策
|
||
│ └── tools/ # 单价对比 / 凑单 / 分期真实利率
|
||
└── util/ # Constants / *Prefs / PermissionUtil / AlertNotifier / DemoDataSeeder ...
|
||
```
|
||
|
||
## 底部 5 Tab
|
||
|
||
| Tab | 内容 |
|
||
|---|---|
|
||
| 比价 | **比价擂台**:搜商品 → 多平台到手价对比表,标最低,可一键跳最低价平台搜 |
|
||
| 雷达 | **降价提醒雷达**:想买的(设心理价)/ 已买的(盯价保),降价推送提醒 |
|
||
| 值不值 | **AI 值不值得买**:输入商品+到手价 → 评分 + 建议 + 更划算时机 |
|
||
| 记录 | 浮窗 / 手动记的价格,按商品组聚合,看趋势图 |
|
||
| 我的 | 账号一键登录、权限、算价工具、自检、关于、隐私 |
|
||
|
||
## 关键设计
|
||
|
||
### 比价擂台(首屏 Hero)
|
||
|
||
搜索 → 调后端 `/arena-quote` 得各平台 AI 估到手价 + 市场常见价;若本机记录过同款,
|
||
本机真实价直接覆盖对应平台行并标「本机」,最低行高亮。
|
||
|
||
### 浮窗显隐 + 自我修复
|
||
|
||
`AccessibilityService` 监听 `TYPE_WINDOW_STATE_CHANGED`,在代码层比对
|
||
`Constants.WHITELIST_PACKAGES`(7 个购物 App)决定浮窗显隐;`FloatingWindowService.notifyVisibility`
|
||
在服务被杀后能按白名单事件自动重启。浮窗按钮为蓝青「比价」圆钮。
|
||
|
||
### 无障碍只读
|
||
|
||
无障碍只在用户点击浮窗时被动抓取一次当前页面控件树,不做任何自动点击 / 输入 / 滑动等代操作。
|
||
`accessibility_service_config.xml` 仅声明 `TYPE_WINDOW_STATE_CHANGED`,不申请截屏与手势权限。
|
||
|
||
### 降价雷达
|
||
|
||
`PriceAlert`(mode = WANT / BOUGHT)统一承载「想买的设心理价」与「已买的盯价保」。
|
||
后台复用 `/track-price` 估当前价,跌破锚价即 `AlertNotifier` 本地通知。
|
||
|
||
### 算价工具(纯本地计算,不联网)
|
||
|
||
- **单价对比**:g/kg/ml/L/件 统一换算成 100g·100ml·件 单价
|
||
- **凑单计算器**:阶梯满减 300-50 / 600-100 / 1000-200 / 1500-300,提示"再凑 X 反而少花 Y"
|
||
- **分期真实利率**:二分法求月 IRR × 12,揭穿"月费率 × 12"低估的名义年化
|
||
|
||
### 隐私
|
||
|
||
首启全屏同意页(不同意即退出);价格记录默认仅存本机(Room),仅在主动记价 / 擂台 / 值不值时
|
||
临时联网识别,不持久化。卸载即清。
|
||
|
||
## 配置
|
||
|
||
- **后端域名**:`app/build.gradle.kts` → release `BASE_URL = "https://api.duobibi.com/"`,
|
||
debug `BASE_URL = "http://127.0.0.1:8766/"`,强制 HTTPS(`usesCleartextTraffic="false"`)
|
||
- **release 签名**:不硬编码,从 `gradle.properties` / `-P` 注入
|
||
`DUOBIBI_KEYSTORE / DUOBIBI_STORE_PASSWORD / DUOBIBI_KEY_ALIAS / DUOBIBI_KEY_PASSWORD`;
|
||
未配置时 debug 走默认 debug.keystore,可直接 `assembleDebug`
|
||
- **三方 key**(占位,上线前到对应控制台注册「多比比」新应用替换):
|
||
`build.gradle.kts` 的 `JPUSH_APPKEY`、`push/MiPushBootstrap.kt` 的小米 AppID/Key
|
||
- **白名单包名**:`util/Constants.kt`(7 个购物 App)
|
||
|
||
## 构建与启动
|
||
|
||
**环境要求**
|
||
|
||
- JDK 17(`compileOptions.sourceCompatibility = VERSION_17`)
|
||
- Android Studio Hedgehog (2023.1) 及以上
|
||
- Android SDK Platform 34(targetSdk)/ 36(compileSdk)
|
||
- 测试设备:Android 8.0 (API 26) 及以上
|
||
|
||
**1. 同步项目**
|
||
|
||
用 Android Studio 直接 Open 本目录,首次同步会自动生成 `local.properties` 指向你的 Android SDK。
|
||
|
||
**2. 构建 APK**
|
||
|
||
```bash
|
||
./gradlew :app:assembleDebug # debug 包,开箱即用
|
||
./gradlew :app:assembleRelease # 需先配置 DUOBIBI_KEYSTORE 等签名属性
|
||
```
|
||
|
||
**3. 安装到设备**
|
||
|
||
```bash
|
||
./gradlew :app:installDebug # 编译并安装到当前连接的设备
|
||
# 或手动安装已有 apk:
|
||
adb install app/build/outputs/apk/debug/app-debug.apk
|
||
```
|
||
|
||
**4. 联调本地后端(debug 模式必做)**
|
||
|
||
debug 包的 `BASE_URL` 为 `http://127.0.0.1:8766/`(见 `app/build.gradle.kts`),需先启动后端,再把设备的 8766 反向映射到 PC:
|
||
|
||
```bash
|
||
adb reverse tcp:8766 tcp:8766
|
||
```
|
||
|
||
release 包直接走 `https://api.duobibi.com/`,无需此步。
|
||
|
||
## 真机调试关键步骤
|
||
|
||
安装后,首次打开 App:
|
||
|
||
1. 阅读并同意隐私 → 看 4 屏引导
|
||
2. 进入「我的」Tab,挨个开三项权限:
|
||
- 无障碍服务 → 系统设置 → 已下载的服务 → 找到「多比比」→ 开启
|
||
- 悬浮窗 → 系统授权页直接开
|
||
- 自启动 → 跳厂商自启动管理页(识别失败有 toast 提示手动)
|
||
3. 「比价」Tab 输入商品名 → 看多平台对比表
|
||
4. 切到 淘宝 / 京东 / 拼多多 / 抖音 / 美团 / 美团外卖 / 饿了么 任意商品页 →
|
||
点蓝色「比价」浮窗 → toast「已记 ¥XX(平台)」→ 回 App「记录」Tab 查看,并自动进入擂台对比
|
||
5. 「雷达」加一条想买的设心理价;「值不值」输入商品+价格看 AI 评分
|
||
|
||
## 待办(占坑期遗留)
|
||
|
||
- 三方 key(极光 / 小米 AppKey、智谱 LLM)需注册「多比比」新应用后替换占位值
|
||
- release 签名属性 `DUOBIBI_KEYSTORE` 未配置时 release 无签名(debug 不受影响)
|
||
- 心跳 `HEARTBEAT_BASE_URL` 仍是局域网占位 IP(`192.168.0.109:8766`),生产化需改真后端 https
|
||
- 极光一键登录在控制台按"包名+签名 MD5"校验,真机联调登录请用配置了 `DUOBIBI_KEYSTORE` 的 release 包
|