介紹
介紹如何使用后臺代理提醒,實現(xiàn)一個簡易鬧鐘。要求完成以下功能:
- 展示指針表盤或數(shù)字時間。
- 添加、修改和刪除鬧鐘。
- 展示鬧鐘列表,并可打開和關(guān)閉單個鬧鐘。
- 鬧鐘到設(shè)定的時間后彈出提醒。
- 將鬧鐘的定時數(shù)據(jù)保存到輕量級數(shù)據(jù)庫。
相關(guān)概念
- [Canvas]:提供畫布組件,用于自定義繪制圖形。
- [CanvasRenderingContext2D]:使用RenderingContext在Canvas組件上進行繪制,繪制對象可以是矩形、文本、圖片等。
- [后臺代理提醒]:開發(fā)應用時,開發(fā)者可以調(diào)用后臺提醒發(fā)布的接口創(chuàng)建定時提醒,包括倒計時、日歷、鬧鐘三種提醒類型。使用后臺代理提醒能力后,應用可以被凍結(jié)或退出,計時和彈出提醒的功能將被后臺系統(tǒng)服務代理。本應用中主要使用到后臺代理提醒的兩個接口:
相關(guān)權(quán)限
本篇Codelab需要在module.json5中配置如下權(quán)限:
"requestPermissions": [
{
"name": "ohos.permission.PUBLISH_AGENT_REMINDER"
}
]
環(huán)境搭建
軟件要求
- [DevEco Studio]版本:DevEco Studio 3.1 Release。
- OpenHarmony SDK版本:API version 9。
硬件要求
- 開發(fā)板類型:[潤和RK3568開發(fā)板]。
- OpenHarmony系統(tǒng):3.2 Release。
環(huán)境搭建
完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以RK3568開發(fā)板為例,參照以下步驟進行:
- [獲取OpenHarmony系統(tǒng)版本]:標準系統(tǒng)解決方案(二進制)。以3.2 Release版本為例:
- 搭建燒錄環(huán)境。
- [完成DevEco Device Tool的安裝]
- [完成RK3568開發(fā)板的燒錄]
- 搭建開發(fā)環(huán)境。
- 開始前請參考[工具準備],完成DevEco Studio的安裝和開發(fā)環(huán)境配置。
- 開發(fā)環(huán)境配置完成后,請參考[使用工程向?qū)創(chuàng)建工程(模板選擇“Empty Ability”)。
- 工程創(chuàng)建完成后,選擇使用[真機進行調(diào)測]。
代碼結(jié)構(gòu)解讀
本篇Codelab只對核心代碼進行講解,對于完整代碼,我們會在gitee中提供。
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
├──entry/src/main/ets // 代碼區(qū)
│ ├──common
│ │ ├──constants
│ │ │ ├──AlarmSettingType.ets // 鬧鐘設(shè)置類型枚舉
│ │ │ ├──CommonConstants.ets // 公共常量類
│ │ │ ├──DetailConstant.ets // 詳情頁常量類
│ │ │ └──MainConstant.ets // 首頁常量類
│ │ └──utils
│ │ ├──DataTypeUtils.ets // 數(shù)據(jù)類型工具類
│ │ ├──DimensionUtil.ets // 屏幕適配工具類
│ │ └──GlobalContext.ets // 全局變量工具類
│ ├──entryability
│ │ └──EntryAbility.ets // 程序入口類
│ ├──model
│ │ ├──database
│ │ │ ├──PreferencesHandler.ets // 輕量級數(shù)據(jù)庫操作類
│ │ │ └──PreferencesListener.ets // 輕量級數(shù)據(jù)庫回調(diào)接口
│ │ └──ReminderService.ets // 系統(tǒng)后臺提醒服務類
│ │──pages
│ │ ├──DetailIndex.ets // 詳情頁入口文件
│ │ └──MainIndex.ets // 主頁入口文件
│ │──view
│ │ ├──Detail
│ │ │ ├──dialog
│ │ │ │ ├──CommonDialog.ets // 公共Dialog組件
│ │ │ │ ├──DurationDialog.ets // 鬧鈴時長選擇Dialog組件
│ │ │ │ ├──IntervalDialog.ets // 鬧鈴間隔選擇Dialog組件
│ │ │ │ ├──RenameDialog.ets // 鬧鈴名設(shè)置Dialog組件
│ │ │ │ └──RepeatDialog.ets // 鬧鈴重復設(shè)置Dialog組件
│ │ │ ├──DatePickArea.ets // 詳情頁時間選擇組件
│ │ │ └──SettingItem.ets // 詳情頁設(shè)置組件
│ │ ├──Main
│ │ │ ├──AlarmList.ets // 主頁鬧鐘列表組件
│ │ │ ├──AlarmListItem.ets // 主頁鬧鐘列表子項組件
│ │ │ └──ClockArea.ets // 主頁時鐘組件
│ │ └──BackContainer.ets // 自定義頭部組件
│ └──viewmodel
│ ├──AlarmItemBean.ets // 鬧鐘屬性類
│ ├──AlarmSettingBean.ets // 鬧鐘設(shè)置屬性類
│ ├──DayDateBean.ets // 日期屬性類
│ ├──DetailViewModel.ets // 詳情模塊邏輯功能類
│ ├──MainViewModel.ets // 主頁邏輯功能類
│ └──ReminderItemBean.ets // 后臺提醒屬性類
└──entry/src/main/resources // 資源文件目錄
鬧鐘主界面
鬧鐘界面包括當前時間、鬧鐘列表、添加鬧鐘子組件,具體包括以下模塊:
- 展示當前時間。
- 展示鬧鐘列表。
- 添加鬧鐘。
- 后臺代理提醒。
展示當前時間
當前時間使用了Canvas組件繪制,默認展示指針表盤,點擊表盤區(qū)域切換為數(shù)字時鐘。
在主頁的ClockArea組件中初始化Canvas畫布,并綁定指針表盤和數(shù)字時鐘切換事件。
// ClockArea.ets
@Component
export default struct ClockArea {
...
build() {
Canvas(this.renderContext)
.width(this.canvasSize)
.aspectRatio(CommonConstants.DEFAULT_LAYOUT_WEIGHT)
.onReady(() = > {
if (this.drawInterval === CommonConstants.DEFAULT_NUMBER_NEGATIVE) {
this.startDrawTask();
}
})
.onClick(() = > {
this.showClock = !this.showClock;
})
}
// 啟動繪畫任務
private startDrawTask() {
let that = this;
that.renderContext.translate(
this.canvasSize / CommonConstants.DEFAULT_DOUBLE,
this.canvasSize / CommonConstants.DEFAULT_DOUBLE);
that.drawClockArea();
this.drawInterval = setInterval(() = > {
that.drawClockArea();
}, MainConstant.DEFAULT_ONE_SECOND_MS);
}
...
}
繪畫任務是使用CanvasRenderingContext2D對象在Canvas畫布組件上繪制指針表盤和數(shù)字時鐘。
// ClockArea.ets
// 開始繪制時鐘區(qū)域
private drawClockArea(): void{
this.renderContext.clearRect(
-this.canvasSize,
-this.canvasSize / CommonConstants.DEFAULT_DOUBLE,
this.canvasSize * CommonConstants.DEFAULT_DOUBLE,
this.canvasSize);
let date = new Date();
let hours = date.getHours();
let minutes = date.getMinutes();
let seconds = date.getSeconds();
if (this.showClock) {
// 繪制表盤時鐘
} else {
// 繪制數(shù)字時鐘
}
}
展示鬧鐘列表
鬧鐘列表組件,展示已添加的鬧鐘信息,可對鬧鐘進行啟停操作,點擊鬧鐘可跳轉(zhuǎn)到鬧鐘操作界面(修改和刪除鬧鐘)。主頁啟動后獲取輕量級數(shù)據(jù)庫中的鬧鐘定時數(shù)據(jù),并監(jiān)控數(shù)據(jù)庫數(shù)據(jù)變化。
// MainViewModel.ets
public queryAlarmsTasker(callback: (alarms: Array< AlarmItem >) = > void) {
let that = this;
that.queryDatabaseAlarms(callback);
let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;
preference.addPreferencesListener({
onDataChanged() {
that.queryDatabaseAlarms(callback);
}
} as PreferencesListener)
}
在AlarmList.ets中添加鬧鐘列表子組件,并綁定啟停、跳轉(zhuǎn)事件。
// AlarmList.ets
@Component
export default struct AlarmList {
@Link alarmItems: Array< AlarmItem >;
build() {
List({ space: DimensionUtil.getVp($r('app.float.alarm_list_space')) }) {
ForEach(this.alarmItems, (item: AlarmItem) = > {
ListItem() {
AlarmListItem({ alarmItem: item })
}.onClick(() = > {
router.pushUrl({ url: "pages/DetailIndex", params: { alarmItem: item } });
})
}, (item: AlarmItem) = > JSON.stringify(item))
}
.padding({
left: DimensionUtil.getVp($r('app.float.alarm_list_content_distance')),
right: DimensionUtil.getVp($r('app.float.alarm_list_content_distance'))
})
.listDirection(Axis.Vertical)
.layoutWeight(CommonConstants.DEFAULT_LAYOUT_WEIGHT)
.margin({ top: DimensionUtil.getVp($r('app.float.alarm_list_content_distance')) })
}
}
添加鬧鐘
添加鬧鐘,點擊界面底部鬧鐘添加按鈕,跳轉(zhuǎn)到鬧鐘操作界面(新增鬧鐘)。
在MainIndex.ets中為添加按鈕綁定跳轉(zhuǎn)事件。
// MainIndex.ets
@Entry
@Component
struct MainIndex {
...
build() {
Column() {
...
Button() {
Image($r('app.media.ic_add')).objectFit(ImageFit.Fill)
}
...
.onClick(() = > {
router.pushUrl({ url: "pages/DetailIndex" });
})
}
...
}
}
后臺代理提醒
后臺代理提醒,根據(jù)鬧鐘列表中的數(shù)據(jù)來設(shè)置(啟停)鬧鐘實例。
// MainViewModel.ets
// 開啟/關(guān)閉鬧鐘
public openAlarm(id: number, isOpen: boolean) {
for (let i = 0; i < this.alarms.length; i++) {
if (this.alarms[i].id === id) {
this.alarms[i].isOpen = isOpen;
if (isOpen) {
this.reminderService.addReminder(this.alarms[i]);
} else {
this.reminderService.deleteReminder(this.alarms[i].id);
}
let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;
preference.set(CommonConstants.ALARM_KEY, JSON.stringify(this.alarms));
break;
}
}
}
鬧鐘詳情界面
鬧鐘操作界面分為新增和修改界面,其中在修改界面可刪除鬧鐘。具體包括以下模塊:
- 退出或保存詳情。
- 設(shè)置鬧鐘時間。
- 設(shè)置鬧鐘詳情。
- 提供后臺代理提醒能力
退出或保存詳情
點擊左上角“x”圖標關(guān)閉操作界面,關(guān)閉鬧鐘操作界面子組件,點擊右上角“√”圖標,保存當前設(shè)置并關(guān)閉操作界面。
在DetailIndex.ets入口頁面中引入頭部組件BackContainer,自定義了返回按鈕和返回邏輯操作,添加確定(“√”)子組件,并綁定點擊事件。
// DetailIndex.ets
build()
{
Column() {
...
Button() {
Image($r('app.media.ic_confirm')).objectFit(ImageFit.Fill)
}
.backgroundColor($r('app.color.trans_parent'))
.width(DimensionUtil.getVp($r('app.float.title_button_size')))
.height(DimensionUtil.getVp($r('app.float.title_button_size')))
.onClick(() = > {
this.viewModel.setAlarmRemind(this.alarmItem);
router.back();
})
...
}
}
// BackContainer.ets
build() {
Row() {
...
Text(this.header)
.fontSize(DimensionUtil.getFp($r('app.float.detail_title_font_size')))
.lineHeight(DimensionUtil.getVp($r('app.float.title_line_height')))
.margin({ left: DimensionUtil.getVp($r('app.float.title_margin')) })
.fontColor($r('app.color.grey_divider'))
.fontWeight(FontWeight.Bold)
Blank()
if (this.closer) {
this.closer();
}
}
.padding({
left: DimensionUtil.getVp($r('app.float.title_horizon_margin')),
right: DimensionUtil.getVp($r('app.float.title_horizon_margin'))
})
.height(DimensionUtil.getVp($r('app.float.page_title_height')))
.width(CommonConstants.FULL_LENGTH)
}
設(shè)置鬧鐘時間
設(shè)置鬧鐘提醒時間,在鬧鐘操作界面可通過滑動選擇器設(shè)置鬧鐘的提醒時間(包括:時段、小時、分鐘)。詳情頁DetailIndex.ets中添加鬧鐘時間選擇器子組件DatePickArea.ets。
// DatePickArea.ets
@Component
export default struct DatePickArea {
build() {
Stack({ alignContent: Alignment.Center }) {
Row() {
ForEach(DetailConstant.DAY_DATA, (item: DayDataBean) = > {
TextPicker({ range: item.data, selected: item.delSelect })
.layoutWeight(CommonConstants.DEFAULT_LAYOUT_WEIGHT)
.backgroundColor($r('app.color.grey_light'))
.onChange((value: string, index: number) = > {
item.delSelect = index;
})
}, (item: DayDataBean) = > JSON.stringify(item))
}
}
.height(DimensionUtil.getVp($r('app.float.date_picker_height')))
.padding({
left: DimensionUtil.getVp($r('app.float.date_picker_padding_horizon')),
right: DimensionUtil.getVp($r('app.float.date_picker_padding_horizon'))
})
}
}
設(shè)置鬧鐘詳情
點擊詳情頁DetailIndex.ets設(shè)置條目組件SettingItem.ets,支持設(shè)置鬧鐘重復時間、鬧鐘名稱、重復次數(shù)和鬧鈴時長。
// SettingItem.ets
build() {
Column() {
ForEach(this.settingInfo, (item: AlarmSettingBean, index: number | undefined) = > {
Divider()
...
Row() {
Text(item.title)...
Text(item.content)...
Image($r('app.media.ic_right'))...
}
...
.onClick(() = > {
this.showSettingDialog(item.sType);
})
}, (item: AlarmSettingBean, index: number | undefined) = > JSON.stringify(item) + index)
}
...
}
提供后臺代理提醒能力
導入系統(tǒng)提醒服務類ReminderService.ets,它由系統(tǒng)后臺代理提醒能力封裝,支持新增、修改、刪除系統(tǒng)鬧鐘功能,在設(shè)置、刪除鬧鐘后同步更新到輕量級數(shù)據(jù)庫中并刷新主頁頁面。
// DetailViewModel.ets
public async setAlarmRemind(alarmItem: AlarmItem) {
alarmItem.hour = this.getAlarmTime(CommonConstants.DEFAULT_SINGLE);
alarmItem.minute = this.getAlarmTime(CommonConstants.DEFAULT_DATA_PICKER_HOUR_SELECTION);
let index = await this.findAlarmWithId(alarmItem.id);
if (index !== CommonConstants.DEFAULT_NUMBER_NEGATIVE) { // 已存在,刪除原有提醒
this.reminderService.deleteReminder(alarmItem.id);
} else { // 不存在,以數(shù)據(jù)長度為notificationId新增鬧鐘數(shù)據(jù)
index = this.alarms.length;
alarmItem.notificationId = index;
this.alarms.push(alarmItem);
}
this.reminderService.addReminder(alarmItem, (newId: number) = > {
alarmItem.id = newId;
alarmItem.isOpen = true;
this.alarms[index] = alarmItem;
let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;
preference.set(CommonConstants.ALARM_KEY, JSON.stringify(this.alarms));
})
}
public async removeAlarmRemind(id: number) {
this.reminderService.deleteReminder(id);
let index = await this.findAlarmWithId(id);
if (index !== CommonConstants.DEFAULT_NUMBER_NEGATIVE) {
this.alarms.splice(index, CommonConstants.DEFAULT_SINGLE);
}
let preference = GlobalContext.getContext().getObject('preference') as PreferencesHandler;
preference.set(CommonConstants.ALARM_KEY, JSON.stringify(this.alarms));
}
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
57文章
2363瀏覽量
42888 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1977瀏覽量
30264 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3725瀏覽量
16375
發(fā)布評論請先 登錄
相關(guān)推薦
評論