h5啟動原生APP總結

來源:互聯網
上載者:User

標籤:請求   安裝   ==   get   on()   屏蔽   功能   解決方案   網域名稱   

許久沒有寫部落格了,最近有個H5啟動APP原生頁面的需求,中間遇上一些坑,看了些網上的實現方案,特意來總結下

一、需要判斷用戶端的平台以及是否在瀏覽器中訪問

1、用戶端判斷

在啟動APP時,Android和IOS系統處理的方式是不一樣的,Android這邊由於開放,可以在瀏覽器中通過<a>標籤以及meta標籤的方式,讓瀏覽器app擷取手機開啟應用的許可權進而啟動APP。

而在IOS這邊,IOS9以後的系統,則可以在APP開發過程中加入配置和邏輯代碼編寫,系統在瀏覽器即將訪問到某個網域名稱前就把這個網域名稱對應的APP開啟,這個有點閃,封閉還是有封閉的好處。

所以首先要在用戶端判斷,是Android系統還是IOS系統,判斷代碼如下

function isInIos(){    var userAgentInfo = navigator.userAgent ,        Agents = ["iPhone" , "iPad", "iPod"];    for(var v = 0; v < Agents.length; v++) {        if (userAgentInfo.indexOf(Agents[v]) > 0) {          return true;        }    }    return false;}        

2、是否在內建瀏覽器中

無論是在哪個平台的用戶端Android/IOS,在的平台上訪問都有一個問題,那就是無法啟動用戶端,這是為了安全性考慮的限制,android這邊屏蔽schema協議,除非公司是的夥伴加入了白名單才能

使用,IOS系統可以去訪問app對應appstore的下載頁,但是經常屏蔽appstore的這個網址,進而訪問不到。比較方便的做法就是在瀏覽器中,無論是IOS還是android都去應用寶的下載(IOS 這邊最後會到

appstore中)頁面開啟。我這邊的需求是提示使用者點擊“...”用預設瀏覽器開啟。

判斷是否是在中,代碼如下:

function isInWx(){    var agent = window.navigator.userAgent.toLowerCase();    return agent.match(/MicroMessenger/i) == ‘micromessenger‘;}

 

 

二、原理

首先無論是andorid還是IOS端,在瀏覽器中通過JS都是無法判斷該手機是否裝有某APP的,即使這個瀏覽器有許可權讀取手機應用列表,也沒有一個固定的對外API讓咱們進行查詢。而H5啟動APP本質上是通過

URL scheme開啟APP,一個APP可以設定一個或多個開啟自己的URL scheme,瀏覽器去訪問某一個APP的URL scheme,然後若系統安裝有這個APP,則會請求許可權去開啟這個APP。其實也算是瀏覽器app

開啟另一個app,iOS就可以使用 UIApplication 的 canOpenUrl 方法來檢測URL scheme 是否能開啟對應的APP,而android也是類似的方式。當然如果JS跳轉URL scheme沒有反應,也意味著這個手機沒有

裝這個app。

 

三、android平台

首先編輯AndroidManifest.xml,主要是增加第二個<intent-filter>

<activity android:name=".activity.LoadingActivity"      android:label="${APP_NAME}"      android:screenOrientation="portrait"      android:theme="@style/FirstActivityTheme">      <intent-filter>          <action android:name="android.intent.action.MAIN" />      <category android:name="android.intent.category.LAUNCHER" />      </intent-filter>      <intent-filter>          <action android:name="android.intent.action.VIEW" />      <category android:name="android.intent.category.DEFAULT" />      <category android:name="android.intent.category.BROWSABLE" />      <data android:host="android"                android:scheme="wushang" />      </intent-filter></activity>

比如此處wushang就是scheme,這個最好是app的唯一識別碼,要不然在H5喚醒時,會出現一個選擇框,選擇啟動哪一個APP。而host表示啟動該頁面,其實這個更應該用com.android.sky這樣的包名來替代更好。

這樣的情況完整的URL就是wushang://android?data=sky,後面是參數傳遞。在Activity中可以用如下代碼擷取參數

public void onCreate(Bundle savedInstanceState) {                  Uri uridata = this.getIntent().getData();                  String mydata = uridata.getQueryParameter("data");            }

之後在進行字串截取還是什麼鬼的都隨意啦。

 

接下來來談談前端代碼,這裡有兩種情況

1、頁面在重新整理進入時,請求許可權喚起APP

這個比較簡單,就只用在頁面的頂部head中加入meta標籤即可

<meta http-equiv="refresh" content="0;url=wushang://android?data=sky">

這個標註當頁面重新整理即去訪問這個連結,進而啟動APP。但是存在一個問題,如果是蘋果系統的Safari瀏覽器的話,訪問有這個meta的頭,會給出錯誤提示,所以這個頭部可以在後端進行頁面渲染時通過用戶端的

總類在加上去。

2、通過點擊事件喚起APP

最簡單的辦法當然是直接使用a標籤,如下

<a href="wushang://android">open Android app</a>

但是在實際使用時,是需要對用戶端的平台類型還有是否在內建瀏覽器中進行判斷的,所以這樣的做法肯定是不行的。

接下來談談在開發過程中,遇到的一個問題,記錄下。因為這邊移動端使用的工具庫庫是zepto,採用的點擊事件是tap,但是在用tap進行處理是經常要點很多下,才能喚起APP

<script type="text/javascript">  $(‘#go‘).tap(function(){      window.location.href = "wushang://android";  });</script>

具體原因不知,可能是tap事件採用的是輕點觸碰。然後摸索了下,才用click事件,或者直接在a標籤上標註處理函數就沒有這問題

<a id="go" >    open Android app</a><a href="javascript:startApp()">   open</a><script src="../res/lib/zepto.min.js"></script><script src="../res/lib/public.js"></script><script>    $(‘#go‘).click(function () {       if(publicFun.isIos()){          alert(‘it is IOS‘)       }else{          window.location.href = "wushang://android";       }    });    function startApp(){       if(publicFun.isIos()){          alert(‘it is IOS‘)       }else{          window.location.href = "wushang://android";       }    }</script>

所以決定以後遇到這類問題,就用這兩種方式了。下面是實際的處理函數

 window.startApp = function(){     //啟動APP     if(publicFun.isInWx()){     //中        alert("請在瀏覽器中開啟");     }else{      //非中        if(publicFun.isIos()){    //IOS系統,直接去itunes中,既可以下載也可以開啟            window.location.href = "https://itunes.apple.com/cn/app/[name]/id[id]";        }else{      //android系統,通過定時器的方式,判斷是否安裝有APP            var hasApp = true , t = 1000;            setTimeout(function () {  //沒有安裝APP則跳轉至應用寶下載,延時時間設定為2秒              if(!hasApp) window.location.href = "http://a.app.qq.com/o/simple.jsp?pkgname=[name]";            } , 2000);            var t1 = Date.now();            window.location.href = "wushang://android";            setTimeout(function () {    //t的時間就是出發APP啟動的時間,若APP啟動了,再次返回頁面時t2這行代碼執行,hasApp即為true。反之若APP沒有啟動即為false              var t2 = Date.now();              hasApp = !(!t1 || t2 - t1 < t + 150);            } , t);        }     }  } 

其實有個非常簡單的辦法,就是直接跳轉應用寶。無論是在android還是IOS,以及非。應用寶的下載頁面都有下載和開啟兩個功能(如果是在IOS平台,它是通過串連app store的方式)

 

四、IOS平台

針對ios9及以上的打不開問題,實際上ios9提供了更好的解決方案————通用連結。

這是iOS9推出的一項功能,如果你的應用支援Universal Links(通用連結),那麼就能夠方便的通過傳統的HTTP連結來啟動APP(如果iOS裝置上已經安裝了你的app,不需要額外做任何判斷等),或者開啟網頁(iOS裝置上沒有安裝你的app)。或許可以更簡單點來說明,在iOS9之前,對於從各種從瀏覽器,Safari、UIWebView或者 WKWebView中喚醒APP的需求,我們通常只能使用scheme。

以上來自網上關於通用連結的介紹,對於前端簡單點講就是你訪問一個http的url,如果這個url帶有你提交給開發平台的設定檔中匹配規則的內容,ios系統會去嘗試開啟你的app,如果打不開,系統就會在瀏覽器中轉向你要訪問的連結。很好的一個屬性,因為通過這個屬性在ios9上我們能夠繞過的攔截從而開啟app。

所以上面的點擊事件,僅僅是去訪問app store,因為若app已安裝,在瀏覽器訪問時,就已經去到APP中了。

這些都是IOS配置上的東西,就不多寫了。至於傳參,以及頁面定向,其實也就是相當於在UIWebView中擷取當前串連的URL,然後進行字串拆分以及校正,即可判斷去哪個頁,以及擷取參數值。

 

h5啟動原生APP總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.