# 叮康 **Repository Path**: wangyidao/healthy-buzzer ## Basic Information - **Project Name**: 叮康 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-12 - **Last Updated**: 2026-10-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 叮康(DingKang)· 老人血压与吃药提醒 App 面向**老年人**及其**照护家人**的健康提醒工具:定时提醒测量血压、定时提醒吃药,并支持**拍照 + 手动录入**记录每次血压,帮助老人与家人掌握健康趋势。 - **包名 / 命名空间**:`com.dingkang` - **平台**:Android(原生 Kotlin + Jetpack Compose),`minSdk 24`(Android 7.0)~ `targetSdk 35`(Android 15) - **设计稿**:https://ardot.tencent.com/file/734496402559662 - **完整设计开发文档**:[叮康_设计开发文档.md](叮康_设计开发文档.md) --- ## 一、功能特性 | 模块 | 功能 | |---|---| | 首页 | 今日待办:血压提醒卡(一键「立即测量」)+ 吃药提醒卡(逐条状态)+ 拍照快捷入口 + 问候语 | | 测量血压 | 相机拍照留存 + 收缩压/舒张压/心率三栏大输入框 + 范围校验 + 自动状态判定(正常/偏高) | | 记录 | 血压记录趋势:周 / 月 / 年切换 + 折线趋势图(MPAndroidChart)+ 记录列表(照片缩略 + 数值 + 状态色) | | 提醒 | 我的用药:添加药品、设定每天服药时间、列表展示、一键「标记完成」 | | 到点提醒 | 全屏闹钟界面 + 响铃振动,点「完成」结束;未被关闭则每 5 分钟重复响铃 | | 我的 | 个人档案、字体大小(全局放大,适老化)、关于我们 | | 适老化 | 大字体(18–26sp 正文/标题)、大点击区(按钮 ≥48dp)、高对比配色、核心动作 2 步内可达 | > **无默认提醒**:所有提醒均由用户在「提醒」页显式添加;启动时会清理历史遗留的默认规则,确保"列表里看不到的提醒绝不会偷偷响"。 --- ## 二、技术栈 | 层面 | 技术 | |---|---| | 语言 / 构建 | Kotlin 2.1.0 · Gradle 8.12(Kotlin DSL) · AGP 8.9.1 · KSP 2.1.0-1.0.29 | | UI | Jetpack Compose(BOM 2025.01.01)+ Material3 + Navigation Compose + Material Icons Extended | | 架构 | 单 Activity + Compose 导航;MVVM(ViewModel + StateFlow);手工依赖注入(`AppContainer`) | | 本地存储 | Room 2.6.1(SQLite)+ DataStore Preferences(设置项) | | 相机 | CameraX 1.3.4 + ExifInterface 1.3.7(读取拍摄方向) | | 图表 | MPAndroidChart v3.1.0 | | 提醒 | `AlarmManager.setAlarmClock` + `AlarmReceiver` + `BootReceiver` + 全屏 `AlarmActivity` | | 主题 | `ui/theme`(Color / Type / Dimensions),字体倍率全局生效 | --- ## 三、环境要求 - **JDK 21**(例如 `D:\program\Java\jdk-21.0.4`) - **Android SDK**(API 35 及以上),本地路径在 `local.properties` 中声明: ```properties sdk.dir=D:/program/Android/Sdk ``` > `local.properties` 含本机路径,已由 `.gitignore` 忽略,请各机器自行创建。 - Gradle 依赖走阿里云镜像(见 `settings.gradle.kts`),国内构建更快;无需手动安装 Gradle,使用仓库自带 `gradlew` 即可。 --- ## 四、构建与运行 ```powershell # Windows PowerShell $env:JAVA_HOME = "D:\program\Java\jdk-21.0.4" $env:PATH = "$env:JAVA_HOME\bin;$env:PATH" # 编译 debug 包 cd d:\gitlab\dingkang .\gradlew.bat assembleDebug # 安装到已连接设备(adb) $env:PATH += ";D:\program\Android\Sdk\platform-tools" adb install -r app\build\outputs\apk\debug\app-debug.apk # 或直接运行(debug 签名) .\gradlew.bat installDebug ``` 产物位置:`app/build/outputs/apk/debug/app-debug.apk` > Release 包当前复用 debug 签名(内部测试可直接出包),正式发布请在 `app/build.gradle.kts` 中替换为自己的 release keystore。Release 已开启 R8 混淆与资源压缩,仅保留 `arm64-v8a` / `armeabi-v7a` 架构。 --- ## 五、权限说明(重要) 提醒能否**准时响铃**,与以下权限强相关: | 权限 | 用途 | 说明 | |---|---|---| | `SCHEDULE_EXACT_ALARM` / `USE_EXACT_ALARM` | 精确闹钟 | 到点必响,不受 Doze/后台限制 | | `POST_NOTIFICATIONS` | 通知(Android 13+) | 运行时申请 | | `USE_FULL_SCREEN_INTENT` | 锁屏全屏弹闹钟界面 | 系统授予 | | `CAMERA` | 拍照记录血压 | 按需申请 | | `READ_MEDIA_IMAGES` / `READ_EXTERNAL_STORAGE(≤32)` | 相册选图 | 按需申请 | | `RECEIVE_BOOT_COMPLETED` | 重启后重排所有提醒 | 静默 | | **`REQUEST_IGNORE_BATTERY_OPTIMIZATIONS`** | **忽略电池优化** | ⚠️ 见下方说明 | ### ⚠️ 为什么必须"忽略电池优化" Android/Flyme 等系统在后台会**冻结(freeze)**非白名单应用。被冻结后,闹钟到点时系统会直接 `skip schedule Receiver` **丢弃闹钟广播**,表现为"提醒设了却完全不响"。 因此: - App 首次启动时,`MainActivity` 会检测白名单状态,未加入则弹窗引导「请允许后台运行」,一键跳转系统"忽略电池优化"确认框; - 部分国产 ROM(如 Flyme)还需在系统设置中额外允许 **自启动 / 后台弹出界面**。 --- ## 六、项目结构 ``` dingkang/ ├── app/ │ └── src/main/java/com/dingkang/ │ ├── DingKangApplication.kt # 入口:初始化容器、通知渠道、重排提醒、清理默认规则 │ ├── AppContainer.kt # 手工依赖注入(Repository / Scheduler / DataStore) │ ├── data/ │ │ ├── datastore/ # SettingsDataStore(字体倍率等) │ │ ├── local/ # Room:AppDatabase / Dao / Entity │ │ │ ├── entity/ # ElderProfile / Medication / MedicationLog │ │ │ │ # BpMeasurement / ReminderRule │ │ │ └── dao/ # Bp / Elder / Medication / MedicationLog / ReminderRule │ │ └── repository/ # BpRepository / MedicationRepository / ProfileRepository │ ├── domain/ # BpStatus(血压状态判定) │ ├── receiver/ │ │ ├── AlarmReceiver.kt # 响铃:拉起全屏界面 + 通知兜底 + 续排明日 + 重复链 │ │ └── BootReceiver.kt # 开机/升级后重排所有提醒 │ ├── ui/ │ │ ├── navigation/AppNav.kt # 底部 4 Tab:首页 / 记录 / 提醒 / 我的 │ │ ├── main/ # 各页面 Screen + ViewModel + AlarmActivity │ │ ├── components/Components.kt# 复用 UI 组件 │ │ └── theme/ # Color / Type / Dimensions / Theme │ └── util/ │ ├── AlarmScheduler.kt # 闹钟调度(三条独立链) │ ├── DateTimeUtil.kt # 时间解析(HH:mm → 今日/明日时间戳) │ └── FileUtil.kt # 照片文件存取 ├── gradle/ # Gradle Wrapper ├── build.gradle.kts / settings.gradle.kts └── local.properties # 本机 SDK 路径(不入库) ``` --- ## 七、提醒机制说明 `AlarmScheduler` 将提醒拆为**三条互不干扰的链**,各自使用独立 key(`medId#HH:mm`): | 链 | key 后缀 | 触发方式 | 说明 | |---|---|---|---| | 每日提醒 | `medId#HH:mm` | `setAlarmClock` | 今天该时刻未到则排今天,否则排明天;每次响铃后自动续排下一天,**保证天天响** | | 重复响铃 | `…#rep` | `setExactAndAllowWhileIdle` | 未被手动关闭时,每 5 分钟再响 | | 稍后提醒 | `…#snooze` | `setAlarmClock` | 调度能力保留,但闹铃界面已移除入口(仅用于兼容清理历史遗留的稍后提醒) | - 用户在闹钟界面点**「完成」**:只取消重复/稍后链,**明日提醒照常保留**(旧实现会误删次日提醒导致响一次后失效)。 - 系统时间取设备默认时区,`RTC_WAKEUP` 与时间戳解释一致,无 UTC/本地混用问题。 --- ## 八、开发提示 - 数据库结构变更:修改 `data/local/entity` 后由 KSP 重新生成,注意 Room 迁移策略(当前为开发期可直接清数据)。 - 字体放大:`SettingsDataStore.fontScale` 驱动 `DingKangTheme`,全局 `sp` 生效。 - 调试提醒:可临时在 `DingKangApplication` 排一条"N 分钟后"的提醒做真机验证(验证完记得移除)。