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

Android 13后台Chrome中Web推送通知点击无法打开URL问题

问题描述

我们的Service Worker监听notificationclick事件,在桌面、旧版Android系统及Android 13的Chrome前台状态下均正常工作,但Android 13系统中Chrome处于后台时,带有URL的推送通知按钮点击后无法打开对应标签页。Service Worker运行状态正常,统计日志可正常上报。

相关代码如下:

self.addEventListener('notificationclick', async function(event) {
const log = new Log(TAG);
  log.setLogLevel(LogLevel.DEBUG);

  log.d('On notification click: ', event.notification).writeLog();
  const data = event.notification.data;
  event.notification.close();
  event.waitUntil(clients.matchAll({
    type: 'window',
  }).then(function(clientList) {
    for (let i = 0; i < clientList.length; i++) {
      const client = clientList[i];
      if (client.url === '/' && 'focus' in client) {
        return client.focus();
      }
    }
    if (clients.openWindow) {
      if (event.action == 'action-1') {
        if (data.buttonTopics && data.buttonTopics[0]) topicsSubscribeNotification(data.appKey, data.deviceId, data.buttonTopics[0]);
        return clients.openWindow(data.actions[0]);
      } else if (event.action == 'action-2') {
        if (data.buttonTopics && data.buttonTopics[1]) topicsSubscribeNotification(data.appKey, data.deviceId, data.buttonTopics[1]);
        return clients.openWindow(data.actions[1]);
      } else {
        if (data.topics) topicsSubscribeNotification(data.appKey, data.deviceId, data.topics);
        return clients.openWindow(data.url);
      }
    }
  }));
  event.preventDefault();
  // send statistics to our api
});

我们尝试过简化URL打开逻辑,但问题在Android 13后台Chrome环境下依然存在。


解决方案

针对Android 13 Chrome后台的特殊行为,可从以下几个方向调整代码:

1. 修正客户端匹配逻辑

Android 13后台时,clients.matchAll默认可能无法获取到后台窗口,需添加includeUncontrolled: true参数;同时原代码中用相对路径'/'匹配窗口的逻辑存在误差,建议改用完整URL前缀匹配:

event.waitUntil(clients.matchAll({
  type: 'window',
  includeUncontrolled: true, // 包含未被当前Service Worker控制的后台窗口
}).then(function(clientList) {
  // 生成完整的根路径URL,避免相对路径匹配误差
  const rootUrl = new URL('/', self.location.origin).href;
  for (let i = 0; i < clientList.length; i++) {
    const client = clientList[i];
    // 匹配根路径及子路径,允许携带查询参数或哈希
    if (client.url.startsWith(rootUrl) && 'focus' in client) {
      return client.focus();
    }
  }
  // 后续openWindow逻辑
}));

2. 确保clients.openWindow的Promise被正确处理

Android 13后台环境下,需显式等待clients.openWindow的Promise完成,同时添加错误捕获排查问题:

// 重构URL处理逻辑,避免嵌套返回导致流程中断
let targetUrl;
if (event.action === 'action-1') {
  data.buttonTopics?.[0] && topicsSubscribeNotification(data.appKey, data.deviceId, data.buttonTopics[0]);
  targetUrl = data.actions[0];
} else if (event.action === 'action-2') {
  data.buttonTopics?.[1] && topicsSubscribeNotification(data.appKey, data.deviceId, data.buttonTopics[1]);
  targetUrl = data.actions[1];
} else {
  data.topics && topicsSubscribeNotification(data.appKey, data.deviceId, data.topics);
  targetUrl = data.url;
}

if (clients.openWindow && targetUrl) {
  // 显式等待窗口打开操作,并捕获错误日志
  return clients.openWindow(targetUrl).catch(err => {
    log.e('Failed to open window: ', err).writeLog();
  });
}

3. 移除不必要的event.preventDefault()

原代码中event.preventDefault()可能干扰Android 13下的通知点击默认行为,且我们已手动调用event.notification.close(),建议移除该语句。

4. 验证URL合法性

确保data.actions[0]、data.actions[1]、data.url均为完整的HTTPS URL,Android 13对非安全域名的限制更严格,避免使用相对路径。


验证步骤
  1. 在Android 13设备上将Chrome置于后台,触发推送通知并点击按钮;
  2. 查看Service Worker日志,确认targetUrl是否正确、clients.openWindow是否被调用、是否有错误信息;
  3. 测试根路径窗口的聚焦逻辑,避免因匹配失败导致重复打开窗口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:22:37