HarmonyOS应用开发实战:猫猫大作战-ReminderRequest 的使用
📅 2026/7/29 14:16:10
👁️ 阅读次数
📝 编程学习
前言
ReminderRequest是 HarmonyOS 的提醒服务能力,支持创建定时提醒、日历提醒和倒计时提醒。在「猫猫大作战」中,我们可以通过提醒功能让玩家每天定时回来领取签到奖励、通知活动开始、或者在体力回满时收到提醒。
与workScheduler后台任务不同,ReminderRequest 的提醒会在系统通知栏以“实况通知“形式显示,用户可以看到醒目的提醒卡片,点击后跳转到游戏。
本文以「猫猫大作战」的每日游戏提醒为锚点,讲解 ReminderRequest 的完整使用方法。
提示:本系列不讲 ArkTS 基础语法与环境搭建。本篇是阶段五第 164 篇。
一、ReminderRequest 基础
1.1 三种提醒类型
import { reminderAgent } from '@kit.ReminderKit'; // 类型 1:定时提醒(每日固定时间) const alarmReminder: reminderAgent.ReminderRequestAlarm = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM, hour: 20, minute: 0, daysOfWeek: [1, 2, 3, 4, 5, 6, 7], // 每天 title: '猫猫大作战', content: '猫咪们等你回来合并呢!', notificationId: 2001, wantAgent: { /* 点击跳转 */ }, }; // 类型 2:日历提醒(指定日期) const calendarReminder: reminderAgent.ReminderRequestCalendar = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, dateTime: { year: 2026, month: 8, day: 1, hour: 10, minute: 0 }, title: '夏日活动开启', content: '双倍积分活动开始了!', notificationId: 2002, }; // 类型 3:倒计时提醒(多久之后) const countdownReminder: reminderAgent.ReminderRequestTimer = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: 3600, // 1 小时后 title: '体力恢复提醒', content: '体力已回满,继续游戏吧!', notificationId: 2003, };| 类型 | 枚举值 | 用途 | 触发方式 |
|---|---|---|---|
Alarm | REMINDER_TYPE_ALARM | 每日定时提醒 | hour+minute+daysOfWeek |
Calendar | REMINDER_TYPE_CALENDAR | 指定日期提醒 | dateTime对象 |
Timer | REMINDER_TYPE_TIMER | 倒计时提醒 | triggerTimeInSeconds |
提示:
notificationId必须唯一,用于更新或取消提醒。建议使用模块前缀区分不同提醒类型(如 2xxx 段)。
二、创建提醒
2.1 每日定时提醒
async function createDailyReminder(context: Context): Promise<number> { const reminder: reminderAgent.ReminderRequestAlarm = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM, hour: 20, minute: 0, daysOfWeek: [1, 2, 3, 4, 5, 6, 7], // 每天 title: '🐱 猫猫大作战', content: '猫咪们等你回来合并呢!快来领取每日奖励!', notificationId: 2001, wantAgent: { pkgName: 'com.maomaodazuozhan.game', abilityName: 'EntryAbility', // 附加参数,可在 EntryAbility 中读取 parameters: { action: 'daily_reminder' }, }, maxScreenWantAgent: { pkgName: 'com.maomaodazuozhan.game', abilityName: 'EntryAbility', }, expiredContent: '今日提醒已过期', snoozeTimes: 2, // 最多推迟 2 次 timeInterval: 10, // 每 10 分钟推迟一次 }; const reminderId = await reminderAgent.publishReminder(reminder); console.info(`每日提醒已创建,ID: ${reminderId}`); return reminderId; }2.2 参数详解
| 参数 | 类型 | 说明 | 示例值 |
|---|---|---|---|
hour | number | 提醒小时 (0-23) | 20 |
minute | number | 提醒分钟 (0-59) | 0 |
daysOfWeek | number[] | 每周天数 (1=周日, 2=周一…) | [1,2,3,4,5,6,7] |
title | string | 提醒标题(显示在通知栏) | ‘猫猫大作战’ |
content | string | 提醒内容 | ‘来合并猫咪吧!’ |
notificationId | number | 唯一 ID,用于更新/取消 | 2001 |
wantAgent | object | 点击提醒后的跳转配置 | { pkgName, abilityName } |
snoozeTimes | number | 推迟次数上限 | 2 |
timeInterval | number | 推迟间隔(分钟) | 10 |
三、点击提醒跳转
3.1 WantAgent 配置
// 点击提醒后跳转到游戏并自动进入活动页面 const wantAgent: reminderAgent.WantAgent = { pkgName: 'com.maomaodazuozhan.game', abilityName: 'EntryAbility', parameters: { action: 'open_activity', activityId: 'summer_2026', from: 'reminder', }, };3.2 在 EntryAbility 中接收
// 来源:entry/src/main/ets/entryability/EntryAbility.ets import { UIAbility, Want } from '@kit.AbilityKit'; export default class EntryAbility extends UIAbility { onNewWant(want: Want): void { // 处理从提醒点击传入的参数 const action = want.parameters?.action as string; const from = want.parameters?.from as string; if (from === 'reminder') { switch (action) { case 'daily_reminder': // 打开签到页面 this.openSignInPage(); break; case 'open_activity': // 打开活动页面 const activityId = want.parameters?.activityId as string; this.openActivityPage(activityId); break; } } } private openSignInPage(): void { // 路由到签到页 console.info('从提醒跳转到签到页'); } private openActivityPage(id: string): void { console.info(`从提醒跳转到活动页: ${id}`); } }四、提醒的增删改查
4.1 取消提醒
async function cancelReminder(reminderId: number): Promise<void> { try { await reminderAgent.cancelReminder(reminderId); console.info(`提醒 ${reminderId} 已取消`); } catch (err) { console.error(`取消提醒失败: ${err.message}`); } } // 取消所有提醒 async function cancelAllReminders(context: Context): Promise<void> { const reminders = await reminderAgent.queryReminders(context); for (const r of reminders) { await reminderAgent.cancelReminder(r.reminderId); } console.info(`已取消 ${reminders.length} 个提醒`); }4.2 查询提醒
async function listAllReminders(context: Context): Promise<void> { const reminders = await reminderAgent.queryReminders(context); console.info(`当前有 ${reminders.length} 个活跃提醒:`); for (const r of reminders) { console.info( ` ID=${r.reminderId}, type=${r.reminderType}, ` + `title=${r.title}, content=${r.content}` ); } } async function getReminderById(reminderId: number): Promise<reminderAgent.ReminderRequest | null> { try { const reminders = await reminderAgent.queryReminders(getContext() as Context); return reminders.find(r => r.reminderId === reminderId) ?? null; } catch { return null; } }| 操作 | API | 参数 | 说明 |
|---|---|---|---|
| 创建 | publishReminder(reminder) | Reminder 对象 | 返回 reminderId |
| 取消 | cancelReminder(id) | 提醒 ID | 取消单个提醒 |
| 查询 | queryReminders(context) | Context | 返回所有提醒列表 |
| 更新 | 先取消再创建 | 原 ID 失效 | Reminder 不支持直接修改 |
五、游戏中的应用场景
5.1 每日签到提醒
async function setupSignInReminder(context: Context): Promise<void> { // 用户设置提醒时间(从 Preferences 读取) const prefs = await preferences.getPreferences(context, 'game_prefs'); const reminderHour = prefs.get('reminder_hour', 20) as number; const reminderMinute = prefs.get('reminder_minute', 0) as number; const reminder: reminderAgent.ReminderRequestAlarm = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM, hour: reminderHour, minute: reminderMinute, daysOfWeek: [1, 2, 3, 4, 5, 6, 7], title: '🐱 猫猫大作战 - 每日签到', content: '签到领取免费猫咪和金币!', notificationId: 2001, wantAgent: { pkgName: 'com.maomaodazuozhan.game', abilityName: 'EntryAbility', parameters: { action: 'sign_in' }, }, }; await reminderAgent.publishReminder(reminder); }5.2 活动开始提醒
async function createEventReminder( context: Context, eventDate: Date, eventName: string ): Promise<number> { const reminder: reminderAgent.ReminderRequestCalendar = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, dateTime: { year: eventDate.getFullYear(), month: eventDate.getMonth() + 1, day: eventDate.getDate(), hour: eventDate.getHours(), minute: eventDate.getMinutes(), }, title: `🎉 ${eventName}`, content: '限时活动已开始,登录领取奖励!', notificationId: 3001, wantAgent: { pkgName: 'com.maomaodazuozhan.game', abilityName: 'EntryAbility', parameters: { action: 'open_event' }, }, }; return await reminderAgent.publishReminder(reminder); }5.3 体力恢复提醒(倒计时)
async function createEnergyReminder(context: Context): Promise<number> { // 假设体力每 30 分钟恢复 1 点,满 5 点需要 2.5 小时 const ENERGY_FULL_TIME = 150; // 分钟 const seconds = ENERGY_FULL_TIME * 60; const reminder: reminderAgent.ReminderRequestTimer = { reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, triggerTimeInSeconds: seconds, title: '⚡ 体力恢复', content: '体力已回满,继续挑战高分吧!', notificationId: 3002, wantAgent: { pkgName: 'com.maomaodazuozhan.game', abilityName: 'EntryAbility', parameters: { action: 'open_game' }, }, }; return await reminderAgent.publishReminder(reminder); }六、提醒样式
6.1 系统通知样式
// ReminderRequest 在系统通知栏显示为"实况通知"样式 // 包含:应用图标、标题、内容、时间、点击跳转提示 // 提醒显示效果 ┌─────────────────────────────────┐ │ 🐱 猫猫大作战 │ │ ─────────────────────── │ │ 猫咪们等你回来合并呢! │ │ 20:00 │ │ [推迟] [确定] │ └─────────────────────────────────┘6.2 自定义参数
const reminder: reminderAgent.ReminderRequestAlarm = { // ... 基础参数 // 提醒内容在锁屏上的展示策略 maxScreenWantAgent: { pkgName: 'com.maomaodazuozhan.game', abilityName: 'EntryAbility', }, // 过期内容(提醒触发后未操作时显示) expiredContent: '今日提醒已过期,点击查看活动详情', // 推迟行为 snoozeTimes: 2, // 最多推迟 2 次 timeInterval: 10, // 每次推迟间隔 10 分钟 };七、权限与限制
7.1 权限声明
// module.json5 中声明 { module: { requestPermissions: [ { name: 'ohos.permission.PUBLISH_AGENT_REMINDER', reason: '$string:reminder_permission_reason', }, ], }, }7.2 运行时权限
async function ensureReminderPermission(context: Context): Promise<boolean> { const atManager = abilityAccessCtrl.createAtManager(); try { const result = await atManager.requestPermissionsFromUser(context, [ 'ohos.permission.PUBLISH_AGENT_REMINDER', ]); return result.authResults[0] === 0; } catch (err) { console.error(`提醒权限获取失败: ${err.message}`); return false; } }7.3 限制
| 限制项 | 说明 |
|---|---|
| 最大提醒数 | 单应用最多 50 个活跃提醒 |
| 最小倒计时 | triggerTimeInSeconds >= 60(至少 1 分钟) |
| 重复间隔 | repeatCycleTime >= 60 * 60 * 1000(至少 1 小时) |
| 权限 | 必须声明PUBLISH_AGENT_REMINDER |
| 实况通知 | 仅 Alarm 和 Calendar 类型支持 |
提示:提醒数量建议控制在 10 个以内,过多会影响系统性能和用户体验。
八、调试与测试
// 在模拟器中测试提醒 // 1. 创建提醒后等待触发 // 2. 使用 hdc 修改系统时间加速测试 // hdc shell date -s "2026-07-28 19:59:50" // 3. 等待 10 秒触发提醒 // 代码内验证提醒是否生效 async function verifyReminderCreated(context: Context): Promise<boolean> { const reminders = await reminderAgent.queryReminders(context); const targetReminder = reminders.find(r => r.title.includes('猫猫大作战')); if (targetReminder) { console.info(`提醒已生效: ID=${targetReminder.reminderId}`); return true; } console.warn('未找到提醒,请检查创建逻辑'); return false; }九、常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 提醒未触发 | 权限未授予 | 检查 PUBLISH_AGENT_REMINDER 权限 |
| 点击提醒未跳转 | WantAgent 配置错误 | 检查 pkgName 和 abilityName |
| 提醒多次触发 | 重复创建未清理 | 创建前先取消旧提醒 |
| 倒计时不准 | 系统休眠限制 | 使用 Alarm 定时间而非 Timer |
| 推送栏不显示 | notificationId 冲突 | 使用唯一 ID |
十、最佳实践
- 提醒数量精简:最多 3-5 个活跃提醒,避免骚扰用户
- 提供推迟功能:设置
snoozeTimes和timeInterval给用户灵活性 - 跳转带参数:在
parameters中传 action,区分不同场景 - 用户可配置:让用户可以设置提醒时间和类型
- 销毁时清理:应用卸载或用户退出时取消所有提醒
- 测试覆盖:每种提醒类型至少测试一次触发和跳转
// 用户设置提醒偏好 async function updateReminderSettings( context: Context, enabled: boolean, hour?: number, minute?: number ): Promise<void> { // 先取消所有旧提醒 const reminders = await reminderAgent.queryReminders(context); for (const r of reminders) { await reminderAgent.cancelReminder(r.reminderId); } if (enabled && hour !== undefined && minute !== undefined) { // 创建新提醒 await createDailyReminder(context); console.info(`提醒已更新: ${hour}:${minute}`); } else { console.info('提醒已关闭'); } }总结
ReminderRequest 提供三种提醒类型——定时、日历、倒计时,适用于游戏中的每日签到提醒、活动通知和体力恢复提醒。核心要点:Alarm 定时每日提醒、 Calendar 指定日期活动、 Timer 倒计时提醒、 WantAgent 点击跳转带参数、 snoozeTimes 推迟机制、 notificationId 唯一标识。
下一篇将深入 LiveViewKit——实况窗与锁屏得分展示。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- ReminderAgent API 参考
- ReminderRequest 官方指南
- WantAgent 跳转配置
- 通知栏与提醒最佳实践
- BACKGROUNDTASKS_KIT 权限
- 定时提醒设计规范
- 开源鸿蒙跨平台社区
- HarmonyOS 开发者官方文档
- 第 163 篇:workScheduler
- 第 165 篇:LiveViewKit
编程学习
技术分享
实战经验