通过应用商店分发 PWA
发布于
完成本指南后,同一个站点会以 Trusted Web Activity(TWA)上架 Google Play,以打包 PWA 上架微软商店,两者都由线上 manifest 生成而不是重写,而且网页版不再向已经装了商店版本的用户推销安装。TWA 在用户的浏览器中全屏渲染你的来源,所以 Web 体验就是产品本身;商店包只是一个外壳加一条经过验证的站点链接。
你需要一个部署在自有域名上的可安装 PWA、运行 Bubblewrap CLI 所需的 Node.js 14.15.0 及以上(缺少 JDK 17 与 Android 命令行工具时首次运行会自动下载)、一个 Google Play 开发者账号,以及一个已加入 Windows Developer Program 的个人 Microsoft 账号。
用 Bubblewrap 生成 Android 项目
Section titled “用 Bubblewrap 生成 Android 项目”Trusted Web Activity 在 Android 版 Chrome 72 及以上可用;Chrome 不支持 TWA 时会回退为带工具栏的 Custom Tab。Bubblewrap 读取 manifest,请你逐项确认要复制进 Android 项目的取值,然后构建出已签名的 APK:
-
安装 CLI(不要用
sudo),并基于 manifest URL 初始化。Terminal window npm i -g @bubblewrap/clibubblewrap init --manifest=https://notes.example/manifest.webmanifestinit会在交互过程中创建签名密钥;保管好 keystore 及其密码,它之后会成为上传密钥。 -
构建并安装到已连接的设备上。
Terminal window bubblewrap buildbubblewrap install # 或:adb install app-release-signed.apk构建产物是
app-release-signed.apk。首次启动时站点会以带地址栏的 Custom Tab 打开;在 Digital Asset Links 验证通过之前这是预期行为。 -
确认是哪个浏览器在提供该 activity。
Terminal window adb logcat -v brief | grep -e TWAProviderPicker
构建失败时运行 bubblewrap doctor:它会检查 ~/.bubblewrap/config.json 中记录的 JDK 与 Android SDK 是否存在且版本正确。
发布 Digital Asset Links 声明
Section titled “发布 Digital Asset Links 声明”只有站点为应用作保,地址栏才会消失。把下面的文件放在 https://notes.example/.well-known/assetlinks.json;Android 的 App Links 文档要求 Content-Type: application/json、HTTPS,且不能有 301 或 302 重定向:
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "example.notes.twa", "sha256_cert_fingerprints": [ "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99" ] }}]指纹必须是给用户实际收到的 APK 签名的那把密钥的证书。Google Play 要求 AAB 上传使用 Play App Signing,即 Google 用一把不同于 Bubblewrap 上传密钥的「应用签名密钥」重新签名;Android 文档指出在这种情况下,用本地 keystore 跑 keytool 得到的指纹 “will usually not match the one on users’ devices”。到 Play Console 的 Release > Setup > App integrity 复制 “App signing key certificate” 的 SHA-256,并把上传密钥与应用签名密钥两枚指纹都列进去,让测试安装与 Play 安装都能通过验证。指纹不匹配或缺失会悄悄把 TWA 降级为顶部带浏览器界面的 Custom Tab。
用 PWA Builder 打包微软商店版本
Section titled “用 PWA Builder 打包微软商店版本”微软的文档写明不需要改代码:在 Partner Center 预留名称、用 PWA Builder 打包、提交。在 Partner Center 选择 Apps and games > New product > MSIX or PWA app,输入名称后选 Reserve product name,再打开 Product management > Product Identity,复制 Package ID、Publisher ID 与 Publisher display name。到 pwabuilder.com 在 Ship your PWA to app stores 下输入站点 URL,点 Start,先处理 Action Items 列出的问题,然后 Package For Stores > Windows > Generate Package,粘贴那三个值,点 Download Package。zip 里有一个 .msixbundle 和一个 .classic.appxbundle;在 Start your submission 的 Packages 步骤把两者都传上去。微软表示审核通常在 24 到 48 小时内完成。前端与 Service Worker 的改动无需重新提交即可到达商店用户;manifest 的改动(图标、名称、file_handlers、share_target)则需要新包,因为 manifest 会被复制进包内。
商店应用已存在时隐藏安装横幅
Section titled “商店应用已存在时隐藏安装横幅”navigator.getInstalledRelatedApps() 解析为用户已安装的相关应用,也是 MDN 点名用于移除「安装我们的 App」横幅的 API。它要求顶层安全上下文(在 <iframe> 中调用会抛出 InvalidStateError),且不是 Baseline,所以方法缺失时默认显示横幅:
async function shouldShowInstallBanner() { if (!('getInstalledRelatedApps' in navigator)) return true; const related = await navigator.getInstalledRelatedApps(); return related.length === 0;}该调用只能找到在 manifest 的 related_applications 中声明、且对方也反向指回的应用:Android 应用通过上面的 Digital Asset Links 文件,Windows 应用通过 URI handlers,PWA 通过一条指向自身的 related_applications 条目。
{ "related_applications": [ { "platform": "play", "id": "example.notes.twa", "url": "https://play.google.com/store/apps/details?id=example.notes.twa" }, { "platform": "windows", "id": "12345Publisher.FieldNotes_abcdef123456" } ]}prefer_related_applications 保持缺省或 false;在 Android 上设为 true 会把用户送去 Google Play 而不是安装 Web 应用。
- Trusted Web Activity
related_applicationsgetInstalledRelatedApps()- 商店政策
- Trusted Web Activities quick start guide(developer.chrome.com)
- Publish a PWA to the Microsoft Store(learn.microsoft.com)
← 返回指南总览。