You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular PWA Badging API:如何实现后台/杀死状态下角标自动更新?

解决PWA后台/被杀状态下推送更新角标问题

问题分析

当前代码仅在应用前台时,通过页面给Service Worker发消息更新角标,但后台或应用被杀时页面未运行,无法触发消息发送,导致角标不更新。核心问题是依赖页面触发角标更新,未利用Service Worker的推送事件唤醒机制。

解决方案

直接在Service Worker的push事件监听器中处理角标更新:

  1. 修正Service Worker中Badging API的调用方式(SW环境需用self.registration.setAppBadge而非navigator.setAppBadge)
  2. 监听推送事件,收到推送时直接更新角标(浏览器会自动唤醒SW执行代码,即使应用被杀)
  3. 统一角标更新逻辑,同时兼容前台页面触发的场景

修改后的代码

fb-sw.js(Service Worker)

// 处理前台页面发来的角标更新消息
self.addEventListener("message", (event) => {
  if (event.data && event.data.action === "badgeCount") {
    updateBadge(event.data.count);
  }
});

// 处理推送通知事件(后台/被杀状态下触发)
self.addEventListener("push", (event) => {
  const payload = event.data?.json() || {};
  // 从推送 payload 中获取未读计数,或自行维护(如从IndexedDB读取累计值)
  const unreadCount = payload.unreadCount || 1;

  // 显示推送通知(iOS必须调用此方法才会唤醒SW处理角标)
  const notificationOptions = {
    body: payload.body || "您有新通知",
    icon: "/icons/icon-192x192.png" // 替换为你的图标路径
  };

  // 并行执行通知显示和角标更新
  event.waitUntil(
    Promise.all([
      self.registration.showNotification(payload.title || "新通知", notificationOptions),
      updateBadge(unreadCount)
    ])
  );
});

// 统一角标更新工具函数
function updateBadge(count) {
  if ("setAppBadge" in self.registration) {
    count > 0 
      ? self.registration.setAppBadge(count) 
      : self.registration.clearAppBadge();
  } else {
    console.log("Badging API 不受当前浏览器支持");
  }
}

messaging.ts(前端页面)

return new Promise((resolve, reject) => {
  if ("setAppBadge" in navigator) {
    // 前台直接更新角标,无需通过SW转发
    navigator.setAppBadge(unreadCount);
    // 可选:同步角标计数到SW(用于后台累计)
    navigator.serviceWorker.ready
      .then(registration => {
        registration.active?.postMessage({
          action: "badgeCount",
          count: unreadCount
        });
        resolve(unreadCount);
      })
      .catch(err => {
        console.error("同步角标到SW失败:", err);
        reject(err);
      });
  } else if ("serviceWorker" in navigator) {
    // 兼容不支持页面Badging API的浏览器,通过SW更新
    navigator.serviceWorker.ready
      .then(registration => {
        registration.active?.postMessage({
          action: "badgeCount",
          count: unreadCount
        });
        resolve(unreadCount);
      })
      .catch(err => {
        console.error("Service Worker 操作失败:", err);
        reject(err);
      });
  } else {
    reject(new Error("当前浏览器不支持Service Worker"));
  }
});

关键注意事项

  • Service Worker唤醒:推送事件触发时,浏览器会临时唤醒SW执行代码,无需应用处于运行状态,这是后台/被杀状态更新角标的核心。
  • iOS特殊要求:
    • PWA必须添加到主屏幕
    • 用户已授权推送通知权限
    • SW的push事件必须调用showNotification,否则iOS不会唤醒SW处理后续逻辑
    • Badging API需iOS 16.4及以上版本支持
  • 计数维护:若需累计未读数量,建议将计数存储在IndexedDB中,每次推送时读取、更新并同步到角标,前台页面加载时也从IndexedDB读取最新计数。

内容的提问来源于stack exchange,提问作者Nouman Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 13:54:55