Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect web app running as homescreen app on Android Stock Browser

We are building a web app that has to be used as a standalone / homescreen app. In Chrome and Safari we can detect if it is viewed from the browser or from native-like browser container with either window.navigator.standalone or window.matchMedia('(display-mode: standalone)'). Neither option seems to work with the default Android stock browser/Samsung Internet. Furthermore, we are also not able to use start_url in manifest.json, because we need to pass a token to the homescreen app that is unique per user.

Is it possible to detect if the app is opened from the homescreen when it was added using the android stock browser?

Related

  • Check if web app is added to home screen on Android (works only with chrome on android)
  • Detect if page is viewed in samsung stock browser or as a standalone web app (unanswered)
  • Bug report: Does not detect the display-mode style
like image 368
Sumurai8 Avatar asked Nov 19 '18 16:11

Sumurai8


2 Answers

As far as I can tell, there is no way to directly detect if an app is running in the Samsung Browser, or as a standalone app in the Samsung Browser. The only difference I was able to find is the window.innerHeight, as this does not include the address bar. With window.screen.height one would be able to potentially calculate a ratio. Since this browser can be used across many different devices, this does not necessarily help you. window.innerHeight should be bigger for standalone apps, but you do not necessarily know how big a standalone app is compared to a browser experience.

// Imperfect solution
if ((window.innerHeight / window.screen.height) > 0.9) {
  // Some probability of this being a standalone app.
}

A different solution I found was to set the manifest file via javascript, allowing us to set the unique token in the start url for each individual user. This approach has several downsides though. Setting a manifest file through javascript is technically unsupported and when you create a manifest file this way, your app will never be installed as a web apk. Firefox does not support dynamically generated manifest files at all, while ios caches the manifest file which may cause issues on its own. The Chrome devtools will not always display what is in your manifest file either. The following is partly from this medium article.

// This approach has many caveats. Be aware of all of them before using this solution
import manifestBase from '../manifest.json';

const myToken = window.localStorage.getItem('myToken');
const manifest = { ...manifestBase };
manifest.start_url = `${window.location.origin}?standalone=true&myToken=${myToken}`;
const stringManifest = JSON.stringify(manifest);
const blob = new Blob([stringManifest], {type: 'application/json'});
const manifestURL = URL.createObjectURL(blob);
document.querySelector('meta[rel=manifest]').setAttribute('href', manifestURL);

You can get around the problem with FireFox by setting the href attribute of your manifest meta tag to a sensible default. You cannot get around the problem in ios if your unique information changes often.. or even at all. If your start url is not dynamic, do not set the manifest file through javascript at all, but instead set the start url with some information (e.g. the standalone=true query string above) that allows you to distinguish a standalone app from a browser url.


One more thing I found is that setting the browser mode to anything else, such as fullscreen does not "fix" the bug with Samsung Browser. It will never set the display mode to anything but a browser, so one is not able to detect it that way either.

like image 139
Sumurai8 Avatar answered Sep 22 '22 06:09

Sumurai8


Here is what I came up with this evening, after banging my head against all the "solutions" I'd found all over the place which just didn't work. My theory here is that the task bar on any phone is 30px or less, so subtract the inner height of the html from the height of the screen, and if left with 30px or less, create fullscreen rules, ex...

     var flScrn = (screen.height - innerHeight );
        if (flScrn < 30) {
            $('.installprompt').css("display","none");
        }
like image 33
R Astan Avatar answered Sep 20 '22 06:09

R Astan