如何检测Chrome移动版中的Web应用是否在独立模式下运行

55

Chrome移动版最近添加了类似于iOS的主屏幕添加功能,这很酷,但它不像iOS那样支持得好 - 它不支持 window.navigator.standalone,因此您无法检测是否作为独立应用程序运行。

参考资料说:

如何检测应用程序是否正在安装的应用程序上运行?

您不能直接。

请注意,它说“直接”。我的问题是是否我们可以通过一些巧妙的方式进行间接地检测?

9个回答

80

这个答案来得有些晚,但我还是在这里发布,只是为了帮助其他正在苦苦寻找解决方案的人。

最近Google实现了CSS条件display-mode: standalone,因此有两种可能的方法来检测应用是否以独立模式运行:

使用CSS:

@media all and (display-mode: standalone) {
    /* Here goes the CSS rules that will only apply if app is running standalone */
}

同时使用CSS和Javascript:

function isRunningStandalone() {
    return (window.matchMedia('(display-mode: standalone)').matches);
}
...
if (isRunningStandalone()) {
    /* This code will be executed if app is running standalone */
}

如果您需要更多信息,谷歌开发者拥有一个专门介绍这个主题的页面:https://developers.google.com/web/updates/2015/10/display-mode


2
Chrome 显然从 2014 年 11 月起就支持了 display-mode: standalone,虽然迟到了,但总比没有好 :) - Dan Dascalescu
奇怪的是,只有在通过主屏幕打开Web应用程序时,这对我才有效。如果用户通过Chrome中的“使用...”按钮打开页面,则似乎不将其视为独立应用程序。有任何想法为什么? - gaugau
6
可能有些人在尝试使用此方法时遇到了困难,记住 manifest.json 文件应该有一个 display: standalone 的入口(而不是 display: fullscreen)。 - dhknudsen

53

iOS和Chrome WebApp的行为不同,这就是我得出以下结论的原因:

isInWebAppiOS = (window.navigator.standalone === true);
isInWebAppChrome = (window.matchMedia('(display-mode: standalone)').matches);

与这里相同:检测iOS是否正在使用Web应用程序


15

对于IOS,我们有window.navigator.standalone属性进行检查。

但对于Android上的Chrome,它不支持此属性。唯一的方法是通过计算屏幕的宽度和高度来检查。

以下是检查的代码:

navigator.standalone = navigator.standalone || (screen.height-document.documentElement.clientHeight<40)

我从下面的链接获得了参考资料:

感谢Chrome 31,Android的主屏幕Web应用程序


如果用户以横向模式启动,则需要一些额外的代码,如下所示: if ((navigator.standalone = navigator.standalone) || (screen.height-document.documentElement.clientHeight<40 || screen.width-document.documentElement.clientHeight<40)) - Christopher Grigg
1
40像素在新设备上无法正常工作,因为底部有额外的UI栏(而不是实际在手机上)...需要再加大约80个像素,而且我不确定这个UI在不同设备上的高度是否一致。 - Dan Tello
3
现在有一种更可靠、符合标准的方法来实现这个功能:display-mode: standalone - Dan Dascalescu

5

一个古老的问题,但现在有更好的解决方案可用于Chrome Android。

最简单的方法之一(仅代表个人观点)。您可以添加Web应用程序清单,其中包含一个“start_url”键和一个值,该值将查询字符串参数添加到您通常的主页中。

例如:如果主页的URL是https://www.example.com, 则在Web应用程序清单中设置:

    "start_url": "https://www.example.com/?user_mode=app"

谷歌关于Web应用程序清单的指南:https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/

5

在iOS系统中,独立模式和网络模式的本地存储是不同的。而在Android KitKat和Chrome中,当您在网络版本的本地存储中保存值时,您可以在独立模式下检索它。

因此,当用户浏览网络版本(添加到主屏幕之前),只需将document.documentElement.clientHeight保存到本地存储中即可。然后,只需比较document.documentElement.clientHeight的当前值和本地存储值即可。如果当前值大于,它就是独立模式。

我在多个设备上都尝试过。


1
有趣的回答。看到一些示例代码会很酷。 :) - mhulse
2
现在有一种更可靠和符合标准的方法来实现这个:display-mode: standalone - Dan Dascalescu

2
对于Chrome浏览器(Android版)从39版本开始使用Web应用程序清单(json),并且如果它是单页应用程序,我使用以下“技巧”:

在manifest.json中,我放置了:"start_url":"standalone.html"

通常情况下它是index.html(在我的情况下),但是我创建了一个完全相同的克隆文件:standalone.html(或者你喜欢的其他名称)。

然后,为了检查,我使用了如下的Javascript代码:

var locurl = document.location.href;
if (locurl.indexOf("standalone.html") != -1) {
    console.log("app is running standalone");
} else {
    console.log("app is running in normal browser mode");
}

这很有效。

在Google Chrome(移动版)31-38中,使用此元标记可能也可以实现:

<meta name="application-url" content="http://my.domain.com/standalone.html">。但尚未测试。


1
我必须撤回这个。它不可靠。Firefox和Google Chrome(桌面版)似乎也遵循manifest.json中的start_url指令,并切换到standalone.html。对不起。 - Klaus
1
这个技巧实际上是由谷歌官方记录在检测是否从主屏幕启动中。你尝试过添加查询参数而不是重命名文件吗? - Dan Dascalescu

0

检测是否在MIT AI2 webview上运行:

if (typeof window.AppInventor!="undefined") { return true; }

你是不是想把“undefined”作为字符串放进去?它不应该只是undefined吗? - K-Dawg
1
直接与未定义的比较是有问题的,因为未定义可以被覆盖,typeof保证返回一个字符串。 - Nezumi
哦,哇,今天我学到了新东西!谢谢。 - K-Dawg

0

在Android上没有“正确”的方法来做到这一点,因此尚未有API支持。

  1. 在第一次登录时,将屏幕高度存储在本地存储中。 通过screenHeight,我指的是页面加载前的document.documentElement.clientHeight,因为之后文档会增长,它不是真正可用屏幕高度的准确测量。

  2. 每当用户下次登录时-检查当前屏幕高度与存储的屏幕高度-如果变得更大,则用户已经全屏。

如果您首次存储屏幕高度的值,则不会出现变小的情况。

注意 - 用户清除缓存的情况。 我们选择忽略它,因为大多数用户不会这样做或相对较少地这样做,并且它将足以(在我们看来)一段时间,直到API修复此问题(希望会有:))

选项b-检查可用屏幕高度与设备屏幕高度,几个测试设备和浏览器模式的匹配显示了一些模式(webapp中可用高度<70)-我强烈相信更广泛的比较可以获得足够90%的设备在90%的情况下。

所有这些都是一种解决方法,当然,我并不是在假装这是一种稳定的方式来实现所需的功能 - 但对我们而言,它起作用了,所以我希望这能帮助其他遇到这个错误(不能以其他方式调用缺失的关键API功能)的人。祝好运 :)enter image description here


2
现在有一种更可靠和符合标准的方法来实现这一点:display-mode: standalone,如上述@josemmo所回答的。 - Dan Dascalescu

0

你需要使用 window.navigator.standalone,这个API只在移动版IOS Safari上工作,甚至不适用于你的Macbook或iMac的Safari...


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