H5頁面中喚起native app


現在各類app,分享出去的H5頁面中,一般都會帶着一個立即打開的按鈕,如果本地安裝了app,那么就直接喚起本地的app,如果沒有安裝,則跳轉到下載。這是一個很正常的推廣和導流量的策略,最近產品經理就提出了這樣的一個需求,做一個像今日頭條功能一樣的帶打開app的下載條。

實現這個功能,我們需要解決兩個問題
1、js如何喚起本地app
2、js如何知道手機已經安裝了對應的應用

js如何喚起本地app

既然是通過網頁調用app,這個當然涉及到與app的通信。通過咨詢ios和android的同事,ios與android都支持一種叫做schema協議的鏈接。這種協議的類似於我們熟悉的http協議,我們只要跟app協商好協議頭,app通過攔截到這個協議頭的請求就可以知道有網頁要求調用。而對於js來說,我們這要像a標簽的href一樣來激活這個協議的鏈接就行了。

比如:

<a href="myapp://">調起app</a>


這種方式ios和android都可以共用

2、如何知道手機已經安裝的對應的應用對於這個功能的實現,首先想到的是查詢應用是否存在,但是這種方法顯而易見是行不通的,比如說你在UC瀏覽器,微信中,我們無法主動的去查詢我們系統中是否安裝了該應用。所以這個判斷是無法實現。所以我們就需要采用曲線救國的方式來實現。既然我們可以喚起app,那我們就可以忽略判斷,直接喚起app,如果用戶沒有安裝,我們做一個容錯處理。

結合這個思路,我們基本可以得到我們的實現方案

var iframe = document.createElement('iframe');
var body = document.body;
iframe.style.display = "none";
ar timer = null;

var openapp = document.getElementById('openapp');
openapp.addEventListener('click', function() {
body.appendChild(iframe);
iframe.src = "appschema://";
timer = setTimeout(function() {
wondow.location.href = "download.html"; //容錯的下載頁面
}, 500);
}, false)

寫完代碼,做了測試,發現這樣的實現有很多問題
1、微信無法調起。微信對於鏈接的跳轉限制很嚴重,很多下載外鏈都引導到瀏覽器打開
2、調起app返回瀏覽器的時候,會跳轉到下載頁面,既然用戶已經下載了app,再讓頁面跳轉到下載頁很不友好
3、ios9+的safari無法通過iframe跳轉到其他頁面

有問題就需要解決

1、對於微信或者QQ空間,在網上查找資料,如果是在應用寶上線的應用,應用寶提供了微下載來實現微信和QQ打開app,先跳轉到應用寶的的下載鏈接,然后下載寶鏈接會判斷打開對應的app,具體參考(http://wiki.open.qq.com/index.php?title=mobile/%E5%BA%94%E7%94%A8%E5%AE%9D%E5%BE%AE%E4%B8%8B%E8%BD%BD)但是應用寶的微下載有個問題,ios微信和QQ中無法打開對應的應用,只是會通過你應用寶配置的appstore下載鏈接跳轉到對應的下載頁面,再從appstore里面打開應用。所以這個問題還是不能完全解決,只能完美解決android的機器

2、針對問題2,網上有人通過監控頁面的pagehide和visibilitychange方法來實現禁止跳轉,具體的實現思路是監控頁面是否隱藏,利用延時如果頁面已經打開app,此時頁面會是隱藏狀態,觸發頁面的隱藏事件,clear延時事件,禁止跳轉,不過這個方案會出現問題,有一些瀏覽器在app打開,離開瀏覽器之后,js事件不在執行,也就是此時無法監控的頁面的隱藏,在返回頁面的時候,js繼續執行,但是事件監控的還是頁面展示的狀態,無法clear延時事件,所以該方式無法完美解決這個問題

后來找到了另外的解決方案,調起app需要喚起另外的進程,所以js的進程會掛起,導致前后有一個時間差,記錄前后的事件差對比就可以判斷是否調起了app了

iframe.src = "appschema://";
var timer = null,
t = Date.now();
timer = setTimeout(function() {
if (Date.now() - t > 1200) {
clearTimeout(timer);
return false;
}
}, 1000);

3、對於問題3,Apple為iOS 9發布了一個所謂的通用鏈接的深層鏈接特性,即Universal links。只要在app中授權好域名,在網頁中只要打開對應域名鏈接,都會檢測與域名綁定的app是否存在,如果存在,直接調起app,具體參考(http://stackoverflow.com/questions/31891777/ios-9-safari-iframe-src-with-custom-url-scheme-not-working),並且該方法不會被微信攔截,可以在微信中使用,這樣也就解決了我們在騰訊平台下ios無法通過微下載打開的問題

最后再來整理一下我們的思路
1、ios通過Universal links,針對ios9一下和以前版本沒有實現Universal links,在綁定好的域名下做一個中間頁,直接跳轉到中間頁
2、android分平台,如果是微信或者QQ(可以通過用戶代理檢測),直接通過微下載,其他瀏覽器,直接用schema協議

具體代碼實現如下

var url = {
        open: 'duchuang://',
        down: 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework'
    },
    iframe = document.createElement('iframe');
iframe.style.cssText = 'display:none;width=0;height=0';
var timer = null,
    //點擊第三方下載
    isAndroid = !!navigator.userAgent.match(/android/ig),
    isIos = !!navigator.userAgent.match(/iphone|ipod/ig),
    isIpad = !!navigator.userAgent.match(/ipad/ig),
    isWeixin = (/MicroMessenger/ig).test(navigator.userAgent),
    isQQ = (/qq/ig).test(navigator.userAgent),
    openapp = document.getElementById('cal-app');
openapp.addEventListener('click', function() {
    if (isIos) {
        window.location.href = "https://appdetail.netwin.cn/download.html"
    }

    if (isAndroid) {
        if (isWeixin || isQQ) { //andorid微信和QQ走微下載
            window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework&android_schema=' +  url;
        } else {
            body.appendChild(iframe);
            iframe.src = url.open;
            var t = Date.now();
            timer = setTimeout(function() {
                if (Date.now() - t > 1200) {
                    clearTimeout(timer);
                    return false;
                }
                if (document.webkitHidden || document.hidden) {
                    return false;
                }
                window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework';
            }, 1000);
        }
    }
}, false)


document.addEventListener("webkitvisibilitychange", function() {
    var tag = document.hidden || document.webkitHidden;
    if (tag) {
        clearTimeout(timer);
    }
});


window.addEventListener('pagehide', function() {
    clearTimeout(timer);
})

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM