How to fall back to marketplace when Android custom URL scheme not handled?

后端 未结 7 487
無奈伤痛
無奈伤痛 2020-12-07 09:47

We have an app that handles a custom URL scheme (vstream://). When someone comes to a web page that has some vstream:// content, we need to redirect them to the store if th

相关标签:
7条回答
  • 2020-12-07 09:51

    Embed a http server in your app as a Service, listen to a local port(higher than 1024, ex: 8080), send a request from Browser to 127.0.0.1:8080. If your app installed(and service running), start it, if request fail, goto google play.

    0 讨论(0)
  • 2020-12-07 09:58

    This is the answer who will save you all !

    https://developers.google.com/chrome/mobile/docs/intents

    <a href="intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end"> Take a QR code </a>
    

    It will your url schestart me if the app is installed ortherwise it will start the market at the indicated package

    0 讨论(0)
  • 2020-12-07 10:03

    Solved! The trick is to open my app in an IFRAME, instead of setting the location:

    setTimeout(function() {
      window.location =
        "market://details?id=com.kaon.android.vstream";
    }, 1000);
    
    document.write('<iframe style="border:none; width:1px; height:1px;" src="vstream:view?code='+code+'"></iframe>');
    

    Notice that I increased the timeout to 1000, because Android actually does both actions in every case (not ideal, but not awful), and this larger timeout is needed to make sure that Market doesn't end up being the thing the user sees when I'm already installed.

    (And yes, of course using document.write is so last-century, but I'm old school that way :)

    0 讨论(0)
  • 2020-12-07 10:09

    Below is a working code snippet for most of the android browsers:

    <script type="text/javascript">
        var custom = "myapp://custom_url";
        var alt = "http://mywebsite.com/alternate/content";
        var g_intent = "intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;end";
        var timer;
        var heartbeat;
        var iframe_timer;
    
        function clearTimers() {
            clearTimeout(timer);
            clearTimeout(heartbeat);
            clearTimeout(iframe_timer);
        }
    
        function intervalHeartbeat() {
            if (document.webkitHidden || document.hidden) {
                clearTimers();
            }
        }
    
        function tryIframeApproach() {
            var iframe = document.createElement("iframe");
            iframe.style.border = "none";
            iframe.style.width = "1px";
            iframe.style.height = "1px";
            iframe.onload = function () {
                document.location = alt;
            };
            iframe.src = custom;
            document.body.appendChild(iframe);
        }
    
        function tryWebkitApproach() {
            document.location = custom;
            timer = setTimeout(function () {
                document.location = alt;
            }, 2500);
        }
    
        function useIntent() {
            document.location = g_intent;
        }
    
        function launch_app_or_alt_url(el) {
            heartbeat = setInterval(intervalHeartbeat, 200);
            if (navigator.userAgent.match(/Chrome/)) {
                useIntent();
            } else if (navigator.userAgent.match(/Firefox/)) {
                tryWebkitApproach();
                iframe_timer = setTimeout(function () {
                    tryIframeApproach();
                }, 1500);
            } else {
                tryIframeApproach();
            }
        }
    
        $(".source_url").click(function (event) {
            launch_app_or_alt_url($(this));
            event.preventDefault();
        });
    </script>
    

    You need to add source_url class to the anchor tag.

    I have blogged more about it here:

    http://aawaara.com/post/88310470252/smallest-piece-of-code-thats-going-to-change-the

    0 讨论(0)
  • 2020-12-07 10:13

    @jesmith, this is a clean version that fixes double action on Android.

    if (navigator.appVersion.indexOf('iPhone') > -1) {
      setTimeout(function noapp() { window.location="http://itunes.apple.com/app/id378890806?mt=8"; }, 25);
      window.location = 'vstream:';
    }
    else if (navigator.userAgent.indexOf('Android') > -1) {
      var iframe = document.createElement('iframe');
      iframe.style.visibility = 'hidden';
      iframe.src = 'vstream:';
      iframe.onload = function noapp() { window.location="market://details?id=com.kaon.android.vstream"; };
      document.body.appendChild(iframe);
    }
    
    0 讨论(0)
  • 2020-12-07 10:14

    UPDATE: Google broke this. See the new accepted answer instead.

    The key, it turns out, is the document.webkitHidden property. When you set window.location to a custom URL scheme and it opens, the browser keeps running, but that property goes to false. So you can test it to determine whether the custom URL scheme was handled.

    Here's a sample, which you can view live

    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Starting App...</title>
    <script>
    
    var URL = "kaonkaon://product.html#malvern;6";
    var MARKET = "market://details?id=com.kaon.android.lepton.kaon3d";
    var ITUNES = "itms://itunes.apple.com/us/app/kaon-interactive-3d-product/id525051513?mt=8&uo=4";
    var QR = "http://goo.gl/gz07g"; // this should be a shortened link back to this page
    
    function onLoad() {
    
        if (navigator.userAgent.match(/Android/)) {
    
            if (navigator.userAgent.match(/Chrome/)) {
    
                // Jelly Bean with Chrome browser
                setTimeout(function() {
                    if (!document.webkitHidden)
                        window.location = MARKET;
                }, 1000);
    
                window.location = URL;
    
            } else {
    
                // Older Android browser
                var iframe = document.createElement("iframe");
                iframe.style.border = "none";
                iframe.style.width = "1px";
                iframe.style.height = "1px";
                var t = setTimeout(function() {
                    window.location = MARKET;
                }, 1000);
                iframe.onload = function () { clearTimeout(t) };
                iframe.src = URL;
                document.body.appendChild(iframe);
    
            }
    
         } else if (navigator.userAgent.match(/iPhone|iPad|iPod/)) {
    
             // IOS
             setTimeout(function() {
                 if (!document.webkitHidden)
                     window.location = ITUNES;
             }, 25);
    
             window.location = URL;
    
         } else {
    
             // Not mobile
             var img = document.createElement("img");
             img.src = "https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl="+encodeURIComponent(QR);
             document.body.appendChild(img);
         }
    }
    </script>
      </head>
      <body onload="onLoad()">
      </body>
    </html>
    
    0 讨论(0)
提交回复
热议问题