鸿蒙跨设备闹钟提醒系统设计与实现
·
鸿蒙跨设备闹钟提醒系统设计与实现
一、系统架构设计
基于HarmonyOS的分布式能力和通知模块,我们设计了一套跨设备同步的闹钟提醒系统,确保用户在任何设备上设置的闹钟都能在所有设备上同步提醒。
https://example.com/alarm-system-arch.png
系统包含三个核心模块:
- 本地通知模块 - 使用
@ohos.notification实现基础闹钟功能 - 分布式同步模块 - 通过
@ohos.distributedData实现多设备状态同步 - UI组件模块 - 提供统一的闹钟设置界面和提醒弹窗
二、核心代码实现
1. 闹钟通知服务(ArkTS)
// AlarmService.ets
import notification from '@ohos.notification';
import distributedData from '@ohos.distributedData';
const ALARM_CHANNEL = 'alarm_sync_channel';
class AlarmService {
private static instance: AlarmService = null;
private dataManager: distributedData.DataManager;
private constructor() {
this.initDataManager();
}
public static getInstance(): AlarmService {
if (!AlarmService.instance) {
AlarmService.instance = new AlarmService();
}
return AlarmService.instance;
}
private initDataManager() {
this.dataManager = distributedData.createDataManager({
bundleName: 'com.example.alarmdemo',
area: distributedData.Area.GLOBAL
});
this.dataManager.registerDataListener(ALARM_CHANNEL, (data) => {
this.handleSyncAlarm(data);
});
}
// 设置闹钟
public setAlarm(alarm: Alarm): void {
// 本地设置闹钟
this.scheduleLocalNotification(alarm);
// 同步到其他设备
this.syncAlarm(alarm);
}
private scheduleLocalNotification(alarm: Alarm): void {
const triggerTime = new Date(alarm.time);
const currentTime = new Date();
if (triggerTime <= currentTime) {
console.warn('设置的闹钟时间必须晚于当前时间');
return;
}
const delay = triggerTime.getTime() - currentTime.getTime();
setTimeout(() => {
this.showNotification(alarm);
}, delay);
}
private showNotification(alarm: Alarm): void {
try {
notification.publish({
id: alarm.id,
contentType: notification.ContentType.NOTIFICATION_TEXT,
content: {
title: alarm.title || '闹钟提醒',
text: alarm.content || '该起床了!',
additionalText: alarm.additionalText || ''
},
tapAction: {
want: {
bundleName: 'com.example.alarmdemo',
abilityName: 'AlarmNotificationAbility',
parameters: {
alarmId: alarm.id
}
}
}
});
} catch (err) {
console.error(`发布通知失败: ${JSON.stringify(err)}`);
}
}
private syncAlarm(alarm: Alarm): void {
this.dataManager.syncData(ALARM_CHANNEL, {
type: 'set',
alarm: alarm
});
}
private handleSyncAlarm(data: any): void {
if (data?.type === 'set' && data.alarm) {
const alarm: Alarm = data.alarm;
this.scheduleLocalNotification(alarm);
}
}
// 取消闹钟
public cancelAlarm(alarmId: string): void {
// 本地取消
notification.cancel(alarmId);
// 同步取消
this.dataManager.syncData(ALARM_CHANNEL, {
type: 'cancel',
alarmId: alarmId
});
}
}
interface Alarm {
id: string;
time: number; // 时间戳
title?: string;
content?: string;
additionalText?: string;
}
2. 闹钟设置界面(ArkUI)
// AlarmSetting.ets
import { AlarmService } from './AlarmService';
@Entry
@Component
struct AlarmSetting {
@State alarmTime: string = '08:00';
@State alarmTitle: string = '起床闹钟';
@State alarmContent: string = '该起床了!';
private alarmService: AlarmService = AlarmService.getInstance();
build() {
Column() {
// 时间选择器
TimePicker({
selected: this.alarmTime
})
.onChange((value: TimePickerResult) => {
this.alarmTime = `${value.hour}:${value.minute}`;
})
// 闹钟标题输入
TextInput({ placeholder: '闹钟标题' })
.onChange((value: string) => {
this.alarmTitle = value;
})
// 闹钟内容输入
TextInput({ placeholder: '闹钟内容' })
.onChange((value: string) => {
this.alarmContent = value;
})
// 设置按钮
Button('设置闹钟')
.onClick(() => {
this.setAlarm();
})
}
.padding(20)
}
private setAlarm() {
const now = new Date();
const [hours, minutes] = this.alarmTime.split(':').map(Number);
const alarmDate = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate(),
hours,
minutes
);
// 如果设置的时间已经过去,设置为第二天
if (alarmDate <= now) {
alarmDate.setDate(alarmDate.getDate() + 1);
}
const alarm: Alarm = {
id: `alarm_${Date.now()}`,
time: alarmDate.getTime(),
title: this.alarmTitle,
content: this.alarmContent
};
this.alarmService.setAlarm(alarm);
// 显示设置成功提示
promptAction.showToast({
message: '闹钟设置成功',
duration: 2000
});
}
}
3. 闹钟通知处理Ability(Java)
// AlarmNotificationAbility.java
public class AlarmNotificationAbility extends Ability {
private static final String TAG = "AlarmNotificationAbility";
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// 处理通知点击
if (intent != null && intent.hasParameter("alarmId")) {
String alarmId = intent.getStringParam("alarmId");
HiLog.info(TAG, "处理闹钟通知点击, alarmId: " + alarmId);
// 显示全屏提醒
showFullScreenAlert(alarmId);
}
}
private void showFullScreenAlert(String alarmId) {
// 创建提醒对话框
AlertDialog dialog = new AlertDialog(getContext());
dialog.setTitle("闹钟提醒");
dialog.setMessage("该起床了!");
dialog.setButton(DialogInterface.BUTTON_POSITIVE, "关闭", (d, which) -> {
terminateAbility();
});
// 全屏显示
Window window = dialog.getWindow();
if (window != null) {
window.setLayout(WindowManager.LayoutConfig.MATCH_PARENT,
WindowManager.LayoutConfig.MATCH_PARENT);
}
dialog.show();
// 播放闹钟铃声
playAlarmSound();
}
private void playAlarmSound() {
// 使用媒体服务播放铃声
// 实际实现需要添加权限和资源文件
HiLog.info(TAG, "播放闹钟铃声");
}
}
三、跨设备同步实现
1. 分布式数据管理配置
// module.json5
{
"module": {
"abilities": [
{
"name": "AlarmNotificationAbility",
"type": "page",
"visible": true
}
],
"distributedNotification": {
"scenarios": [
{
"name": "alarm_scenario",
"value": "alarm_reminder"
}
]
},
"reqPermissions": [
{
"name": "ohos.permission.NOTIFICATION_CONTROLLER",
"reason": "用于闹钟通知"
},
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC",
"reason": "用于跨设备同步闹钟"
}
]
}
}
2. 增强版闹钟同步服务
// EnhancedAlarmService.ets
import notification from '@ohos.notification';
import distributedData from '@ohos.distributedData';
import deviceManager from '@ohos.distributedDeviceManager';
const ALARM_SYNC_CHANNEL = 'enhanced_alarm_sync';
class EnhancedAlarmService {
private deviceManager: deviceManager.DeviceManager;
private dataManager: distributedData.DataManager;
private alarms: Map<string, Alarm> = new Map();
constructor() {
this.initDeviceManager();
this.initDataManager();
}
private async initDeviceManager() {
try {
this.deviceManager = await deviceManager.createDeviceManager('com.example.alarmdemo');
this.deviceManager.on('deviceOnline', (device) => {
this.syncAllAlarmsToDevice(device.deviceId);
});
} catch (err) {
console.error('初始化DeviceManager失败:', JSON.stringify(err));
}
}
private initDataManager() {
this.dataManager = distributedData.createDataManager({
bundleName: 'com.example.alarmdemo',
area: distributedData.Area.GLOBAL
});
this.dataManager.registerDataListener(ALARM_SYNC_CHANNEL, (data) => {
this.handleSyncData(data);
});
}
public setAlarm(alarm: Alarm): void {
// 存储闹钟
this.alarms.set(alarm.id, alarm);
// 本地调度
this.scheduleLocalAlarm(alarm);
// 同步到所有设备
this.syncAlarmToAllDevices(alarm);
}
private scheduleLocalAlarm(alarm: Alarm): void {
const now = new Date().getTime();
const delay = alarm.time - now;
if (delay <= 0) {
console.warn('闹钟时间已过,不进行调度');
return;
}
setTimeout(() => {
this.triggerAlarm(alarm);
}, delay);
}
private triggerAlarm(alarm: Alarm): void {
// 发布通知
notification.publish({
id: alarm.id,
contentType: notification.ContentType.NOTIFICATION_TEXT,
content: {
title: alarm.title || '闹钟提醒',
text: alarm.content || '该起床了!'
},
tapAction: {
want: {
bundleName: 'com.example.alarmdemo',
abilityName: 'EnhancedAlarmNotificationAbility'
}
}
});
// 分布式通知
this.notifyAllDevices(alarm);
}
private notifyAllDevices(alarm: Alarm): void {
const devices = this.deviceManager.getTrustedDeviceListSync();
devices.forEach(device => {
distributedData.distributedNotification.publish({
scenario: 'alarm_reminder',
content: {
alarmId: alarm.id,
message: alarm.content
},
targetDevice: device.deviceId
});
});
}
private syncAlarmToAllDevices(alarm: Alarm): void {
const devices = this.deviceManager.getTrustedDeviceListSync();
devices.forEach(device => {
this.dataManager.syncData(ALARM_SYNC_CHANNEL, {
type: 'set',
alarm: alarm,
targetDevice: device.deviceId
});
});
}
private syncAllAlarmsToDevice(deviceId: string): void {
this.alarms.forEach(alarm => {
this.dataManager.syncData(ALARM_SYNC_CHANNEL, {
type: 'set',
alarm: alarm,
targetDevice: deviceId
});
});
}
private handleSyncData(data: any): void {
if (!data) return;
switch (data.type) {
case 'set':
if (data.alarm) {
this.handleSetAlarm(data.alarm);
}
break;
case 'cancel':
if (data.alarmId) {
this.handleCancelAlarm(data.alarmId);
}
break;
}
}
private handleSetAlarm(alarmData: any): void {
const alarm: Alarm = {
id: alarmData.id,
time: alarmData.time,
title: alarmData.title,
content: alarmData.content
};
// 避免重复设置
if (!this.alarms.has(alarm.id)) {
this.alarms.set(alarm.id, alarm);
this.scheduleLocalAlarm(alarm);
}
}
private handleCancelAlarm(alarmId: string): void {
if (this.alarms.has(alarmId)) {
this.alarms.delete(alarmId);
notification.cancel(alarmId);
}
}
}
export const enhancedAlarmService = new EnhancedAlarmService();
四、使用示例
1. 在应用中使用闹钟服务
// MainPage.ets
import { enhancedAlarmService } from './EnhancedAlarmService';
@Entry
@Component
struct MainPage {
@State alarms: Alarm[] = [];
build() {
Column() {
// 闹钟列表
List({ space: 10 }) {
ForEach(this.alarms, (alarm) => {
ListItem() {
this.buildAlarmItem(alarm);
}
})
}
.layoutWeight(1)
// 添加闹钟按钮
Button('添加闹钟')
.onClick(() => {
this.addSampleAlarm();
})
}
}
@Builder
buildAlarmItem(alarm: Alarm) {
Row() {
Column() {
Text(alarm.title)
.fontSize(18)
Text(new Date(alarm.time).toLocaleTimeString())
.fontSize(16)
}
.layoutWeight(1)
Button('取消')
.onClick(() => {
enhancedAlarmService.cancelAlarm(alarm.id);
this.alarms = this.alarms.filter(a => a.id !== alarm.id);
})
}
.padding(10)
}
private addSampleAlarm() {
const now = new Date();
const alarmTime = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate(),
now.getHours(),
now.getMinutes() + 2 // 2分钟后
);
const alarm: Alarm = {
id: `alarm_${Date.now()}`,
time: alarmTime.getTime(),
title: '测试闹钟',
content: '这是一个测试闹钟'
};
enhancedAlarmService.setAlarm(alarm);
this.alarms = [...this.alarms, alarm];
promptAction.showToast({
message: '已添加测试闹钟,2分钟后响铃',
duration: 2000
});
}
}
2. 跨设备同步测试
// AlarmSyncTest.ets
@Entry
@Component
struct AlarmSyncTest {
@State localAlarms: Alarm[] = [];
@State remoteDevices: Device[] = [];
@State remoteAlarms: Map<string, Alarm[]> = new Map();
private alarmService: EnhancedAlarmService = enhancedAlarmService;
aboutToAppear() {
this.loadDevices();
}
build() {
Column() {
// 本地闹钟
Text('本地闹钟').fontSize(20)
this.buildAlarmList(this.localAlarms)
// 远程设备闹钟
ForEach(this.remoteDevices, (device) => {
Text(`${device.deviceName}的闹钟`).fontSize(18)
this.buildAlarmList(this.remoteAlarms.get(device.deviceId) || [])
})
// 测试按钮
Button('添加测试闹钟到所有设备')
.onClick(() => {
this.addTestAlarmToAllDevices();
})
}
}
@Builder
buildAlarmList(alarms: Alarm[]) {
Column() {
ForEach(alarms, (alarm) => {
Row() {
Text(alarm.title)
Text(new Date(alarm.time).toLocaleTimeString())
}
})
}
}
private loadDevices() {
const devices = this.alarmService.getDeviceManager().getTrustedDeviceListSync();
this.remoteDevices = devices.map(device => ({
deviceId: device.deviceId,
deviceName: device.deviceName
}));
}
private addTestAlarmToAllDevices() {
const now = new Date();
const alarmTime = new Date(now.getTime() + 5 * 60 * 1000); // 5分钟后
const alarm: Alarm = {
id: `test_${now.getTime()}`,
time: alarmTime.getTime(),
title: '跨设备测试闹钟',
content: '这是一个跨设备同步的测试闹钟'
};
this.alarmService.setAlarm(alarm);
this.localAlarms = [...this.localAlarms, alarm];
// 模拟远程设备接收
this.remoteDevices.forEach(device => {
const existing = this.remoteAlarms.get(device.deviceId) || [];
this.remoteAlarms.set(device.deviceId, [...existing, alarm]);
});
}
}
interface Device {
deviceId: string;
deviceName: string;
}
五、性能优化与最佳实践
- 批量同步策略:当有多个闹钟需要同步时,采用批量同步减少网络请求
// 批量同步实现
public syncAllAlarms(): void {
const alarms = Array.from(this.alarms.values());
// 分批同步,每批10个
const batchSize = 10;
for (let i = 0; i < alarms.length; i += batchSize) {
const batch = alarms.slice(i, i + batchSize);
this.dataManager.syncData(ALARM_SYNC_CHANNEL, {
type: 'batchSet',
alarms: batch
});
}
}
- 智能唤醒:在设备休眠时优化闹钟触发
// AlarmScheduler.java
public class AlarmScheduler {
public static void scheduleExactAlarm(Context context, long triggerAtMillis) {
// 使用精确闹钟API
AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
if (alarmManager == null) return;
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(
triggerAtMillis, pendingIntent);
alarmManager.setAlarmClock(info, pendingIntent);
} else {
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
}
}
}
- 省电模式处理:检测设备是否处于省电模式并调整提醒策略
// 检查省电模式
import power from '@ohos.power';
function checkPowerSaveMode(): boolean {
try {
const mode = power.getPowerMode();
return mode === power.PowerMode.MODE_POWER_SAVE;
} catch (err) {
console.error('检查省电模式失败:', err);
return false;
}
}
// 调整提醒策略
function scheduleWithPowerSave(alarm: Alarm): void {
const isPowerSave = checkPowerSaveMode();
if (isPowerSave) {
// 省电模式下使用延迟提醒
setTimeout(() => {
showDelayedNotification(alarm);
}, 10000); // 延迟10秒
} else {
// 正常提醒
showNotification(alarm);
}
}
通过以上实现,我们创建了一个功能完善、跨设备同步的闹钟提醒系统,能够在鸿蒙生态中提供一致的用户体验。系统具备良好的扩展性,可以方便地添加更多高级功能如重复闹钟、智能跳过节假日等。
更多推荐

所有评论(0)