如何在Angular PWA中拦截应用程序安装提示?

6

我使用Angular的指南创建了一个PWA。我遇到了拦截应用程序安装横幅的问题。我正在使用以下代码将其延迟到稍后:

let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the prompt
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;
  console.log("Intercepting the app install banner prompt");

  setTimeout(function() {
    deferredPrompt.prompt();
  }, 20000);

  // Wait for the user to respond to the prompt
  deferredPrompt.userChoice
  .then((choiceResult) => {
    if (choiceResult.outcome === 'accepted') {
      console.log('User accepted the A2HS prompt');
    } else {
      console.log('User dismissed the A2HS prompt');
    }
    deferredPrompt = null;
  });
});

我的清单文件:
{
  "name": "TreadWill",
  "short_name": "TreadWill",
  "theme_color": "#2a3b3d",
  "background_color": "#2a3b3d",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

当我在本地主机上尝试运行此代码时,控制台日志中包含的消息得以记录,但是20秒后,我收到了一个错误:

Uncaught (in promise) DOMException

在这行代码中:
deferredPrompt.prompt();

当我在移动设备上托管代码并尝试运行时,应用安装横幅会立即显示,而不是在20秒后显示。
我已经尝试将此代码放入index.html文件本身中,放入单独的js文件并在index.html文件中调用。创建一个服务并在.ts文件中包含几乎相似的代码。但是没有任何作用。虽然出于绝望之下,我正在尝试使用js解决方案,但我更喜欢Angular解决方案。理想情况下,我想捕获并存储“beforeinstallprompt”事件到全局变量,并在不同的点提示该事件。
如何解决这个问题?

这是Chrome吗?目前,在Chrome中有一个临时解决方案,即使您做了所有正确的事情,安装横幅也会显示。最终(我相信)计划是让您控制安装。但现在还不行。 - Mathias
1
@Mathias 是的,它是Chrome浏览器。谢谢你让我知道。但是从这个官方指南https://developers.google.com/web/fundamentals/app-install-banners/ 我得到的印象是我应该能够将其推迟到以后的时间点。 - Outsider
2个回答

5
您可能已经做得很好了,但根据这篇文章的说法:
“当网站符合添加到主屏幕的条件时,无论您是否在beforeinstallprompt事件上使用preventDefault(),迷你信息栏都会出现。”
因此,对于我来说,它也会立即显示。
Pete LePage(@petele)是关注A2HS更新的好人。
这是我创建的Add To Home Screen(A2HS)测试工具。页面底部有源代码链接,请随意使用任何有用的内容。我最近没有将其更新为最新版本的angular,但由于它是基本代码,所以应该仍然可以正常工作。
https://a2hs.glitch.me

4
Mathias的回答中提供的链接帮助我解决了问题。我只是添加了一些在回答中没有明确提到但可能对其他人有帮助的要点。
  • 应用程序安装横幅只能在某些用户活动中显示,例如按钮单击。它不能通过setTimeout来提示。
  • 目前,在Chrome和Edge浏览器中拦截beforeinstallprompt并稍后显示它是有效的,因为当用户访问网站时,Chrome和Edge会自动触发该事件。Firefox不会触发beforeinstallprompt事件,因此在Firefox上无法使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接