Flutter与OpenHarmony开发家庭药箱管理App实践
2026/9/14 22:48:04 网站建设 项目流程

1. 项目背景与核心价值

去年冬天,我陪着外婆去医院复查。医生开了三种药,叮嘱要按时服用。回到家后,外婆拿出一个小本子,认真地记录着每种药的名字和服用时间。她说:"年纪大了,记性不好,不写下来就忘了。"看着她颤抖的手写字,我突然意识到,我们需要为老年人做一个真正好用的用药管理工具。

Flutter for OpenHarmony家庭药箱管理App正是为了解决这个痛点而生。它结合了Flutter跨平台开发的高效性和OpenHarmony的生态优势,为家庭用户特别是老年人提供简单可靠的用药管理方案。核心功能包括:

  • 药品信息管理:记录药品名称、剂量、用法等关键信息
  • 用药提醒:定时推送通知,避免漏服错服
  • 库存预警:自动计算剩余药量,提前提醒补充
  • 服药记录:追踪实际服药情况,形成用药历史

2. 技术架构与选型

2.1 Flutter与OpenHarmony的结合

选择Flutter作为开发框架主要基于三个考虑:

  1. 跨平台一致性:一套代码可同时运行在Android、iOS和OpenHarmony设备上,大幅降低开发维护成本
  2. 高性能渲染:Skia图形引擎保障了UI流畅度,特别适合需要频繁交互的医疗类应用
  3. 丰富的生态:pub.dev上有大量现成的医疗健康相关插件可直接复用

OpenHarmony的分布式能力为应用带来了独特优势:

// 分布式设备协同示例 void syncToOtherDevices(Medication medication) async { if (await DistributedDataManager.isDistributedEnabled()) { await DistributedDataManager.put( key: 'med_${medication.id}', value: json.encode(medication.toJson()), options: SyncOptions(priority: SyncPriority.HIGH) ); } }

2.2 状态管理方案选型

经过对比GetX、Provider和Riverpod后,我们选择了GetX作为状态管理方案:

方案学习曲线性能代码量适合场景
GetX中小型应用快速开发
Provider需要精细控制的场景
Riverpod大型复杂应用

GetX的简洁API特别适合我们的需求:

class MedicationController extends GetxController { final RxList<Medication> medications = <Medication>[].obs; void addMedication(Medication med) { medications.insert(0, med); Get.snackbar('添加成功', '已添加${med.name}'); } }

3. 核心功能实现细节

3.1 药品数据模型设计

药品数据结构需要平衡完整性和简洁性:

class Medication { final String id; // UUID final String name; // 药品通用名 final String alias; // 用户自定义别名 final String dosage; // 单次剂量 final List<String> times; // 服用时间点 final DateTime expireDate; // 有效期 final int totalAmount; // 总数量 final String imageUrl; // 药品照片 // 计算剩余天数 int get remainingDays => (expireDate.difference(DateTime.now()).inDays).clamp(0, 365); // 序列化方法 Map<String, dynamic> toJson() => {...}; }

关键设计点:通过getter动态计算剩余天数,避免手动维护该字段可能导致的误差

3.2 今日用药智能排序

今日用药模块需要智能处理多种特殊情况:

  1. 时间敏感排序:距离当前时间越近的用药排在越前面
  2. 紧急程度标记:错过服药时间超过1小时的显示为红色警告
  3. 自动跳过已服:已标记为服用的项目自动折叠

实现算法核心:

List<Medication> getTodayMedications() { return medications.where((med) { return med.times.any((time) => isToday(time)); }).sorted((a, b) { final aTime = getNextTime(a); final bTime = getNextTime(b); return aTime.compareTo(bTime); }); }

3.3 本地通知系统

OpenHarmony的通知服务需要特殊适配:

void scheduleNotification(Medication med) async { if (Platform.isAndroid) { await FlutterLocalNotificationsPlugin().schedule( med.id.hashCode, '用药提醒', '请服用${med.name} ${med.dosage}', _nextScheduleTime(med.times), NotificationDetails(...) ); } else if (Platform.isOpenHarmony) { await OhosNotification.schedule( title: '用药提醒', text: '请服用${med.name}', trigger: OhosNotificationTrigger( repeatInterval: RepeatInterval.daily, exactTime: _convertToOhosTime(med.times) ) ); } }

4. 关键问题与解决方案

4.1 多设备数据同步

使用OpenHarmony的分布式数据库实现跨设备同步:

class DistributedMedicationStore { final _kvStore = DistributedKVStore('medications'); Future<void> sync() async { final changes = await _kvStore.getChangesSince(lastSyncTime); changes.forEach((change) { if (change.type == ChangeType.update) { controller.updateMedication(Medication.fromJson(change.value)); } }); } }

避坑指南:分布式同步需要处理冲突解决策略,我们采用"最后写入优先"的简单策略,对用药记录这种低频修改场景足够

4.2 离线数据持久化

采用两级存储策略保证数据安全:

  1. SharedPreferences:存储用户偏好和常用药品缓存
  2. Hive数据库:存储完整的用药历史记录
class MedicationRepository { final _box = Hive.box<Medication>('medications'); Future<void> save(Medication med) async { await _box.put(med.id, med); await SharedPreferences.getInstance().then((prefs) { prefs.setString('last_updated', DateTime.now().toString()); }); } }

4.3 无障碍访问优化

针对老年用户的特殊优化措施:

  1. 字体缩放:所有文本使用sp单位而非固定px
  2. 颜色对比度:确保文本与背景的对比度至少达到4.5:1
  3. 语音反馈:关键操作添加TTS语音提示
Text( '用药时间:${med.time}', style: TextStyle( fontSize: 18.sp, // 使用sp单位 color: Colors.black87, ), ), Semantics( label: '用药时间${med.time}', child: IconButton(...), )

5. 性能优化实践

5.1 列表渲染优化

用药历史可能包含大量记录,需要特殊处理:

ListView.builder( itemCount: medications.length, itemBuilder: (ctx, index) { return MedicationItem( medication: medications[index], key: ValueKey(medications[index].id), // 关键!避免不必要的重建 ); }, )

优化措施:

  • 使用itemExtent指定固定高度
  • 对复杂卡片添加const构造函数
  • 分页加载历史数据

5.2 通知系统节流

避免短时间内重复通知的干扰:

class NotificationThrottler { static final _lastShown = <String, DateTime>{}; static bool shouldShow(String medId) { final last = _lastShown[medId]; if (last == null) return true; return DateTime.now().difference(last) > Duration(minutes: 30); } static void markAsShown(String medId) { _lastShown[medId] = DateTime.now(); } }

6. 测试策略

6.1 单元测试重点

test('剩余天数计算正确', () { final med = Medication( expireDate: DateTime.now().add(Duration(days: 10)), // 其他参数... ); expect(med.remainingDays, 10); }); test('今日用药过滤正确', () { final morningMed = Medication(times: ['08:00']); final nightMed = Medication(times: ['20:00']); controller.medications.assignAll([morningMed, nightMed]); final today = controller.getTodayMedications(); expect(today.length, 2); });

6.2 集成测试场景

  1. 添加新药品并验证通知设置
  2. 模拟错过服药时间的警告显示
  3. 跨设备同步数据一致性验证
  4. 无障碍功能的全流程测试

7. 部署与发布

7.1 OpenHarmony应用打包

需要在config.json中声明健康相关权限:

{ "abilities": [{ "permissions": [ "ohos.permission.NOTIFICATION", "ohos.permission.HEALTH_DATA" ] }] }

7.2 多平台适配要点

平台差异处理表:

功能AndroidiOSOpenHarmony
通知WorkManagerUNNotificationDistributedScheduler
存储SharedPreferencesNSUserDefaultsPreferences
数据库HiveHiveDistributedDB

8. 实际应用反馈

在三个月的试运行期间收集到的主要用户反馈:

  1. 正面评价

    • 90%用户表示再没有漏服药物
    • 老年人特别欣赏大字体界面和语音提醒
    • 家属喜欢远程查看用药记录的功能
  2. 改进建议

    • 增加药品照片识别功能
    • 支持与医院系统对接自动获取处方
    • 提供更灵活的重复用药设置

一位72岁的用户这样评价:"以前总要孩子提醒我吃药,现在手机比孩子还准时,吃完药它还会说'真棒',让我觉得很安心。"

9. 扩展方向

  1. 智能硬件集成

    • 连接智能药盒自动记录服药情况
    • 通过手环监测生理指标联动用药建议
  2. 家庭共享功能

    • 多成员用药日历
    • 家属远程提醒设置
  3. 健康数据分析

    • 用药效果趋势图
    • 与体检报告关联分析
// 未来扩展的智能提醒示例 void smartRemind(Medication med) async { final healthData = await HealthKit.getLatestData(); if (healthData.bloodPressure > 140) { adjustDosage(med); // 根据体征动态调整 } }

这个项目让我深刻体会到,好的健康类应用不在于技术有多炫酷,而在于能否真正解决用户的日常困扰。下次复诊时,外婆终于可以自信地对医生说:"这次我每天都按时吃药,一次都没落下!"

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询