跳转到内容

平台 · 平台

Chrome 与 Android 上的 PWA

发布于 更新于

在搭载 Google Mobile Services(GMS)的 Android 设备上,从 Chrome 安装 PWA 会生成一个 WebAPK:Chrome 向 Google 服务器请求并安装的一个小型 APK,使应用获得启动器入口、Android 应用设置中的条目,以及覆盖其 scope 的 intent filter。没有 GMS 时,Chrome 只会添加一个带浏览器角标的主屏幕快捷方式;要上架 Google Play,则需把同一个 Web 应用封装为 Trusted Web Activity(TWA)。

安装形态取决于浏览器,而不是站点。在 Android 上,只有 GMS 设备上的 Chrome 与三星设备上的 Samsung Internet 会把 PWA 安装为 WebAPK;Firefox、Edge、Opera 以及无 GMS 设备上的 Chrome 添加的是在浏览器中打开站点的快捷方式(Making PWAs installable,MDN)。Android 版 Chrome 能运行的每个 Android 版本都支持安装,最早到 Jelly Bean。

  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Android)支持57中来源12
  1. 安装时通过 Google 的铸造服务器生成 WebAPK。
  2. 没有跨浏览器兼容性数据集(BCD / caniuse)收录 WebAPK;版本号依据 Chrome Platform Status 核对。

源数据: /compatibility/webapk.json · 全球使用占比: 64 % (StatCounter 2026-05)

来源: 规范 · 最近核验 2026-07-16 · 置信度: 中 (由来源计算)

Trusted Web Activity 是另一套机制,有自己的数据集:

  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Android)支持72中来源123
  1. 依据 Chrome 文档,Trusted Web Activity 自 Android 版 Chrome 72 起可用。
  2. 没有跨浏览器兼容性数据集(BCD / caniuse)收录 TWA;版本号依据 Chrome 自己的文档核对。
  3. 同一份文档提到其他浏览器可能实现相同协议,但没有记录任何其他浏览器对 TWA 的支持。

源数据: /compatibility/twa.json · 全球使用占比: 64 % (StatCounter 2026-05)

来源: 规范 · 最近核验 2026-09-09 · 置信度: 中 (由来源计算)

Chromium 系浏览器(Chrome、Samsung Internet、Edge)只在 manifest 具备以下成员时才主动推广安装:name 或 short_name;包含 192px 与 512px 两项的 icons;start_url;display 或 display_override;prefer_related_applications 为 false 或不存在。页面必须通过 https 提供,开发阶段可用 localhost 或 127.0.0.1;file:// 虽是安全上下文,但不算数。Service Worker 不是可安装性的必要条件。Android 版 Chrome、桌面版 Chrome、桌面版 Edge 与桌面版 Safari 还允许用户安装完全没有 manifest 的站点;manifest 的作用是让浏览器主动推广安装,并决定安装结果的形态。

Android 版 Chrome 面向用户的路径(英文界面)是三点 More 菜单,然后 Install and create shortcut,再 Install(Chrome 帮助)。页面也可以在 beforeinstallprompt 处理函数中自行打开同一个对话框,代码见「示例」。

Chrome 根据 manifest 及其他元数据构建 WebAPK(WebAPKs on Android,web.dev)。安装之后:

  • 应用在用户当初安装它的那个 Chrome 中打开,而不是 WebView。
  • 它为 scope 内的每个 URL 注册 intent filter。设置 "scope": "/app/" 后,点击指向 /app/read/book 的链接会打开应用,/help/ 则在浏览器标签页中打开。
  • 权限不会在安装时授予。Android 会在安装时授予原生应用通知权限,但 WebAPK 必须在运行时通过 Chrome 自己的提示与设置申请。
  • 存储就是浏览器 profile 的存储。Cookie、IndexedDB、Cache Storage 与 Service Worker 注册都与 Chrome 共享;清除 Chrome 的站点数据也会清掉已安装应用的数据。
  • Chrome 71 及之后生成的 WebAPK 在 manifest 提供 512px 图标时,会在启动画面显示更大的图标。
  • 生成的 APK 不被 Google Play 接受。要上架 Play 得用 TWA。

Android 版 Chrome 在启动时,如果距上次检查超过 24 小时,会安排一次 manifest 拉取;拉取失败后间隔可能延长到 30 天(How Chrome handles updates to the web app manifest,web.dev)。name、short_name、icons、background_color、display、orientation、scope、shortcuts、start_url、theme_color 或 web_share_target 的变化会排队生成新的 WebAPK,Chrome 会等到所有应用窗口关闭、设备接通电源并连上 Wi-Fi 后才去请求。重命名或移动 manifest 文件可能让更新彻底停止;在 manifest 里存放用户专属值则会毫无收益地反复重建 APK。

面向 Google Play 的 Trusted Web Activity

Section titled “面向 Google Play 的 Trusted Web Activity”

TWA 通过基于 Custom Tabs 的协议,从你发布的 Android 应用中打开你的源,Chrome 72 及之后可用(Trusted Web Activities,developer.chrome.com)。应用与站点必须通过 Digital Asset Links 建立关联;关联成立时,内容在用户的浏览器中全屏渲染,没有浏览器 UI。宿主应用无法直接访问 Cookie 或 localStorage,状态只能通过 URL(查询参数与 intent URI)传递。在低于 72 的 Chrome 上,同一个应用会回退为带普通工具栏的 Custom Tab。Bubblewrap 是生成 Android 工程的 Node.js CLI;打包步骤见 Trusted Web Activity(TWA):PWA 进入 Play 商店。

两个示例在浏览器标签页、WebAPK 与桌面应用窗口中都能原样运行,由特性检测决定用户看到什么。

一旦 Chrome 判定页面可安装,beforeinstallprompt 就会在 window 上触发,通常在页面加载期间,但没有保证的时机。按钮要一直隐藏到事件到来,因为该事件只有 Chromium 系浏览器实现:

  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Android)支持68中来源—
Chrome (Desktop)支持73中来源—
Edge (Desktop)支持79中来源—
Safari (iOS)不支持—中来源1
Safari (macOS)不支持—中来源2
Firefox (Desktop)不支持—中来源3
Samsung Internet支持9.0中来源—
  1. 没有 beforeinstallprompt;需用户通过分享面板 → 添加到主屏幕手动安装。
  2. 通过「文件 → 添加到程序坞」菜单安装,而不是网页事件。
  3. 没有基于 manifest 的桌面安装路径。

源数据: /compatibility/install-prompt.json · 全球使用占比: 72 % (StatCounter 2026-05)

来源: 规范 · MDN · 最近核验 2026-06-24 · 置信度: 中 (由来源计算)

<button id="install" hidden>安装</button>
let installPrompt = null;
const installButton = document.querySelector('#install');
window.addEventListener('beforeinstallprompt', (event) => {
event.preventDefault(); // 压制 Chrome 自带的安装 UI
installPrompt = event; // 保存事件供点击处理函数使用
installButton.removeAttribute('hidden');
});
installButton.addEventListener('click', async () => {
if (!installPrompt) return;
const consumedPrompt = installPrompt;
installButton.disabled = true; // 对话框打开期间禁止再次点击
try {
const result = await consumedPrompt.prompt();
console.log(`安装提示结果:${result.outcome}`); // "accepted" 或 "dismissed"
} finally {
installPrompt = null; // 无论哪条退出路径,实例都已被消费
installButton.disabled = false;
installButton.setAttribute('hidden', '');
}
});

prompt() 必须在用户激活的处理函数内运行,并且对同一个 BeforeInstallPromptEvent 实例只能调用一次(BeforeInstallPromptEvent: prompt() method,MDN),所以处理函数在 finally 中退役该事件,而不是只在成功后才这么做。iOS 上不存在这个事件,按钮会一直隐藏,用户从分享菜单安装。

display-mode 报告的是浏览器实际应用的模式,当浏览器不支持所请求的值时,它会与 manifest 中的 display 不同(display-mode,MDN)。它描述的是呈现方式而非安装状态,因此只用它调整 UI,不要当成安装 API:

function applyDisplayMode(installButton) {
if (!('matchMedia' in window)) {
// matchMedia 不可用:让按钮保持隐藏,依赖浏览器菜单。
installButton.hidden = true;
return;
}
if (window.matchMedia('(display-mode: standalone)').matches) {
installButton.hidden = true; // 已经以应用窗口运行
}
}

匹配到 standalone 只说明页面不在普通标签页中,并不证明存在 WebAPK,因为桌面应用窗口与 iOS 主屏幕 Web 应用也会匹配同一个媒体查询。

WebAPK 的更新周期在设备上可以直接看到,这是区分「manifest 没更新」与「缓存问题」最快的办法。

卸载走的是 Android 而不是 Chrome:Settings > Apps > See all apps,点开该 Web 应用,再点 Uninstall(英文界面,Chrome 帮助)。开发者修改应用 name 后,Chrome 会向用户展示新名称,并提供 OK 接受或 Uninstall app 卸载;Chrome 帮助把模仿其他应用的改名视为开发者可能存在恶意的信号。

规范

规范状态
无。