跳转到内容

安装 · API

getInstalledRelatedApps()

发布于

navigator.getInstalledRelatedApps() 兑现为调用方 web 应用 manifest 中 related_applications 里已安装在设备上的那部分条目,站点据此可以隐藏自己的安装按钮,或深链接到原生对应应用。Android 上的 Chrome 84 与 Samsung Internet 14 报告 Play 应用与已安装的 PWA;Windows 上的 Chrome 85、Edge 85 与 Opera 71 只报告 UWP 应用,同样的浏览器在 macOS、Linux、ChromeOS 上兑现为空数组;Firefox 与 Safari 均未实现(BCD api.Navigator.getInstalledRelatedApps)。

const apps = await navigator.getInstalledRelatedApps();

该方法带有 [SecureContext],在纯 HTTP 源上不存在;它只定义在 Navigator 上,WorkerNavigator 上没有。

无。Promise 兑现为一个 RelatedApplication 字典数组,每个已安装的匹配项一个元素,字段如下。

字段 类型 说明
platform string 商店或生态:"play"、"windows"、"webapp"、"chrome_web_store"、"chromeos_play"、"f-droid" 或 "amazon"。从 manifest 条目复制而来。
id string,可选 平台相关的标识符(Android 包名、UWP 包家族名)。
url string,可选 manifest 条目中的 url;对 "webapp" 而言是相关 PWA 的 manifest URL。
version string,可选 平台暴露的已安装版本。

匹配需要关系的两端同时成立:调用方站点的 manifest 条目,以及另一方应用指回来的声明。Android 应用通过 Digital Asset Links(资源中的 asset_statements,与站点的 /.well-known/assetlinks.json 相互验证)声明;UWP 应用通过 URI handler 声明;相关 PWA 则通过自己的 related_applications 条目声明,若它在调用方 scope 之外,则通过 assetlinks.json 声明。

  • InvalidStateError:从非顶层浏览上下文的文档(例如 <iframe>)调用,或文档已不再 fully active(规范 “getInstalledRelatedApps()” 第 1、2 步)。
  • TypeError:Firefox 与 Safari 中 navigator.getInstalledRelatedApps 为 undefined,同步抛出;在不安全源上,任一浏览器亦是如此。

空数组不是错误。related_applications 缺失、列出的应用都未安装、反向引用(asset links 或 URI handler)验证失败,以及 Windows 之外的 Chromium 桌面版本,结果都是空数组。

两个示例都假定 manifest 的 related_applications 列出了 Android 应用 com.example.app 与站点自己的 PWA。

manifest 声明关系;页面在决定是否显示 web 安装入口前先检查。由于该方法只回答前 3 个条目,最重要的应用要排在前面。

{
"related_applications": [
{ "platform": "play", "id": "com.example.app",
"url": "https://play.google.com/store/apps/details?id=com.example.app" },
{ "platform": "webapp", "url": "https://example.com/manifest.json" }
],
"prefer_related_applications": false
}
async function decideInstallUi() {
const apps = await navigator.getInstalledRelatedApps();
if (apps.some((app) => app.platform === 'play')) {
installButton.hidden = true; // 原生应用已在设备上
openInAppLink.hidden = false; // 改为提供深链接
} else if (apps.some((app) => app.platform === 'webapp')) {
installButton.hidden = true; // 这个 PWA 已从另一个浏览器或配置文件安装
}
}

除非希望原生应用取代 PWA,否则让 prefer_related_applications 保持 false:它为 true 时,Chrome 的安装界面会转而提供商店页面,而不是安装 web 应用。

该方法不存在或没有结果时,页面得不到来自其他应用的已安装信号,应回退到常规安装流程,并用 display-mode 检查判断自身是否已安装。

async function relatedAppInstalled() {
if (!('getInstalledRelatedApps' in navigator)) return false; // Firefox、Safari、HTTP
try {
const apps = await navigator.getInstalledRelatedApps();
return apps.length > 0;
} catch (error) {
if (error.name === 'InvalidStateError') return false; // 在 iframe 内被调用
throw error;
}
}
if (!(await relatedAppInstalled())) {
showInstallAffordance(); // beforeinstallprompt 流程,或 iOS 上的分享菜单指引
}

false 分支是正确的降级行为:无法回答这个问题的浏览器应当表现得像没有相关应用一样,最坏的结果不过是向已经装了原生应用的用户多显示一个安装按钮。

规范

规范状态
无。