Подтвердить что ты не робот

Как вернуться на рынок, когда настраиваемая схема URL-адресов Android не обрабатывается?

У нас есть приложение, которое обрабатывает настраиваемую схему URL (vstream://). Когда кто-то приходит на веб-страницу с некоторым содержимым vstream://, нам нужно перенаправить их в магазин, если у них нет нашего приложения.

В iOS мы делаем следующее:

setTimeout(function() {
  window.location =
    "itms://itunes.apple.com/us/app/kaon-v-stream/id378890806?mt=8&uo=4";
}, 25);

window.location = "vstream:view?code=...stuff...";

Если присваивание window.location не выполняется, таймаут перескакивает через App Store до появления диалогового окна. (Я нашел эту технику здесь: Возможно ли зарегистрировать URL-адрес для URL-адресов для приложений iPhone, например YouTube и Maps?.

К сожалению, этот трюк не работает в Android. Мы обнаруживаем серверную часть устройства и написали это вместо itms: line:

"market://details?id=com.kaon.android.vstream";

Проблема, в то время как iOS выдает ошибку, когда вы переходите к необработанной схеме URL, Android переходит на сгенерированную страницу. Поэтому тайм-аут никогда не будет работать.

Есть ли какой-либо способ на веб-странице, чтобы явным образом проверять, обрабатывается ли настраиваемая схема URL-адресов, или кто-то может предложить взломать этот, который будет работать на Android? (Конечно, я полагаю, мне нужен хак, который будет работать независимо от того, какой браузер он использует, а это, вероятно, высокий порядок...)

UPDATE: Нижеприведенные подходы не работают в желе Bean на Nexus 7. Новый браузер Chrome не переходит на сгенерированную страницу (поэтому iFrame не требуется), но, похоже, нет никакого способа узнать, является ли URL-адрес схема была обработана. Если бы это было так, тайм-аут все равно. Если он не был обработан, тайм-аут срабатывает. Если я использую обработчик onload и iframe, обработчик onload никогда не срабатывает (установлено ли приложение или нет). Я буду обновлять, если я когда-нибудь выясню, как узнать, была ли обработана эта схема...

Я удалил свой "Solved" в своем предыдущем решении, так как он больше не работает.

ОБНОВЛЕНИЕ 2: Теперь у меня хорошее кросс-платформенное решение, которое работает на iOS, Android 4.1 с Chrome и Android до Chrome. См. Ниже...

Обновление 3: Google снова сломал все намерения. Проверьте ОЧЕНЬ приятное решение, которое я принял amit_saxena там где-то/

4b9b3361

Ответ 1

Ниже приведен фрагмент рабочего кода для большинства браузеров для Android:

<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>

Вам нужно добавить класс source_url в тег привязки.

У меня есть блог об этом подробнее:

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

Ответ 2

ОБНОВЛЕНИЕ: Google нарушил это. Вместо этого см. Новый принятый ответ.

Ключ, оказывается, является свойством document.webkitHidden. Когда вы устанавливаете window.location в схему пользовательских URL-адресов, и она открывается, браузер продолжает работать, но это свойство переходит в false. Таким образом, вы можете проверить его, чтобы определить, была ли обработана пользовательская схема URL.

Здесь образец, который вы можете просмотреть в прямом эфире

<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>

Ответ 3

Это ответ, который спасет вас всех!

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>

Это будет ваш url schestart me, если приложение установлено или в противном случае он начнет рынок в указанном пакете

Ответ 4

@jesmith, это чистая версия, которая исправляет двойное действие на 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);
}

Ответ 5

Решено! Хитрость заключается в том, чтобы открыть мое приложение в IFRAME вместо установки местоположения:

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>');

Заметьте, что я увеличил тайм-аут до 1000, потому что Android фактически выполняет оба действия в каждом случае (не идеальный, но не ужасный), и этот большой тайм-аут необходим, чтобы убедиться, что рынок не оказался тем, что пользователь видит, когда я уже установлен.

(И да, конечно, использование document.write так прошло в прошлом веке, но я старую школу так:)

Ответ 6

По некоторым причинам окончательное решение для меня не работает на android (это только я?!!). Ключ в том, что функция iframe.onload НЕ выполняется, когда ваше приложение установлено, и оно выполняется, когда ваше приложение НЕ установлено.

Решение становится немного проще на самом деле. Вот сегмент для части "Старые Android-браузер":

    } else {

        // Older Android browser
        var iframe = document.createElement("iframe");
        iframe.style.border = "none";
        iframe.style.width = "1px";
        iframe.style.height = "1px";
        iframe.onload = function () { window.location = MARKET; };
        iframe.src = URL;
        document.body.appendChild(iframe);

    }

Ответ 7

Вставьте сервер http в свое приложение в качестве Сервиса, послушайте локальный порт (выше 1024, например: 8080), отправьте запрос из браузера в 127.0.0.1:8080. Если ваше приложение установлено (и запущено обслуживание), запустите его, если запрос не выполнен, перейдите в игру google.