用@ohos.notification设置刷牙提醒——齿录的通知实现
去鸿蒙应用市场搜一下**「齿录」**,下载下来体验体验。设置早晚刷牙提醒后,到了时间系统会推送通知提醒你——这个功能看起来简单,但在鸿蒙里实现通知需要了解
@ohos.notification的用法。体验完了再回来看这篇文章,看看本地通知是怎么设置的。
写在前面
大家好,我是一名写了十多年Web前端的老兵。上一篇文章讲了@ohos.data.preferences的习惯追踪,这篇文章我们聚焦到通知提醒:怎么用@ohos.notification设置本地通知。
在Web里,你可以用Notification API推送浏览器通知。鸿蒙里的通知系统更强大,支持定时通知、通知渠道、通知按钮等。
这篇文章聊什么
齿录的提醒通知,核心要解决:
- 定时通知:每天早上8点和晚上10点推送刷牙提醒
- 通知内容:显示提醒文字和打卡按钮
- 通知管理:开启/关闭提醒、修改时间
第一步:声明权限
在module.json5里声明通知权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.NOTIFICATION",
"reason": "用于推送刷牙提醒",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
}
]
}
}
第二步:发送简单通知
import { notificationManager } from '@kit.NotificationKit'
async function sendSimpleNotification(title: string, content: string) {
const notificationRequest: notificationManager.NotificationRequest = {
id: Date.now(),
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: content
}
}
}
await notificationManager.publish(notificationRequest)
}
第三步:定时通知
鸿蒙的定时通知需要用notificationManager.publishReminder:
import { notificationManager } from '@kit.NotificationKit'
async function scheduleReminder(hour: number, minute: number, title: string, content: string) {
const now = new Date()
const target = new Date()
target.setHours(hour, minute, 0, 0)
// 如果目标时间已过,设置为明天
if (target.getTime() <= now.getTime()) {
target.setDate(target.getDate() + 1)
}
const triggerTime = target.getTime()
const reminder: notificationManager.ReminderRequest = {
reminderType: notificationManager.ReminderType.TIMER,
triggerTime: triggerTime,
maxScreenWantAgent: {
// 点击通知打开应用
},
notificationId: Date.now(),
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: content
}
},
tapDismissed: true
}
await notificationManager.publishReminder(reminder)
}
第四步:实现刷牙提醒页面
import { notificationManager } from '@kit.NotificationKit'
import { preferences } from '@kit.ArkData'
interface ReminderSettings {
morningEnabled: boolean
morningTime: string // '08:00'
eveningEnabled: boolean
eveningTime: string // '22:00'
}
@Entry
@Component
struct ReminderSettingsPage {
@State settings: ReminderSettings = {
morningEnabled: true,
morningTime: '08:00',
eveningEnabled: true,
eveningTime: '22:00'
}
@State morningHour: number = 8
@State morningMinute: number = 0
@State eveningHour: number = 22
@State eveningMinute: number = 0
private context = getContext(this) as common.UIAbilityContext
async aboutToAppear() {
await this.loadSettings()
}
async loadSettings() {
try {
const pref = await preferences.getPreferences(this.context, 'dental_habits')
const saved = await pref.get('reminder_settings', '')
if (typeof saved === 'string' && saved.length > 0) {
this.settings = JSON.parse(saved) as ReminderSettings
this.parseTime()
}
} catch (err) {
console.error('读取设置失败:', err)
}
}
parseTime() {
const morningParts = this.settings.morningTime.split(':')
this.morningHour = parseInt(morningParts[0])
this.morningMinute = parseInt(morningParts[1])
const eveningParts = this.settings.eveningTime.split(':')
this.eveningHour = parseInt(eveningParts[0])
this.eveningMinute = parseInt(eveningParts[1])
}
async saveSettings() {
try {
const pref = await preferences.getPreferences(this.context, 'dental_habits')
this.settings.morningTime = `${this.morningHour.toString().padStart(2, '0')}:${this.morningMinute.toString().padStart(2, '0')}`
this.settings.eveningTime = `${this.eveningHour.toString().padStart(2, '0')}:${this.eveningMinute.toString().padStart(2, '0')}`
await pref.put('reminder_settings', JSON.stringify(this.settings))
await pref.flush()
// 更新通知
await this.updateReminders()
} catch (err) {
console.error('保存设置失败:', err)
}
}
async updateReminders() {
// 取消所有现有通知
await notificationManager.cancelAllReminders()
// 设置新的通知
if (this.settings.morningEnabled) {
await this.scheduleDailyReminder(
this.morningHour,
this.morningMinute,
'早上好!',
'别忘了刷牙哦,保持口腔健康从早起开始。'
)
}
if (this.settings.eveningEnabled) {
await this.scheduleDailyReminder(
this.eveningHour,
this.eveningMinute,
'晚安提醒',
'睡前记得刷牙和使用牙线,保护牙齿从今天做起。'
)
}
}
async scheduleDailyReminder(hour: number, minute: number, title: string, content: string) {
const now = new Date()
const target = new Date()
target.setHours(hour, minute, 0, 0)
if (target.getTime() <= now.getTime()) {
target.setDate(target.getDate() + 1)
}
const reminder: notificationManager.ReminderRequest = {
reminderType: notificationManager.ReminderType.TIMER,
triggerTime: target.getTime(),
notificationId: hour * 100 + minute,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: content
}
},
tapDismissed: true
}
try {
await notificationManager.publishReminder(reminder)
console.info(`已设置提醒: ${hour}:${minute}`)
} catch (err) {
console.error(`设置提醒失败: ${err}`)
}
}
build() {
Column() {
Text('提醒设置')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.margin({ bottom: 24 })
// 早上提醒
Column() {
Row() {
Text('早上刷牙提醒')
.fontSize(16)
.fontColor('#FFFFFF')
Toggle({ type: ToggleType.Switch, isOn: this.settings.morningEnabled })
.onChange((isOn: boolean) => {
this.settings.morningEnabled = isOn
this.saveSettings()
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
if (this.settings.morningEnabled) {
TimePicker({
selected: new Date(2024, 0, 1, this.morningHour, this.morningMinute)
})
.onChange((value: TimePickerResult) => {
this.morningHour = value.hour
this.morningMinute = value.minute
this.saveSettings()
})
.margin({ top: 8 })
}
}
.padding(16)
.backgroundColor('#1F2937')
.borderRadius(12)
.margin({ bottom: 16 })
// 晚上提醒
Column() {
Row() {
Text('晚上刷牙提醒')
.fontSize(16)
.fontColor('#FFFFFF')
Toggle({ type: ToggleType.Switch, isOn: this.settings.eveningEnabled })
.onChange((isOn: boolean) => {
this.settings.eveningEnabled = isOn
this.saveSettings()
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
if (this.settings.eveningEnabled) {
TimePicker({
selected: new Date(2024, 0, 1, this.eveningHour, this.eveningMinute)
})
.onChange((value: TimePickerResult) => {
this.eveningHour = value.hour
this.eveningMinute = value.minute
this.saveSettings()
})
.margin({ top: 8 })
}
}
.padding(16)
.backgroundColor('#1F2937')
.borderRadius(12)
// 测试通知
Button('测试通知')
.onClick(() => {
sendSimpleNotification('齿录提醒', '这是一条测试通知')
})
.width('100%')
.height(48)
.backgroundColor('#374151')
.borderRadius(24)
.margin({ top: 24 })
}
.width('100%')
.height('100%')
.backgroundColor('#111827')
.padding(16)
}
}
第五步:处理通知点击
用户点击通知后,可以跳转到打卡页面:
import { wantAgent, WantAgent } from '@kit.AbilityKit'
async function createWantAgent(): Promise<WantAgent> {
const wantAgentInfo: wantAgent.WantAgentParams = {
wants: [
{
bundleName: 'com.example.dentalapp',
abilityName: 'EntryAbility',
parameters: {
page: 'checkin'
}
}
],
actionType: wantAgent.OperationType.START_ABILITY,
requestCode: 0,
actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
}
return await wantAgent.getWantAgent(wantAgentInfo)
}
// 在创建通知时使用wantAgent
const reminder: notificationManager.ReminderRequest = {
reminderType: notificationManager.ReminderType.TIMER,
triggerTime: target.getTime(),
notificationId: hour * 100 + minute,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: content
}
},
tapDismissed: true,
maxScreenWantAgent: await createWantAgent()
}
总结
这篇文章围绕"齿录"的提醒通知功能,把@ohos.notification的核心用法过了一遍:
基本通知
notificationManager.publish():发送即时通知NotificationRequest:配置通知内容
定时通知
notificationManager.publishReminder():设置定时通知ReminderRequest:配置触发时间和内容ReminderType.TIMER:定时触发
通知管理
notificationManager.cancelAllReminders():取消所有通知notificationManager.cancel():取消指定通知
注意事项
- 需要声明通知权限
- 定时通知设置为每天触发
- 用户点击通知可以跳转到指定页面
- 测试时先用即时通知验证功能
如果你对"齿录"感兴趣,欢迎去鸿蒙应用市场搜索下载体验。有问题欢迎交流。