Files
2026-05-29 13:27:41 +08:00

167 lines
8.0 KiB
Markdown
Raw Permalink 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.
# 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 包