Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> iOS/Android 浏覽器(h5)及微信中喚起本地APP

iOS/Android 浏覽器(h5)及微信中喚起本地APP

編輯:關於Android編程

在移動互聯網,鏈接是比較重要的傳播媒質,但很多時候我們又希望用戶能夠回到APP中,這就要求APP可以通過浏覽器或在微信中被方便地喚起。

這是一個既直觀又很好的用戶體驗,但在實現過程中會遇到各種問題:

如何解決未安裝APP時的做好引導頁 如何在微信中喚醒APP 在iOS9中如何處理universal link被用戶誤關的情況 如何解決Android各種機型、各種第三方浏覽器導致的兼容問題等 在APP未安裝情況下,引導用戶下載後打開APP後,如何進入之前喚起時指定的頁面或內容,即如何實現場景還原 在微信中喚醒APP時,如何進入指定的頁面或內容

下面是我一些個人的經驗分享。

浏覽器中打開

iOS/Android APP配置

這塊內容其實比較簡單,在網上都有很多資料可供查閱,就不再贅述。

原理說明

首先需要說明,不管iOS還是Android,浏覽器都不可能預知本地是否安裝了某個APP的。或者更嚴謹地說,我們不能通過浏覽器來預知本地是否安裝。因為就算浏覽器可以讀取本地應用的安裝列表,但是目前也沒任何一家浏覽器提供查詢的API,所以這條路是走不通的。

本質上浏覽器是通過URL scheme打開APP,一個APP可以設置一個或多個打開自己的URL scheme。比如,Twitter就注冊自己能被「twitter://」打開。

其實,如果是做APP間相互跳轉是比較簡單的。iOS就可以使用 UIApplication 的 canOpenUrl 方法來檢測URL scheme 是否能打開對應的APP。比如,如果「twitter://」檢測能被打開,也就說明本地安裝了 Twitter 。再用 UIApplication 的 openURL 方法,就能打開Twitter了。Android 中的做法類似。

實現方案

因為iOS9和之前的iOS系統有區別,所以這裡我們也要區別對待。

iOS7/iOS8

iOS中默認通過Safari打開URL scheme,方法一般如下兩種:

直跳方式:點擊鏈接、修改 window.location 等。 iframe 方式:在 body 上添加 iframe,設置src屬性為跳轉的URL scheme。

第一種情況:

window.location.href = http://blog.csdn.net/dreamstarting/article/details/schemeUrl;

但在第一種情況,如果APP喚醒失敗,或者APP未安裝的話,很多時候都會跳到錯誤頁,這很影響用戶體驗,而我們的要求可能是跳轉到其他頁面或者下載APP。

後一種方法不會引起頁面可見的變化(例如頁面內容變成一個新頁面),不會導致浏覽器歷史記錄的變化,

過程是這樣:點擊 a 標簽時,首先會嘗試打開URL scheme,如果成功,就喚起APP;如果失敗,則跳轉到 href 屬性,即下載頁。

Android

但這個方案在很多安卓機型上有問題,為保證可用,改用第一種方案:

$('a').click(function() {
    location.href = '自定義 URL scheme';
    t = Date.now();
    setTimeout(function(){
        if (Date.now() - t < 1200) {
            location.href = 'Android 下載地址';
        }
    }, 1000);
    return false;
}

理想過程是這樣:浏覽器嘗試打開 URL scheme,在1秒計時後,檢查當前時間,如果實際時間已過 1200 毫秒,說明喚起APP 成功(喚起 APP 會讓浏覽器的定時器變慢);如果沒超過 1200 毫秒,很可能是沒有安裝應用,就跳到下載地址。

或者換種方式:

var ifr = document.createElement('iframe');
ifr.src = 'com.baidu.tieba://';
ifr.style.display = 'none';
document.body.appendChild(ifr);
var openTime = +new Date();
window.setTimeout(function(){
    document.body.removeChild(ifr);
    if( (+new Date()) - openTime > 2500 ){
        window.location = 'http://exam.com/xxxx.apk';
    }
},2000)

但原理都是一樣,利用setTimeout。但這其實不穩定,因為Android是基於Linux的分時多任務的,setTimeout的基准偏差可能會沒那麼大。

但如果設置比較小的運行間隔(<30ms),在浏覽器或者webview中,應用切換到後台,setInterval會被很明顯的延遲執行,比如設置一個運行間隔20ms,總計運行100次的定時器,如果頁面一直處於前台,則100次跑完,總耗時與 100x20=2000ms不會有太大差異,但頁面在後台運行時,此時間會明顯超過2000ms。可以利用這一點來實現是否成功打開APP檢測及回調。

function openApp(openUrl, appUrl, action, callback) {
    //檢查app是否打開
    function checkOpen(cb){
        var _clickTime = +(new Date());
        function check(elsTime) {
            if ( elsTime > 3000 || document.hidden || document.webkitHidden) {
                cb(1);
            } else {
                cb(0);
            }
        }
        //啟動間隔20ms運行的定時器,並檢測累計消耗時間是否超過3000ms,超過則結束
        var _count = 0, intHandle;
        intHandle = setInterval(function(){
            _count++;        
            var elsTime = +(new Date()) - _clickTime;
            if (_count>=100 || elsTime > 3000 ) {
                clearInterval(intHandle);
                check(elsTime);
            }
        }, 20);
    }

    //在iframe 中打開APP
    var ifr = document.createElement('iframe');
    ifr.src = openUrl;
    ifr.style.display = 'none';
    if (callback) {
        checkOpen(function(opened){
            callback && callback(opened);
        });
    }

    document.body.appendChild(ifr);      
    setTimeout(function() {
        document.body.removeChild(ifr);
    }, 2000);  
}

另外,可以通過 document.hidden 或 document.[webkit|moz|ms]Hidden 來判斷頁面是否被置入後台(即應用被喚起),或visibilitychange事件,但對於Android 4.4版本一下則不支持。

iOS9

在 iOS 9 上,iframe 方案變得不可用。
按不能使用之前Android的代碼,因為在打開自定義 URL scheme 時,會彈出對話框,詢問是否用 xx 應用來打開。往往用戶還沒來得及點擊打開,定時器又觸發了,導致跳到 App Store。

可以在嘗試打開URL scheme 後,再加一個頁面跳轉,這樣對話框會被覆蓋,再刷新頁面,就能無需確認喚起APP:

$('a').click(function() {
    location.href = '自定義 URL scheme';
    location.href = '下載頁';
    location.reload();
}

這裡,下載頁延時 2 秒跳轉到 App Store。

APP已安裝這是沒問題的,但如果APP未安裝,跳 App Store 的請求會失敗。
這時可以使用兩個定時器:

$('a').click(function() {
    location.href = '自定義 URL scheme';
    setTimeout(function() {
        location.href = '下載頁';
    }, 250);
    setTimeout(function() {
        location.reload();
    }, 1000);
}

不過在iOS9中其實是支持universal link的,就是一個http域名形式,在微信中都可以喚起APP。如果未安裝的話,可以直接引導用戶去APP store下載。

沒有完美的解決方案

主要是在安卓上,總歸會有各種兼容問題,知乎的解決辦法是,提供兩個按鈕,一個下載,一個打開APP,讓用戶自己選。

微信中打開

因為微信將喚起本地APP的接口給禁了,所以微信中是不能直接喚起APP的,一般做法是提示用戶在浏覽器中打開,之後的流程還是我們上面講的內容。

但是,在iOS9中,這個限制是可以突破的,也就是說可以直接喚起APP。方法就是使用我們上文提到的universal link。

在Android和iOS8及其以下系統中,我們可以利用騰訊的親兒子:應用寶。簡單講,就是把你的喚起地址配置成你APP的應用寶地址,微信中跳轉到這個地址後,如果用戶已經安裝了APP,則可直接喚起,如果沒有安裝,則可直接點擊下載,如下圖示:

這裡寫圖片描述vce1xMG0vdOjqLHIt73LtbXjvLi31s/to6zItLK70KHQxLXju/fByyZyZHF1bzttbGlua3MuY2MmcmRxdW87o6mjrLW81sLM+LW9zeKyv+SvwMDG99bQo6zI58/CzbzL+cq+o7o8L2NvZGU+PC9jb2RlPjwvY29kZT48L2NvZGU+PC9wPg0KPHA+PGNvZGU+PGNvZGU+PGNvZGU+PGNvZGU+PGltZyBhbHQ9"這裡寫圖片描述" src="/uploadfile/Collfiles/20160801/20160801093839975.jpg" title="\" />

這時候再在微信中就打不開APP了,因為universal link已被關閉,這是iOS9的機制,沒法改變,這時候用戶再在微信中打開,就得需要一個中間頁來引導用戶在外部浏覽器中打開APP,如下圖所示:

這裡寫圖片描述

另外,在微信中喚醒APP默認只能到達首頁,即不能到達指定頁面或內容,如果想要做,則需要額外的處理。

拿來主義

從以上內容可以總結出:要做一個兼容性很好的方案,就需要考慮各種情況,在不同的情況適配不同的方案,比方說用戶是在手機浏覽器打開還是微信中打開,或者是在pc中打開,universal link是否被關閉等,這就使代碼實現變得復雜,且容易出錯,且還有安卓平台機型眾多、浏覽器眾多等導致的兼容問題。

如果覺得實現難度或者成本太高,你可以考慮使用魔窗的mLink。只要你加了魔窗的sdk,就可以通過類似“https://s.mlinks.cc/AA01”的鏈接,在任何環境下打開你的APP(如果在pc機上打開,浏覽器中將會出現http://blog.csdn.net/dreamstarting/article/details/APP下載地址的二維碼),上面提到的問題都不復存在,並且魔窗已經兼容超過600台以上安卓機型的第三方主流浏覽器。而且關鍵的是,不管是在手機浏覽器中,還是在微信中打開,你可以指定喚起APP後直達APP中的某個頁面或內容(某個促銷商品等),就算用戶沒安裝APP,點擊下載安裝之後,再打開,還是跳轉到指定的頁面,這就是場景還原,或者叫做Deffered Deep Linking。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved