HarmonyOS 提醒与设置页实战第四篇:早安提醒、晚间复盘、专注计时和天气信息怎么做

摘要

【知行生活小助手】软件,可以在华为应用市场中下载,或在百度云下载:https://appgallery.huawei.com/app/detail?id=com.example.app_05&channelId=SHARE&source=appshare
生活助手类 APP 想要真正被用户长期使用,不能只停留在“打开时给建议”。它需要主动提醒、专注计时、天气信息、权限管理和隐私说明,才能形成完整的用户体验闭环。本文以“知行生活小助手”为例,深入剖析 ReminderServiceSettingsPreferencesServiceWeatherService 与设置页之间的协作方式,并重点解决 HarmonyOS 开发中三个核心技术难点:

  1. 系统提醒发布与定时器管理:如何正确使用 reminderAgentManager 发布每日重复提醒(早安/晚间)和一次性倒计时提醒,并处理本地状态与系统提醒的同步。
  2. 通知权限与异常处理:如何优雅地处理通知权限申请,并对“缺少系统提醒能力”等底层错误进行用户友好的文案归一化,提升应用健壮性。
  3. 提醒状态修复机制:当用户卸载重装、系统清理或权限变化导致本地开关状态与系统实际提醒不一致时,如何通过 repairDailyReminderState 等机制自动修复,确保功能可靠。

通过本文,你将掌握一套从 UI 配置到系统能力调用的完整提醒与设置页实战方案,避免常见踩坑,打造真正可用的生活助手类应用。## 目录

  1. 设置页在生活助手中的作用
  2. 提醒服务整体设计
  3. 早安提醒与晚间复盘
  4. 专注倒计时提醒
  5. 通知权限与异常提示
  6. 天气信息如何接入首页
  7. 总结

一、设置页在生活助手中的作用

很多项目会把设置页做成“关于我们 + 清除缓存”,但知行生活小助手的设置页承担了更重要的产品职责:

功能 价值
早安提醒 每天主动唤起用户,形成使用习惯
晚间复盘 引导用户回顾今日采纳建议
专注计时 让生活建议落到具体行动
通知权限 确保提醒可以真正触达
数据清理 提供用户控制权
隐私协议 明确本地数据与权限用途

对生活类 APP 来说,“提醒”其实是留存能力的一部分。如果只做推荐,没有提醒,用户很容易忘记再次打开应用。

二、设置页功能结构

设置页建议在文章中配一张实际页面截图,或者至少插入模块结构图。它的功能可以拆成四块:

SettingsPage
├── 权限状态
│   ├── 通知权限
│   └── 系统提醒能力提示
├── 每日提醒
│   ├── 早安提醒
│   └── 晚间复盘
├── 专注计时
│   ├── 计时时长
│   ├── 开始/取消
│   └── 到点提醒
└── 数据与隐私
    ├── 清空历史
    ├── 隐私政策
    └── 用户协议

这段结构能帮助读者快速理解:设置页不是边缘页面,而是整个生活助手的“后台控制台”。

三、提醒服务整体设计

项目中提醒能力集中在 ReminderService

在这里插入图片描述

import reminderAgentManager from '@ohos.reminderAgentManager';
import notification from '@ohos.notification';
import notificationManager from '@ohos.notificationManager';

export class ReminderService {
  private static _instance: ReminderService | null = null;

  static getInstance(): ReminderService {
    if (!ReminderService._instance) {
      ReminderService._instance = new ReminderService();
    }
    return ReminderService._instance;
  }
}

它负责三类提醒:

  1. 每天早上的早安提醒。
  2. 每天晚上的复盘提醒。
  3. 用户主动启动的专注倒计时。

本地保存的 key 包括:

const KEY_MORNING_ID: string = 'reminderMorningId';
const KEY_EVENING_ID: string = 'reminderEveningId';
const KEY_TIMER_ID: string = 'reminderTimerId';
const KEY_TIMER_END_MS: string = 'reminderTimerEndMs';

这些 id 的作用是:后续取消、同步、修复状态时能找到系统里已经发布的提醒。

四、早安提醒与晚间复盘

每天重复提醒使用 ReminderRequestAlarm 构造:

private buildAlarmRequest(
  title: string,
  content: string,
  hour: number,
  minute: number,
  notificationId: number
): reminderAgentManager.ReminderRequestAlarm {
  return {
    reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_ALARM,
    hour,
    minute,
    daysOfWeek: [1, 2, 3, 4, 5, 6, 7],
    title,
    content,
    expiredContent: '提醒已过期',
    actionButton: [
      { title: '知道了', type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE }
    ],
    notificationId,
    slotType: notification.SlotType.SERVICE_INFORMATION,
    tapDismissed: true,
    ringDuration: 5,
    snoozeTimes: 0
  };
}

早安提醒文案:

'新的一天,记得喝水、舒展身体,给自己一个小目标'

晚间复盘文案:

'回顾一下今天的小成就,记录一份心情或采纳一条建议'

这两条文案都围绕应用定位:一个在早上推动行动,一个在晚上推动复盘。

五、专注倒计时提醒

专注计时使用 ReminderRequestTimer

private buildTimerRequest(
  seconds: number,
  title: string,
  content: string
): reminderAgentManager.ReminderRequestTimer {
  return {
    reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_TIMER,
    triggerTimeInSeconds: seconds,
    title,
    content,
    expiredContent: '专注时间已到',
    actionButton: [
      { title: '知道了', type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE }
    ],
    notificationId: 10003,
    slotType: notification.SlotType.SERVICE_INFORMATION,
    tapDismissed: true,
    ringDuration: 5,
    snoozeTimes: 0
  };
}

发布倒计时时,会先取消旧计时器,再保存结束时间:

async publishTimer(minutes: number): Promise<void> {
  await this.cancelTimer();
  const seconds = minutes * 60;
  const label = minutes >= 60 ? (minutes / 60) + '小时' : minutes + '分钟';
  const req = this.buildTimerRequest(
    seconds,
    '专注时间到!',
    label + '专注时间结束,记得休息一下'
  );
  await this.publishTimerRequest(req, KEY_TIMER_ID);
  await this.settings.putNumber(KEY_TIMER_END_MS, Date.now() + seconds * 1000);
}

保存 KEY_TIMER_END_MS 的好处是:设置页再次打开时可以判断计时是否仍在进行,而不是只依赖内存变量。

六、通知权限与异常提示

提醒类功能最常见的问题是:代码发布成功了,但用户收不到提醒。原因可能是通知权限没开,也可能是安装包缺少系统提醒能力。

项目中对发布异常做了文案归一:

private normalizePublishError(message: string): string {
  if (message.includes('number of reminders exceeds')) {
    return '当前安装包缺少系统提醒发布能力,请使用已开通 reminder_capability 的签名/Profile 安装包';
  }
  return message;
}

这段处理非常适合写进踩坑小节。因为很多 HarmonyOS 初学者遇到系统能力、Profile、签名相关问题时,会只看到底层英文错误,不知道下一步该怎么处理。

此外,设置页会检查通知是否开启:

const enabled = await notificationManager.isNotificationEnabled();
if (!enabled) {
  await notificationManager.requestEnableNotification(ctx);
}

七、提醒状态修复机制

提醒类功能还有一个隐藏问题:本地开关状态和系统真实提醒状态可能不一致。比如用户卸载重装、系统清理、权限变化后,本地仍显示“已开启”,但系统里提醒已经不存在。

项目中通过 repairDailyReminderState 修复这类问题:

async repairDailyReminderState(settings: AppSettings): Promise<AppSettings> {
  const morningId = await this.settings.getNumber(KEY_MORNING_ID, -1);
  const eveningId = await this.settings.getNumber(KEY_EVENING_ID, -1);
  const morningValid = settings.morningEnabled
    ? await this.hasValidReminder(morningId)
    : false;
  const eveningValid = settings.eveningEnabled
    ? await this.hasValidReminder(eveningId)
    : false;

  if (settings.morningEnabled && !morningValid) {
    await this.settings.setMorningEnabled(false);
    await this.settings.putNumber(KEY_MORNING_ID, -1);
    settings.morningEnabled = false;
  }
  return settings;
}

这段逻辑是文章的技术亮点之一,因为它体现了真实应用中对异常状态的处理,而不是只演示“发布提醒成功”。

八、天气信息如何接入首页

首页中展示天气与日历文案:

@State weatherInfo: WeatherInfo = WeatherService.getInstance().getFallback();
private weatherService = WeatherService.getInstance();

async loadWeather() {
  this.weatherInfo = await this.weatherService.getCurrentWeather();
}

首页初始化时同时刷新建议和天气:

await this.refresh();
await this.loadWeather();

天气信息并不只是装饰。对于生活助手来说,它可以继续参与推荐策略:

  1. 下雨时少推荐外出散步。
  2. 高温时推荐补水、室内运动。
  3. 晚上减少高强度运动建议。
  4. 周末推荐整理、休闲、户外活动。

当前项目已经有 WeatherServiceWeatherCalendarPage,后续可以进一步把天气数据接入 SuggestionService 的推荐权重。

九、测试与验收清单

测试项 操作 预期
通知权限未开启 打开提醒开关 弹出通知权限申请
开启早安提醒 设置早上时间并保存 系统创建每日提醒
开启晚间复盘 设置晚上时间并保存 系统创建每日提醒
修改提醒时间 更改时间后保存 旧提醒取消,新提醒发布
启动专注计时 选择时长并开始 到点后系统提醒
取消计时 点击取消 系统 timer 被取消
缺少 reminder capability 发布失败 展示可理解错误文案
首页天气加载失败 模拟定位或天气失败 使用 fallback 数据

十、常见踩坑

1. 为什么模拟器或调试包无法发布提醒?

系统提醒能力可能和签名、Profile、权限能力有关。如果出现 number of reminders exceeds 等异常,不能简单认为是代码错误,需要检查安装包是否具备 reminder_capability

2. 为什么通知权限开了仍然收不到?

需要同时检查:

  1. 应用通知权限是否开启。
  2. Reminder slot 是否创建成功。
  3. 系统提醒能力是否具备。
  4. 设备是否处于特殊省电或勿扰状态。

3. 为什么要每次 sync 前取消旧提醒?

如果不取消旧提醒,用户多次修改时间可能产生重复提醒。当前实现中 sync() 会先 cancelDailyAlarms(),再按当前设置重新发布,避免重复。

十一、参考资料

  1. HarmonyOS reminderAgentManager 系统提醒能力文档。
  2. HarmonyOS notificationManager 通知权限文档。
  3. HarmonyOS ArkTS 异步异常处理实践。
  4. CSDN 质量分规则:建议补充可运行代码、异常处理、测试清单和参考链接。

十二、互动问题

你觉得生活助手最应该提醒用户什么?

  1. 早起喝水。
  2. 晚间复盘。
  3. 久坐活动。
  4. 专注结束休息。

十三、总结

知行生活小助手通过 ReminderService 把早安提醒、晚间复盘和专注计时封装成统一服务,再由设置页负责权限申请、开关配置和用户反馈。天气服务则让首页更具生活场景感。对于 HarmonyOS 项目来说,这部分内容非常适合作为技术亮点:它不仅有 UI,还有系统能力、权限处理、异常归一和状态修复。

推荐标签

HarmonyOS ArkTS 系统提醒 通知权限 生活助手APP

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐