check if user has already installed PWA to homescreen on Chrome?

前端 未结 5 1367
孤城傲影
孤城傲影 2020-12-24 02:04

I\'m trying to create an \"Add To Home Screen\" button on my progressive web app, as described in Chrome\'s documentation.

I\'m generally following the prescribed p

相关标签:
5条回答
  • 2020-12-24 02:10

    Perhaps, don't show the button until you intercept the automatic pop-up?

    or
    In your code, check to see if the window is standalone
    If it is, you need not show the button

    if (window.matchMedia('(display-mode: standalone)').matches) {  
        // do things here  
        // set a variable to be used when calling something  
        // e.g. call Google Analytics to track standalone use   
    }  
    

    My example tester here
    https://a2hs.glitch.me

    Source code for my tester
    https://github.com/ng-chicago/AddToHomeScreen

    0 讨论(0)
  • 2020-12-24 02:18

    I was looking for something similar and the simple solution is the scope passed in the manifest.web manifest file (manifest.json renamed to manifest.webm), we need to remove the scope from the manifest file and now if we have PWA added to our home screen and someone clicks a link outside the PWA triggers open by default.

    Website : https://ctrltab.co.in/

    manifest: https://ctrltab.co.in/manifest.webmanifest

    0 讨论(0)
  • 2020-12-24 02:29

    HTML

    <!-- start with hidden button -->
    <button id="install" style="display:none;">install</button>
    

    JAVASCRIPT

    // variable store event
    window.deferredPrompt = {};
    
    // get button with id
    const install_button = document.querySelector('#install');
    
    // if the app can be installed emit beforeinstallprompt
    window.addEventListener('beforeinstallprompt', e => {
      // this event does not fire if the application is already installed
      // then your button still hidden ;)
    
      // show button with display:block;
      install_button.style.display = 'block';
    
      // prevent default event
      e.preventDefault();
    
      // store install avaliable event
      window.deferredPrompt = e;
    
      // wait for click install button by user
      install_button.addEventListener('click', e => {
        window.deferredPrompt.prompt();
        window.deferredPrompt.userChoice.then(choiceResult => {
          if (choiceResult.outcome === 'accepted') {
            // user accept the prompt
    
            // lets hidden button
            install_button.style.display = 'none';
          } else {
            console.log('User dismissed the prompt');
          }
          window.deferredPrompt = null;
        });
      });
    });
    
    // if are standalone android OR safari
    if (window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true) {
      // hidden the button
      install_button.style.display = 'none';
    }
    
    // do action when finished install
    window.addEventListener('appinstalled', e => {
      console.log("success app install!");
    });
    
    0 讨论(0)
  • 2020-12-24 02:33

    To answer original question. With latest versions of Chrome you can use window.navigator.getInstalledRelatedApps(). It returns a promise with an array of installed apps that your web app specifies as related in the manifest.json. To enable this to work you need to add related_applications field to manifest.json

      "related_applications": [{
        "platform": "webapp",
        "url": "https://app.example.com/manifest.json"
      }]
    

    And then you can use it like:

    //check if browser version supports the api
    if ('getInstalledRelatedApps' in window.navigator) {
      const relatedApps = await navigator.getInstalledRelatedApps();
      relatedApps.forEach((app) => {
        //if your PWA exists in the array it is installed
        console.log(app.platform, app.url);
      });
    }
    

    Source: API docs

    Now you can display some elements depending if your app is installed. E.g: you can display "Open app" button and redirect user to PWA. But remember to disable it when the user is already in the app using @Mathias's answer and checking (display-mode: standalone)

    However, regarding your use case. You should display install button only when beforeinstallprompt is intercepted. Browser does not fire this event if the PWA is already installed on the device. And when prompt is fired and choiceResult.outcome === 'accepted' you hide the button again.

    0 讨论(0)
  • 2020-12-24 02:33

    I don't see how this is the correct answer, because this is basically a check if user uses the App already, but the behavior we wan't is "When the user is on the web and tries to install the app again to tell him that he already has the app in his device". Upon me this is not an answer that solves this.

    What we can do is: 1. When the user clicks install but has the application on his device In this case the beforeinstallprompt event WON'T BE fired so this event will return null. We store the result in global variable and when the result is null we show this to user that he already has the app installed. 2. When the user clicks install but doesn't have the application on his device In this case the beforeinstallprompt event WILL be fired so this event will return access to show the prompt. We can store the result in global variable and if it is not NULL (which won't be) because beforeinstallprompt will be fired if the user don't have the app on his device we show the prompt() to the user.

    I doubt if mine solution is good too but I think that the Question and the correct answer don't have nothing in common

    window.addEventListener("beforeinstallprompt", event => {
      window.deferedPrompt = event;
    });
    
    handleButtonClick = () => {
     const promptEvent = window.deferedPrompt;
     if(!promptEvent){
     // DO SOMETHING
     }
    //Show the add to home screen prompt
    promptEvent.prompt()
    
    promptEvent.userChoice.then((result: any) => {
          // Reset the deferred prompt variable, since
          // prompt() can only be called once.
          window.deferedPrompt = null;.
        });
    }
    
    
    
    <button onClick={handleButtonClick}>Install</button>
    
    0 讨论(0)
提交回复
热议问题