一、基础通知增强实现

1. 带优先级与振动配置的通知

import notificationManager from '@kit.NotificationManagerKit';

// 创建通知通道(Slot)
notificationManager.addSlot({
  slotId: 'high_priority',
  level: notificationManager.SlotLevel.LEVEL_HIGH,
  vibration: true,
  sound: 'sound.mp3'
});

// 发送高优先级通知
notificationManager.publish({
  id: 1001,
  slotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,
  content: {
    contentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
    normal: {
      title: '紧急系统更新',
      text: '立即重启设备完成安全补丁安装',
      additionalText: '剩余时间: 15分钟'
    }
  },
  deliveryTime: new Date().getTime() + 300000 // 5分钟后触发
}).catch(err => console.error('通知发送失败:', err));
  • 要点与说明
    • slotIdlevel 共同决定通知的优先级行为,建议对高优先级设置独立通道以避免被低优先级覆盖。
    • vibrationsound 是用户感知的核心体验要素,必要时允许自定义声音资源的路径或资源标识。
    • deliveryTime 支持定时投递,生产环境可结合任务队列或任务调度框架进一步稳定处理。

二、交互式通知开发

1. 带操作按钮的通知

import wantAgent from '@kit.AbilityKit';

// 定义 WantAgent 参数
const wantAgentInfo: wantAgent.WantAgentInfo = {
  wants: [
    {
      deviceId: '', // 空字符串表示本机
      bundleName: 'com.ohos.Noti',
      abilityName: 'EntryAbility',
      action: 'action.view'
    }
  ],
  operationType: wantAgent.OperationType.START_ABILITY
};

// 创建带操作的通知
wantAgent.getWantAgent(wantAgentInfo).then(agent => {
  notificationManager.publish({
    content: {
      normal: {
        title: '文件下载完成',
        text: '点击查看',
        wantAgent: agent  // 绑定点击跳转
      }
    },
    actions: [
      {
        title: '打开文件',
        want: {
          bundleName: 'com.example.myapp',
          abilityName: 'FileViewerAbility'
        }
      },
      {
        title: '删除',
        type: notificationManager.ActionType.DELETE
      }
    ]
  });
});
  • 要点与说明
    • WantAgent 作为“跳转目标”的绑定来源,确保能力名和 bundle 名正确且具备相应权限。
    • actions 提供多种按钮交互,例如打开应用内能力、删除等;必要时可扩展为“忽略/提醒稍后”等自定义类型。
    • 点击事件需在能力端实现对 wantAgent 的处理逻辑,确保用户体验流畅。

三、前台服务持续通知

1. 进度条实时更新

import taskpool from '@kit.TaskpoolKit';

// 启动前台服务
let notificationId = 2000;
notificationManager.publish({
  id: notificationId,
  isForegroundService: true,
  content: {
    contentType: notificationManager.ContentType.NOTIFICATION_CONTENT_PROGRESS,
    progress: {
      title: '视频转码中',
      text: '480p → 1080p',
      value: 0,
      maxValue: 100
    }
  }
});

// 异步更新进度
taskpool.execute(async () => {
  for (let progress = 0; progress <= 100; progress += 10) {
    await sleep(1000); // 模拟处理延时
    notificationManager.publish({
      id: notificationId,
      content: {
        progress: { value: progress }
      }
    });
  }
});

// 辅助睡眠函数
function sleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}
  • 要点与说明
    • isForegroundService: true 能确保任务在后台持续执行时不易被系统杀死。
    • 进度更新应尽量避免高频创建,优先使用更新接口来变更已存在的通知内容(如本文使用同一 id 的更新)。

四、分布式通知同步

1. 跨设备消息广播

import distributedKVStore from '@kit.DistributedKVStore';

// 初始化分布式数据库
const kvManager = distributedKVStore.createKVManager({
  context: getContext(this),
  bundleId: 'com.example.myapp'
});

const kvStore = await kvManager.getKVStore('notifications');

// 监听数据变化
kvStore.on('dataChange', (event) => {
  if (event.inserted.length > 0) {
    const notification = event.inserted.value;
    notificationManager.publish(notification);
  }
});

// 发送到其他设备
function syncNotification(deviceId: string, content: string) {
  const notificationKey = `msg_${Date.now()}`;
  kvStore.put(notificationKey, {
    deviceId: deviceId,
    content: content,
    timestamp: new Date().toISOString()
  });
}
  • 要点与说明
    • dataChange 事件应尽量过滤重复事件,防止通知重复投递。
    • 发送的数据要控制大小,遵循后续的 100KB 内部压缩要求。
    • 考虑时钟差异与冲突,添加时间戳/版本号等字段进行冲突解决。

五、定时精准提醒

1. 周期性日程提醒

import reminderAgent from '@kit.ReminderAgentKit';

// 设置每日提醒
const reminder: reminderAgent.ReminderRequest = {
  reminderType: reminderAgent.ReminderType.CALENDAR,
  triggerTime: {
    hour: 9,
    minute: 30,
    daysOfWeek: [1, 2, 3, 4, 5] // 周一到周五
  },
  actionButton: [
    { title: '签到', type: reminderAgent.ActionButtonType.OPEN_APP },
    { title: '忽略', type: reminderAgent.ActionButtonType.CLOSE }
  ]
};

// 注册提醒
reminderAgent.publishReminder(reminder)
  .then(reminderId => console.log('提醒ID:', reminderId))
  .catch(err => console.error('设置失败:', err));
  • 要点与说明
    • daysOfWeek 的排序和时区处理需在实现中明确,确保跨区域用户体验一致。
    • actionButton 提供快速行动入口,OPEN_APPCLOSE 以符合系统行为规范。
    • 提醒成功后应提供回调或事件以供上层记录与统计。

六、自定义通知视图

1. 大图样式通知

notificationManager.publish({
  content: {
    contentType: notificationManager.ContentType.NOTIFICATION_CONTENT_PICTURE,
    picture: {
      title: '风景美图分享',
      text: '来自用户@旅行者',
      expandedTitle: '点击查看大图',
      briefText: '西藏风光',
      image: $r('app.media.himalaya') // 引用资源文件
    }
  },
  slotType: notificationManager.SlotType.CONTENT_INFORMATIVE
});
  • 要点与说明
    • 图片资源引用方式需与应用资源系统对齐,确保跨设备可渲染。
    • 未来可扩展为更多自定义视图类型,如“大图 + 操作条”、图片轮播等。

七、异常处理规范

1. 权限校验与发送前防护

// 权限检查
import abilityAccessCtrl from '@kit.AbilityAccessCtrlKit';

async function checkNotificationPermission() {
  try {
    const atManager = abilityAccessCtrl.createAtManager();
    const status = await atManager.checkAccessToken(
      abilityAccessCtrl.AccessToken.ATokenType.HAP,
      'ohos.permission.NOTIFICATION'
    );
    return status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
  } catch (err) {
    console.error('权限检查异常:', err);
    return false;
  }
}

// 发送前验证
if (await checkNotificationPermission()) {
  // 执行通知发送
} else {
  console.warn('通知权限未授予');
}
  • 要点与说明
    • 将权限检查前置到发送前,避免用户看到失败体验。
    • 对异常情况应有明确日志和上报机制,便于排查与统计。

关键配置项说明

  1. 权限声明

module.json5 中添加所需权限:

"requestPermissions": [
  { "name": "ohos.permission.NOTIFICATION" },
  { "name": "ohos.permission.DISTRIBUTED_DATASYNC" }
]
  1. 性能优化建议
  • 避免在循环中频繁创建新通知,优先使用 updateNotification(或等效的更新接口)来变更已存在的通知内容。
  • 分布式通知需压缩数据至 100KB 以内,避免网络带宽与时间成本过大。
  • 长时间任务通知需绑定 foregroundService,避免进程被系统杀死;必要时结合断点续传与心跳机制。
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐