鸿蒙后台任务管理开发指南【3】

2025-06-30 23:44:57
104次阅读
0个评论

第三篇:延迟任务开发实战

概述

延迟任务(Work Scheduler)是鸿蒙系统提供的一种智能后台任务调度机制,适用于实时性要求不高、可延迟执行的任务。系统会根据设备的网络状态、电池电量、充电状态、存储空间等条件,在最合适的时机执行这些任务,从而实现资源的优化配置和设备功耗的有效控制。

延迟任务特别适合那些对时间不敏感但对系统资源敏感的场景,如数据备份、日志上传、缓存清理等。通过延迟任务,应用可以在用户无感知的情况下完成这些维护性工作,提升整体用户体验。

1. 延迟任务基础概念

1.1 触发条件

延迟任务支持多种触发条件的组合:

网络类型条件

  • NETWORK_TYPE_ANY:任何网络连接
  • NETWORK_TYPE_MOBILE:移动数据网络
  • NETWORK_TYPE_WIFI:WiFi网络
  • NETWORK_TYPE_BLUETOOTH:蓝牙网络
  • NETWORK_TYPE_ETHERNET:以太网

电池状态条件

  • 电池电量百分比(0-100)
  • 低电量、正常电量、充足电量等状态

充电状态条件

  • CHARGING_PLUGGED_ANY:任何充电方式
  • CHARGING_PLUGGED_AC:交流电充电
  • CHARGING_PLUGGED_USB:USB充电
  • CHARGING_PLUGGED_WIRELESS:无线充电

存储状态条件

  • STORAGE_LEVEL_LOW:存储空间不足
  • STORAGE_LEVEL_OKAY:存储空间正常
  • STORAGE_LEVEL_LOW_OR_OKAY:存储空间不足或正常

1.2 系统调度机制

系统根据应用的活跃程度将其分为不同组别,并设置不同的执行频率:

活跃分组:最小间隔2小时,适用于用户经常使用的应用 经常使用分组:最小间隔4小时,适用于用户定期使用的应用 常用分组:最小间隔24小时,适用于用户偶尔使用的应用 极少使用分组:最小间隔48小时,适用于用户很少使用的应用 受限分组:禁止执行延迟任务 从未使用分组:禁止执行延迟任务

2. 延迟任务实现

2.1 基础延迟任务管理

import { workScheduler } from '@kit.BackgroundTasksKit';
import { BusinessError } from '@kit.BasicServicesKit';

export class WorkSchedulerManager {
  private workInfos: Map<number, workScheduler.WorkInfo> = new Map();

  /**
   * 启动延迟任务
   * @param workInfo 任务信息
   */
  async startWork(workInfo: workScheduler.WorkInfo): Promise<boolean> {
    try {
      await workScheduler.startWork(workInfo);
      this.workInfos.set(workInfo.workId, workInfo);
      console.info(`延迟任务启动成功,任务ID: ${workInfo.workId}`);
      return true;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`延迟任务启动失败: ${err.code}, ${err.message}`);
      return false;
    }
  }

  /**
   * 停止延迟任务
   * @param workId 任务ID
   */
  async stopWork(workId: number): Promise<boolean> {
    try {
      await workScheduler.stopWork(workInfo, needCancel);
      this.workInfos.delete(workId);
      console.info(`延迟任务停止成功,任务ID: ${workId}`);
      return true;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`延迟任务停止失败: ${err.code}, ${err.message}`);
      return false;
    }
  }

  /**
   * 获取任务状态
   * @param workId 任务ID
   */
  async getWorkStatus(workId: number): Promise<workScheduler.WorkInfo | undefined> {
    try {
      const workInfo = await workScheduler.getWorkStatus(workId);
      console.info(`任务状态查询成功: ${JSON.stringify(workInfo)}`);
      return workInfo;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`任务状态查询失败: ${err.code}, ${err.message}`);
      return undefined;
    }
  }

  /**
   * 获取所有任务状态
   */
  async obtainAllWorks(): Promise<Array<workScheduler.WorkInfo>> {
    try {
      const workInfos = await workScheduler.obtainAllWorks();
      console.info(`获取所有任务成功,共${workInfos.length}个任务`);
      return workInfos;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`获取所有任务失败: ${err.code}, ${err.message}`);
      return [];
    }
  }

  /**
   * 停止并清除任务
   * @param workId 任务ID
   */
  async stopAndClearWork(workId: number): Promise<boolean> {
    try {
      await workScheduler.stopAndClearWork(workId);
      this.workInfos.delete(workId);
      console.info(`任务停止并清除成功,任务ID: ${workId}`);
      return true;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`任务停止并清除失败: ${err.code}, ${err.message}`);
      return false;
    }
  }

  /**
   * 检查最后一次任务是否超时
   * @param workId 任务ID
   */
  async isLastWorkTimeOut(workId: number): Promise<boolean> {
    try {
      const isTimeout = await workScheduler.isLastWorkTimeOut(workId);
      console.info(`任务${workId}超时状态: ${isTimeout}`);
      return isTimeout;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`检查任务超时状态失败: ${err.code}, ${err.message}`);
      return false;
    }
  }
}

2.2 智能数据同步延迟任务

export class SmartDataSyncManager {
  private workSchedulerManager: WorkSchedulerManager;
  private readonly SYNC_WORK_ID = 2001;

  constructor() {
    this.workSchedulerManager = new WorkSchedulerManager();
  }

  /**
   * 启动智能数据同步任务
   * 仅在WiFi环境且电量充足时执行
   */
  async startSmartDataSync(): Promise<boolean> {
    const workInfo: workScheduler.WorkInfo = {
      workId: this.SYNC_WORK_ID,
      bundleName: 'com.example.myapplication',
      abilityName: 'DataSyncWorkSchedulerExtensionAbility',
      networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI, // 仅WiFi环境
      isCharging: false, // 不要求充电
      chargerType: workScheduler.ChargingType.CHARGING_PLUGGED_ANY,
      batteryLevel: 30, // 电量高于30%
      batteryStatus: workScheduler.BatteryStatus.BATTERY_STATUS_OKAY, // 电池状态良好
      storageRequest: workScheduler.StorageRequest.STORAGE_LEVEL_OKAY, // 存储空间充足
      isRepeat: true, // 重复执行
      repeatCycleTime: 24 * 60 * 60 * 1000, // 24小时重复一次
      repeatCount: -1, // 无限重复
      parameters: {
        syncType: 'full',
        priority: 'low'
      }
    };

    const success = await this.workSchedulerManager.startWork(workInfo);
    if (success) {
      console.info('智能数据同步任务启动成功');
    }
    return success;
  }

  /**
   * 启动充电时的大文件下载任务
   */
  async startChargingDownloadTask(): Promise<boolean> {
    const workInfo: workScheduler.WorkInfo = {
      workId: this.SYNC_WORK_ID + 1,
      bundleName: 'com.example.myapplication',
      abilityName: 'DownloadWorkSchedulerExtensionAbility',
      networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI,
      isCharging: true, // 要求充电状态
      chargerType: workScheduler.ChargingType.CHARGING_PLUGGED_ANY,
      batteryLevel: 20, // 电量高于20%即可,因为在充电
      storageRequest: workScheduler.StorageRequest.STORAGE_LEVEL_OKAY,
      isRepeat: false, // 单次执行
      parameters: {
        downloadUrl: 'xxxxxx',
        targetPath: '/data/downloads/',
        maxRetries: 3
      }
    };

    return await this.workSchedulerManager.startWork(workInfo);
  }

  /**
   * 启动存储清理任务
   * 在存储空间不足时自动清理
   */
  async startStorageCleanupTask(): Promise<boolean> {
    const workInfo: workScheduler.WorkInfo = {
      workId: this.SYNC_WORK_ID + 2,
      bundleName: 'com.example.myapplication',
      abilityName: 'CleanupWorkSchedulerExtensionAbility',
      networkType: workScheduler.NetworkType.NETWORK_TYPE_ANY,
      storageRequest: workScheduler.StorageRequest.STORAGE_LEVEL_LOW, // 存储空间不足时触发
      isRepeat: true,
      repeatCycleTime: 7 * 24 * 60 * 60 * 1000, // 7天重复一次
      parameters: {
        cleanupType: 'cache',
        maxCacheSize: '500MB'
      }
    };

    return await this.workSchedulerManager.startWork(workInfo);
  }

  /**
   * 停止所有同步相关任务
   */
  async stopAllSyncTasks(): Promise<void> {
    await this.workSchedulerManager.stopWork(this.SYNC_WORK_ID);
    await this.workSchedulerManager.stopWork(this.SYNC_WORK_ID + 1);
    await this.workSchedulerManager.stopWork(this.SYNC_WORK_ID + 2);
    console.info('所有同步任务已停止');
  }
}

2.3 WorkSchedulerExtensionAbility实现

import { WorkSchedulerExtensionAbility } from '@kit.BackgroundTasksKit';
import { workScheduler } from '@kit.BackgroundTasksKit';

export default class DataSyncWorkSchedulerExtensionAbility extends WorkSchedulerExtensionAbility {
  
  /**
   * 延迟任务开始执行
   */
  onWorkStart(work: workScheduler.WorkInfo): void {
    console.info(`延迟任务开始执行: ${JSON.stringify(work)}`);
    
    // 根据任务参数执行不同的逻辑
    const syncType = work.parameters?.['syncType'] as string;
    const priority = work.parameters?.['priority'] as string;
    
    switch (syncType) {
      case 'full':
        this.performFullSync(priority);
        break;
      case 'incremental':
        this.performIncrementalSync(priority);
        break;
      default:
        this.performDefaultSync();
    }
  }

  /**
   * 延迟任务停止执行
   */
  onWorkStop(work: workScheduler.WorkInfo): void {
    console.info(`延迟任务停止执行: ${JSON.stringify(work)}`);
    
    // 执行清理工作
    this.cleanup();
  }

  /**
   * 执行完整同步
   */
  private async performFullSync(priority: string): Promise<void> {
    console.info(`开始执行完整同步,优先级: ${priority}`);
    
    try {
      // 模拟数据同步过程
      await this.syncUserData();
      await this.syncAppSettings();
      await this.syncMediaFiles();
      
      console.info('完整同步执行完成');
    } catch (error) {
      console.error('完整同步执行失败:', error);
    }
  }

  /**
   * 执行增量同步
   */
  private async performIncrementalSync(priority: string): Promise<void> {
    console.info(`开始执行增量同步,优先级: ${priority}`);
    
    try {
      // 获取上次同步时间
      const lastSyncTime = await this.getLastSyncTime();
      
      // 同步增量数据
      await this.syncIncrementalData(lastSyncTime);
      
      // 更新同步时间
      await this.updateLastSyncTime();
      
      console.info('增量同步执行完成');
    } catch (error) {
      console.error('增量同步执行失败:', error);
    }
  }

  /**
   * 执行默认同步
   */
  private async performDefaultSync(): Promise<void> {
    console.info('开始执行默认同步');
    
    try {
      // 执行基础同步逻辑
      await this.syncEssentialData();
      
      console.info('默认同步执行完成');
    } catch (error) {
      console.error('默认同步执行失败:', error);
    }
  }

  /**
   * 同步用户数据
   */
  private async syncUserData(): Promise<void> {
    return new Promise((resolve) => {
      setTimeout(() => {
        console.info('用户数据同步完成');
        resolve();
      }, 5000);
    });
  }

  /**
   * 同步应用设置
   */
  private async syncAppSettings(): Promise<void> {
    return new Promise((resolve) => {
      setTimeout(() => {
        console.info('应用设置同步完成');
        resolve();
      }, 2000);
    });
  }

  /**
   * 同步媒体文件
   */
  private async syncMediaFiles(): Promise<void> {
    return new Promise((resolve) => {
      setTimeout(() => {
        console.info('媒体文件同步完成');
        resolve();
      }, 10000);
    });
  }

  /**
   * 获取上次同步时间
   */
  private async getLastSyncTime(): Promise<number> {
    // 从本地存储获取上次同步时间
    return Date.now() - 24 * 60 * 60 * 1000; // 模拟24小时前
  }

  /**
   * 同步增量数据
   */
  private async syncIncrementalData(since: number): Promise<void> {
    console.info(`同步从${new Date(since)}以来的增量数据`);
    return new Promise((resolve) => {
      setTimeout(() => {
        console.info('增量数据同步完成');
        resolve();
      }, 3000);
    });
  }

  /**
   * 更新同步时间
   */
  private async updateLastSyncTime(): Promise<void> {
    // 更新本地存储的同步时间
    console.info('同步时间已更新');
  }

  /**
   * 同步基础数据
   */
  private async syncEssentialData(): Promise<void> {
    return new Promise((resolve) => {
      setTimeout(() => {
        console.info('基础数据同步完成');
        resolve();
      }, 1000);
    });
  }

  /**
   * 清理资源
   */
  private cleanup(): void {
    console.info('执行延迟任务清理工作');
    // 释放资源,清理临时文件等
  }
}

3. 延迟任务优化策略

3.1 条件组合优化

export class OptimizedWorkScheduler {
  
  /**
   * 创建节能型数据备份任务
   * 多条件组合确保在最佳时机执行
   */
  createEnergyEfficientBackupTask(): workScheduler.WorkInfo {
    return {
      workId: 3001,
      bundleName: 'com.example.myapplication',
      abilityName: 'BackupWorkSchedulerExtensionAbility',
      // 网络条件:优先WiFi,移动网络也可以
      networkType: workScheduler.NetworkType.NETWORK_TYPE_WIFI,
      // 电量条件:电量充足或正在充电
      batteryLevel: 50, // 电量高于50%
      isCharging: false, // 不强制要求充电,但充电时优先执行
      // 存储条件:确保有足够空间
      storageRequest: workScheduler.StorageRequest.STORAGE_LEVEL_OKAY,
      // 时间条件:深夜执行,避免影响用户使用
      isDeepIdle: true, // 设备深度空闲时执行
      // 重复设置
      isRepeat: true,
      repeatCycleTime: 7 * 24 * 60 * 60 * 1000, // 每周执行一次
      // 任务参数
      parameters: {
        backupType: 'incremental',
        compressionLevel: 'medium',
        encryptionEnabled: true
      }
    };
  }

  /**
   * 创建智能缓存清理任务
   * 根据存储状态动态调整清理策略
   */
  createSmartCacheCleanupTask(): workScheduler.WorkInfo {
    return {
      workId: 3002,
      bundleName: 'com.example.myapplication',
      abilityName: 'CacheCleanupWorkSchedulerExtensionAbility',
      // 存储空间不足时触发
      storageRequest: workScheduler.StorageRequest.STORAGE_LEVEL_LOW,
      // 不限制网络类型
      networkType: workScheduler.NetworkType.NETWORK_TYPE_ANY,
      // 电量要求不高
      batteryLevel: 15,
      // 可重复执行
      isRepeat: true,
      repeatCycleTime: 3 * 24 * 60 * 60 * 1000, // 每3天检查一次
      parameters: {
        cleanupStrategy: 'aggressive', // 存储不足时使用激进清理策略
        preserveRecentFiles: true,
        maxCleanupSize: '1GB'
      }
    };
  }
}

通过本篇的学习,开发者可以掌握鸿蒙延迟任务的智能调度机制,实现高效的后台任务管理和系统资源优化。


第四篇:代理提醒开发实战

概述

代理提醒(Agent Powered Reminder)是鸿蒙系统提供的一种特殊后台任务机制,当应用退后台或进程终止后,系统会代理应用执行相应的提醒功能。这种机制特别适用于定时提醒类业务,确保即使应用不在前台运行,用户也能及时收到重要提醒。

代理提醒支持三种类型:倒计时提醒、日历提醒和闹钟提醒。每种类型都有其特定的使用场景和配置方式,开发者可以根据实际需求选择合适的提醒类型。

1. 代理提醒基础概念

1.1 提醒类型

倒计时提醒:适用于短期定时任务,如番茄钟、烹饪计时器、运动计时等场景。

日历提醒:适用于特定日期时间的提醒,如会议提醒、生日提醒、纪念日提醒等。

闹钟提醒:适用于重复性的定时提醒,如每日闹钟、周期性任务提醒等。

1.2 权限配置

使用代理提醒需要在应用配置文件中声明相应权限:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.PUBLISH_AGENT_REMINDER",
        "reason": "用于发布代理提醒",
        "usedScene": {
          "abilities": ["MainAbility"],
          "when": "always"
        }
      }
    ]
  }
}

2. 代理提醒实现

2.1 基础代理提醒管理

import { reminderAgentManager } from '@kit.BackgroundTasksKit';
import { BusinessError } from '@kit.BasicServicesKit';

export class ReminderManager {
  private reminders: Map<number, reminderAgentManager.ReminderRequest> = new Map();

  /**
   * 发布代理提醒
   * @param reminderReq 提醒请求
   */
  async publishReminder(reminderReq: reminderAgentManager.ReminderRequest): Promise<number | undefined> {
    try {
      const reminderId = await reminderAgentManager.publishReminder(reminderReq);
      this.reminders.set(reminderId, reminderReq);
      console.info(`代理提醒发布成功,提醒ID: ${reminderId}`);
      return reminderId;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`代理提醒发布失败: ${err.code}, ${err.message}`);
      return undefined;
    }
  }

  /**
   * 取消代理提醒
   * @param reminderId 提醒ID
   */
  async cancelReminder(reminderId: number): Promise<boolean> {
    try {
      await reminderAgentManager.cancelReminder(reminderId);
      this.reminders.delete(reminderId);
      console.info(`代理提醒取消成功,提醒ID: ${reminderId}`);
      return true;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`代理提醒取消失败: ${err.code}, ${err.message}`);
      return false;
    }
  }

  /**
   * 获取所有有效提醒
   */
  async getValidReminders(): Promise<Array<reminderAgentManager.ReminderRequest>> {
    try {
      const reminders = await reminderAgentManager.getValidReminders();
      console.info(`获取有效提醒成功,共${reminders.length}个提醒`);
      return reminders;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`获取有效提醒失败: ${err.code}, ${err.message}`);
      return [];
    }
  }

  /**
   * 取消所有提醒
   */
  async cancelAllReminders(): Promise<boolean> {
    try {
      await reminderAgentManager.cancelAllReminders();
      this.reminders.clear();
      console.info('所有代理提醒已取消');
      return true;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`取消所有提醒失败: ${err.code}, ${err.message}`);
      return false;
    }
  }

  /**
   * 添加通知插槽
   * @param slot 通知插槽
   */
  async addNotificationSlot(slot: reminderAgentManager.NotificationSlot): Promise<boolean> {
    try {
      await reminderAgentManager.addNotificationSlot(slot);
      console.info('通知插槽添加成功');
      return true;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`通知插槽添加失败: ${err.code}, ${err.message}`);
      return false;
    }
  }

  /**
   * 移除通知插槽
   * @param slotType 插槽类型
   */
  async removeNotificationSlot(slotType: reminderAgentManager.SlotType): Promise<boolean> {
    try {
      await reminderAgentManager.removeNotificationSlot(slotType);
      console.info('通知插槽移除成功');
      return true;
    } catch (error) {
      const err = error as BusinessError;
      console.error(`通知插槽移除失败: ${err.code}, ${err.message}`);
      return false;
    }
  }
}

2.2 倒计时提醒实现

export class CountdownReminderManager extends ReminderManager {

  /**
   * 创建倒计时提醒
   * @param title 提醒标题
   * @param content 提醒内容
   * @param countdownSeconds 倒计时秒数
   */
  async createCountdownReminder(
    title: string,
    content: string,
    countdownSeconds: number
  ): Promise<number | undefined> {
    
    // 创建通知动作按钮
    const actionButton1: reminderAgentManager.ActionButton = {
      title: '稍后提醒',
      type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE
    };

    const actionButton2: reminderAgentManager.ActionButton = {
      title: '关闭提醒',
      type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
    };

    // 创建Want Agent,用于点击提醒时的跳转
    const wantAgentInfo: wantAgent.WantAgentInfo = {
      wants: [
        {
          bundleName: 'com.example.myapplication',
          abilityName: 'MainAbility',
          parameters: {
            reminderType: 'countdown',
            reminderTitle: title
          }
        }
      ],
      operationType: wantAgent.OperationType.START_ABILITY,
      requestCode: 0,
      wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
    };

    const wantAgent = await wantAgent.getWantAgent(wantAgentInfo);

    // 创建倒计时提醒请求
    const countdownRequest: reminderAgentManager.ReminderRequestTimer = {
      reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_TIMER,
      triggerTimeInSeconds: countdownSeconds,
      actionButton: [actionButton1, actionButton2],
      wantAgent: wantAgent,
      maxScreenWantAgent: wantAgent,
      title: title,
      content: content,
      expiredContent: '倒计时已结束',
      notificationId: 100,
      slotType: reminderAgentManager.SlotType.REMINDER
    };

    return await this.publishReminder(countdownRequest);
  }

  /**
   * 创建番茄钟提醒
   * @param sessionName 番茄钟会话名称
   * @param minutes 番茄钟时长(分钟)
   */
  async createPomodoroReminder(sessionName: string, minutes: number): Promise<number | undefined> {
    const title = `番茄钟:${sessionName}`;
    const content = `专注时间:${minutes}分钟`;
    const seconds = minutes * 60;

    return await this.createCountdownReminder(title, content, seconds);
  }

  /**
   * 创建烹饪计时器
   * @param dishName 菜品名称
   * @param cookingMinutes 烹饪时长(分钟)
   */
  async createCookingTimer(dishName: string, cookingMinutes: number): Promise<number | undefined> {
    const title = `烹饪计时:${dishName}`;
    const content = `还需要${cookingMinutes}分钟`;
    const seconds = cookingMinutes * 60;

    return await this.createCountdownReminder(title, content, seconds);
  }

  /**
   * 创建运动计时器
   * @param exerciseName 运动项目名称
   * @param durationMinutes 运动时长(分钟)
   */
  async createExerciseTimer(exerciseName: string, durationMinutes: number): Promise<number | undefined> {
    const title = `运动计时:${exerciseName}`;
    const content = `目标时长:${durationMinutes}分钟`;
    const seconds = durationMinutes * 60;

    return await this.createCountdownReminder(title, content, seconds);
  }
}

2.3 日历提醒实现

export class CalendarReminderManager extends ReminderManager {

  /**
   * 创建日历提醒
   * @param title 提醒标题
   * @param content 提醒内容
   * @param dateTime 提醒时间
   */
  async createCalendarReminder(
    title: string,
    content: string,
    dateTime: Date
  ): Promise<number | undefined> {

    // 计算提醒时间(从1970年1月1日开始的秒数)
    const triggerTimeInSeconds = Math.floor(dateTime.getTime() / 1000);

    // 创建日历提醒请求
    const calendarRequest: reminderAgentManager.ReminderRequestCalendar = {
      reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_CALENDAR,
      dateTime: {
        year: dateTime.getFullYear(),
        month: dateTime.getMonth() + 1, // 月份从0开始,需要加1
        day: dateTime.getDate(),
        hour: dateTime.getHours(),
        minute: dateTime.getMinutes(),
        second: dateTime.getSeconds()
      },
      repeatMonths: [], // 不重复
      repeatDays: [], // 不重复
      actionButton: [
        {
          title: '查看详情',
          type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_CUSTOM
        },
        {
          title: '稍后提醒',
          type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE
        }
      ],
      title: title,
      content: content,
      expiredContent: '提醒时间已过',
      snoozeContent: '稍后提醒',
      notificationId: 200,
      slotType: reminderAgentManager.SlotType.REMINDER
    };

    return await this.publishReminder(calendarRequest);
  }

  /**
   * 创建会议提醒
   * @param meetingTitle 会议标题
   * @param meetingTime 会议时间
   * @param location 会议地点
   * @param advanceMinutes 提前提醒分钟数
   */
  async createMeetingReminder(
    meetingTitle: string,
    meetingTime: Date,
    location: string,
    advanceMinutes: number = 15
  ): Promise<number | undefined> {

    // 计算提醒时间(会议开始前advanceMinutes分钟)
    const reminderTime = new Date(meetingTime.getTime() - advanceMinutes * 60 * 1000);

    const title = `会议提醒:${meetingTitle}`;
    const content = `${advanceMinutes}分钟后在${location}开始会议`;

    return await this.createCalendarReminder(title, content, reminderTime);
  }

  /**
   * 创建生日提醒
   * @param personName 人员姓名
   * @param birthdayDate 生日日期
   * @param age 年龄
   */
  async createBirthdayReminder(
    personName: string,
    birthdayDate: Date,
    age?: number
  ): Promise<number | undefined> {

    const title = `生日提醒:${personName}`;
    const content = age ? `今天是${personName}的${age}岁生日` : `今天是${personName}的生日`;

    // 设置为每年重复
    const birthdayRequest: reminderAgentManager.ReminderRequestCalendar = {
      reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_CALENDAR,
      dateTime: {
        year: birthdayDate.getFullYear(),
        month: birthdayDate.getMonth() + 1,
        day: birthdayDate.getDate(),
        hour: 9, // 上午9点提醒
        minute: 0,
        second: 0
      },
      repeatMonths: [birthdayDate.getMonth() + 1], // 每年同月重复
      repeatDays: [birthdayDate.getDate()], // 每年同日重复
      title: title,
      content: content,
      expiredContent: '生日已过',
      notificationId: 300,
      slotType: reminderAgentManager.SlotType.REMINDER
    };

    return await this.publishReminder(birthdayRequest);
  }

  /**
   * 创建纪念日提醒
   * @param eventName 事件名称
   * @param anniversaryDate 纪念日日期
   * @param yearsSince 距今年数
   */
  async createAnniversaryReminder(
    eventName: string,
    anniversaryDate: Date,
    yearsSince?: number
  ): Promise<number | undefined> {

    const title = `纪念日提醒:${eventName}`;
    const content = yearsSince ? `今天是${eventName}${yearsSince}周年纪念日` : `今天是${eventName}纪念日`;

    return await this.createCalendarReminder(title, content, anniversaryDate);
  }
}

2.4 闹钟提醒实现

export class AlarmReminderManager extends ReminderManager {

  /**
   * 创建闹钟提醒
   * @param title 闹钟标题
   * @param hour 小时(0-23)
   * @param minute 分钟(0-59)
   * @param daysOfWeek 重复的星期几(1-7,1为周一)
   */
  async createAlarmReminder(
    title: string,
    hour: number,
    minute: number,
    daysOfWeek: number[] = []
  ): Promise<number | undefined> {

    // 创建闹钟提醒请求
    const alarmRequest: reminderAgentManager.ReminderRequestAlarm = {
      reminderType: reminderAgentManager.ReminderType.REMINDER_TYPE_ALARM,
      hour: hour,
      minute: minute,
      daysOfWeek: daysOfWeek,
      actionButton: [
        {
          title: '关闭',
          type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE
        },
        {
          title: '稍后提醒',
          type: reminderAgentManager.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE
        }
      ],
      title: title,
      content: `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')} 闹钟`,
      expiredContent: '闹钟时间已过',
      snoozeContent: '稍后提醒',
      snoozeTimes: 3, // 最多稍后提醒3次
      timeInterval: 10 * 60, // 稍后提醒间隔10分钟
      notificationId: 400,
      slotType: reminderAgentManager.SlotType.REMINDER
    };

    return await this.publishReminder(alarmRequest);
  }

  /**
   * 创建每日闹钟
   * @param title 闹钟标题
   * @param hour 小时
   * @param minute 分钟
   */
  async createDailyAlarm(title: string, hour: number, minute: number): Promise<number | undefined> {
    // 每天重复(周一到周日)
    const daysOfWeek = [1, 2, 3, 4, 5, 6, 7];
    return await this.createAlarmReminder(title, hour, minute, daysOfWeek);
  }

  /**
   * 创建工作日闹钟
   * @param title 闹钟标题
   * @param hour 小时
   * @param minute 分钟
   */
  async createWeekdayAlarm(title: string, hour: number, minute: number): Promise<number | undefined> {
    // 工作日重复(周一到周五)
    const daysOfWeek = [1, 2, 3, 4, 5];
    return await this.createAlarmReminder(title, hour, minute, daysOfWeek);
  }

  /**
   * 创建周末闹钟
   * @param title 闹钟标题
   * @param hour 小时
   * @param minute 分钟
   */
  async createWeekendAlarm(title: string, hour: number, minute: number): Promise<number | undefined> {
    // 周末重复(周六和周日)
    const daysOfWeek = [6, 7];
    return await this.createAlarmReminder(title, hour, minute, daysOfWeek);
  }

  /**
   * 创建自定义重复闹钟
   * @param title 闹钟标题
   * @param hour 小时
   * @param minute 分钟
   * @param repeatDays 重复的日期(周一=1,周二=2,...,周日=7)
   */
  async createCustomRepeatAlarm(
    title: string,
    hour: number,
    minute: number,
    repeatDays: number[]
  ): Promise<number | undefined> {
    return await this.createAlarmReminder(title, hour, minute, repeatDays);
  }

  /**
   * 创建单次闹钟
   * @param title 闹钟标题
   * @param hour 小时
   * @param minute 分钟
   */
  async createSingleAlarm(title: string, hour: number, minute: number): Promise<number | undefined> {
    // 不重复的闹钟
    return await this.createAlarmReminder(title, hour, minute, []);
  }
}

3. 综合提醒管理系统

3.1 统一提醒管理器

export class UnifiedReminderManager {
  private countdownManager: CountdownReminderManager;
  private calendarManager: CalendarReminderManager;
  private alarmManager: AlarmReminderManager;

  constructor() {
    this.countdownManager = new CountdownReminderManager();
    this.calendarManager = new CalendarReminderManager();
    this.alarmManager = new AlarmReminderManager();
  }

  /**
   * 初始化提醒系统
   */
  async initialize(): Promise<boolean> {
    try {
      // 添加提醒通知插槽
      const reminderSlot: reminderAgentManager.NotificationSlot = {
        type: reminderAgentManager.SlotType.REMINDER,
        level: reminderAgentManager.SlotLevel.LEVEL_HIGH,
        desc: '代理提醒通知',
        badgeFlag: true,
        bypassDnd: true, // 绕过勿扰模式
        lockscreenVisibility: reminderAgentManager.VisibilityType.PUBLIC,
        vibrationEnabled: true,
        sound: 'default',
        lightEnabled: true,
        lightColor: 0xFF0000
      };

      await this.countdownManager.addNotificationSlot(reminderSlot);
      console.info('提醒系统初始化成功');
      return true;
    } catch (error) {
      console.error('提醒系统初始化失败:', error);
      return false;
    }
  }

  /**
   * 获取倒计时管理器
   */
  getCountdownManager(): CountdownReminderManager {
    return this.countdownManager;
  }

  /**
   * 获取日历管理器
   */
  getCalendarManager(): CalendarReminderManager {
    return this.calendarManager;
  }

  /**
   * 获取闹钟管理器
   */
  getAlarmManager(): AlarmReminderManager {
    return this.alarmManager;
  }

  /**
   * 获取所有活跃提醒
   */
  async getAllActiveReminders(): Promise<Array<reminderAgentManager.ReminderRequest>> {
    const allReminders = await this.countdownManager.getValidReminders();
    console.info(`当前共有${allReminders.length}个活跃提醒`);
    return allReminders;
  }

  /**
   * 清理所有提醒
   */
  async clearAllReminders(): Promise<boolean> {
    try {
      await this.countdownManager.cancelAllReminders();
      console.info('所有提醒已清理');
      return true;
    } catch (error) {
      console.error('清理提醒失败:', error);
      return false;
    }
  }
}

通过本篇的学习,开发者可以掌握鸿蒙代理提醒的完整实现方案,为用户提供可靠的定时提醒服务,即使应用不在前台运行也能确保重要提醒不被错过。

总结

本指南详细介绍了鸿蒙系统的四种后台任务类型:短时任务、长时任务、延迟任务和代理提醒。每种任务类型都有其特定的使用场景和实现方式,开发者应根据实际需求选择合适的后台任务类型,并遵循系统的资源管控机制,实现高效、节能的后台任务管理。

收藏00

登录 后评论。没有帐号? 注册 一个。