# 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 包
