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

如何在Service Worker中打开mailto:与tel:链接?解决Chrome安卓端异常问题

解决Android Chrome中Service Worker推送通知的mailto/tel协议唤起问题

我之前也碰到过一模一样的问题——Windows端Chrome里点击推送通知的邮件/电话按钮能正常唤起对应系统应用,但Android端Chrome却会打开一个显示mailto:...或tel:...链接的空白黑标签页,完全不符合预期。这其实是Android Chrome在Service Worker环境下,对mailto:、tel:这类非HTTP(S)协议的处理逻辑和桌面端有差异,直接调用clients.openWindow()会被当作普通URL解析,而非唤起系统应用。

修复后的代码方案

你可以调整notificationclick事件的处理逻辑,先获取当前活跃的客户端页面(或者打开一个临时空白页),然后在客户端上下文里发起协议跳转,就能让Android Chrome正确唤起对应应用了:

self.addEventListener('notificationclick', function(event) {
  event.notification.close(); // 先关闭通知弹窗
  const { contactRequest } = JSON.parse(event.notification.data);

  // 封装协议跳转逻辑
  const handleProtocolAction = (url) => {
    return clients.matchAll({ type: 'window', includeUncontrolled: true })
      .then(clientList => {
        // 优先复用已打开的同域名页面
        for (const client of clientList) {
          if (client.url.startsWith(self.origin) && 'focus' in client) {
            return client.focus().then(() => {
              client.navigate(url); // 在已有页面上下文里触发协议跳转
            });
          }
        }
        // 没有活跃页面时,打开临时空白页再跳转
        if (clients.openWindow) {
          return clients.openWindow('/blank.html').then(newClient => {
            if (newClient) {
              newClient.navigate(url);
            }
          });
        }
      });
  };

  switch(event.action) {
    case 'call':
      event.waitUntil(handleProtocolAction('tel:' + contactRequest.phone));
      break;
    case 'mail':
      event.waitUntil(handleProtocolAction('mailto:' + contactRequest.email));
      break;
    default:
      // 处理通知默认点击行为(比如打开网站主页)
      event.waitUntil(clients.openWindow('/'));
  }
});

关键细节说明

  • 用event.waitUntil()包裹异步操作:确保Service Worker在完成协议跳转逻辑前不会被浏览器终止,保证操作能执行完成。
  • 优先复用已有客户端:通过clients.matchAll()找到当前域名下的活跃页面,在这个页面上下文里发起协议跳转,避免不必要的新标签页打开。
  • 临时空白页兜底:如果没有活跃页面,先打开一个同域名的空白页面(比如/blank.html,你需要自己创建这个空页面),再在页面内触发协议跳转——Android Chrome会识别到协议并唤起对应应用,之后空白页可以自动关闭。

你需要创建的/blank.html可以非常简单,只需要加一段自动关闭的逻辑即可:

<!DOCTYPE html>
<html>
<head>
  <script>
    // 页面加载后短暂延迟自动关闭
    window.addEventListener('load', () => {
      setTimeout(() => window.close(), 100);
    });
  </script>
</head>
<body></body>
</html>

这样修改后,Android Chrome就能和桌面端一样,点击推送通知的邮件/电话按钮直接唤起系统邮件或拨号应用,不会再出现烦人的空白黑标签页了。

内容的提问来源于stack exchange,提问作者Ivan Beldad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:27:54