h5喚起app


第一種方法:

<meta name="apple-itunes-app" content="app-id=1359749746">在主頁內加一個meta標簽,讓native給你他們的id放上即可,這種會在頁面的上邊出現一條提示你已經安裝了app問你是否打開

參考網址 https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html

第二種方法:

let last = Date.now();
var frame = document.createElement('iframe');
frame.src = 'xkd://xkd.yirendai.com';
frame.style.display = 'none';
document.body.appendChild(frame);
setTimeout(function() { document.body.removeChild(frame); }, 4)
// window.location.href='xkd://xkd.yirendai.com'
setTimeout(function() {
if (Date.now() - last > 1000) {
_this.$router.push({path:'/loadingPageLogin/'+_this.loginType,query:{channelNo:_this.channelId}})
}
},1200)
上面這種方式喚起如果在某一個app內打開不會報錯了(如果用location.href喚起,在app內打開時喚起的地址會報錯因為是在app內打開的,但是用iframe有些and手機可能喚起不成功)

第三種方法:

 https://github.com/AlanZhang001/H5CallUpNative

關於通過H5頁面喚Native戶端的介紹

本文檔用於介紹通過H5端喚起本地NN客戶端的研究過程!剛進新公司,導師讓研究下5頁面喚NNtive戶端的課題,后面公司客戶端產品可能會用到這方面的技術,所以研究了下,寫成文章,保密需要,去掉了和具體客戶端綁定的內容,希望對那些想了解這方面知識的人有用!

背景

  • 目前通過H5頁面喚起native App的場景十分常見,比如常見的分享功能;一方面,對於用戶而言,相同的內容在native app上比H5體驗更好,操作更加方便,另一方面,對於app運營來說,可以增加app的用戶粘性度。

  • 當前native客戶端內置webview中,比較常用的是通過schema打開登陸頁、觸發分享入口的顯示;而在外部瀏覽器或者webview中喚醒公司的客戶端目前還沒有太多嘗試,有據此展開研究的必要性,以便日后在真實的需求中使用!

喚醒native APP 的幾種方式

在Android端,常用的方式是Schame + Android Itent,在IOS端,常用的方式是Schema + Universal links(IOS9+); 使用的前提都是客戶端程序實現了schema協議。

下面對這3種方式做簡要的介紹:

Schema

在Android和IOS瀏覽器中(非微信瀏覽器),可以通過schema協議的方式喚醒本地app客戶端;schema協議在App注冊之后,與前端進行統一約定,通過H5頁面訪問某個具體的協議地址,即可打開對應的App客戶端 頁面;

訪問協議地址,目前有3種方式,以打開NN客戶端登錄頁為例:

1.通過a標簽打開,點擊標簽是啟動

<a href="ftnn:login">打開登錄頁</a>

2.通過iframe打開,設置iframe.src即會啟動

<iframe src="ftnn:login"></iframe>

3.直接通過window.location 進行跳轉

window.location.href= "ftnn:login";

Android上注冊schema協議,可以參考博文:Android手機上實現WebApp直接調起NativeApp

注:由於微信的白名單限制,無法通過schema來喚起本地app,只有白名單內的app才能通過微信瀏覽器喚醒,這個問題我目前沒有找到合適的解決辦法!

Android Intent

在Android Chrome瀏覽器中,版本號在chrome 25+的版本不在支持通過傳統schema的方法喚醒App,比如通過設置window.location = "xxxx://login"將無法喚醒本地客戶端。需要通過Android Intent 來喚醒APP; 使用方式如下:

1.構件intent字符串:

intent:
login						// 特定的schema uri,例如login表示打開NN登陸頁
#Intent; 
  package=cn.xxxx.xxxxxx;     			// NN apk 信息
  action=android.intent.action.VIEW; 		// NN apk 信息
  category=android.intent.category.DEFAULT; 	// NN apk 信息
  component=[string]; 				// NN apk 信息,可選
  scheme=xxxx; 					// 協議頭
  S.browser_fallback_url=[url]			// 可選,schema啟動客戶端失敗時的跳轉頁,一般為下載頁,需編碼
end; 

2.構造一個a標簽,將上面schame 字符串作為其href值,當點擊a標簽時,即為通過schema打開某客戶端登陸頁,如果未安裝客戶端,則會跳轉到指定頁,這里會跳轉到下載頁;

<a href="intent://loin#Intent;scheme=ftnn;package=cn.futu.trader;category=android.intent.category.DEFAULT;action=android.intent.action.VIEW;S.browser_fallback_url=http%3A%2F%2Fa.app.qq.com%2Fo%2Fsimple.jsp%3Fpkgname%3Dcn.futu.trader%26g_f%3D991653;end">打開登錄頁</a>

Universal links

Universal links為 iOS 9 上一個所謂 通用鏈接 的深層鏈接特性,一種能夠方便的通過傳統 HTTP 鏈接來啟動 APP, 使用相同的網址打開網站和 APP;通過唯一的網址, 就可以鏈接一個特定的視圖到你的 APP 里面, 不需要特別的 schema;

在IOS中,對比schema的方式,Universal links有以下優點:

  1. 通過schema啟動app時,瀏覽器會有彈出確認框提示用戶是否打開,而Universal links不會提示,體驗更好;

  2. Universal link可在再微信瀏覽器中打開外部App;

網易新聞客戶端IOS 9上目前采用這種Universal links方式

針對這部分內容可以參考博文:

由於公司IOS客戶端目前未實現這種協議,所以無法對這種喚醒方式做測試,日后明確支持此類協議,待測試功能后,再補充這部分詳細內容!

實現過程

首先,通過瀏覽器是無法判斷是否安裝了客戶端程序的,因此整體的思路就是:嘗試去通過上面的喚起方式來喚起本地客戶端,如果喚起超時,則直接跳轉到下載頁;整個實現過程圍繞這一點展開。

在不考慮IOS9 Universal links喚醒方式的條件下,可以分為這幾個步驟;

  1. 生成schema字符串

首先判斷瀏覽器UA,如果為Chrome for Android,則必須安裝 Android Intent的方式來組織schema字符串;如果為其他瀏覽器,則按照普通的schema方式來返回即可; 

注意參數中包含的url地址需要進行encodeURIComponent編碼

2 .通過iframe或者a標簽來加載schema

由於無法確定是否安裝了客戶端,因此通過window.location = schema的方式可能導致瀏覽器跳轉到錯誤頁;所以通過iframe.src或a.href載入schema是目前比較常見的方法;

相比於iframe和a,通過設置其diaplay為none來進行隱藏,這樣即便鏈接錯誤也不會對當前頁構成影響,但是對於a標簽,在未安裝客戶端的情況下,仍然會存在提示訪問不存在的情況(比如opera),所以在選取上的優先級是:iframe>a>window.location,只有在iframe.href 無法調用schema的情況下,才采用a.href的方式。

經過非全面測試:

  • Android系統上,Chrome for Android無法通過iframe.src 來調用schema,而通過a.href 的方式可以成功調用,而針對chrome內核的瀏覽器如獵豹,360,小米瀏覽器, opera對於iframe.src和a.href的方式都能支持,所以對chrome及先關的內核的瀏覽器采用a.href的方式來調用scheme;對於其他瀏覽器,如UC,firefox,mobile QQ,sogou瀏覽器則采用iframe.src的方式調用schema。對於微信瀏覽器,則直接跳轉到下載頁。其他未經測試的瀏覽器,默認采用iframe.src來調用schema;
  • IOS 9系統上,Safari瀏覽器無法通過iframe.src的方式調用schema,對於UC,Chrome,百度瀏覽器,mobileQQ只能通過a.href的方式進行調用schema;對於微信瀏覽器,默認跳轉到下載頁;

代碼如下:

3 .處理客戶端未安裝的情況

前面提到無法確定客戶端程序是否安裝,所以在通過iframe和a調用schema時,會設置一個settimeout,超時,則跳轉到下載頁;

此處的超時時間設置也十分關鍵,如果超時時間小於app啟動時間,則未待app啟動,就是執行setimeout的方法,如果超時時間較長,則當客戶端程序未安裝時,需要較長時間才能執行settimeout方法進入下載頁。

代碼中,進入到setimeout時,對跳轉過程再次進行了限定;當瀏覽器因為啟動app而切換到后台時,settimeout存在計時推遲或延遲的問題,此時,如果從app切換回瀏覽器端,則執行跳轉代碼時經歷的時間應該大於setimeout所設置的時間;反之,如果本地客戶端程序未安裝,瀏覽器則不會進入后台程序,定時器則會准時執行,故應該跳轉到下載頁!

在實際測試過程,當通過schema成功喚起客戶端,再次返回瀏覽器時,發現頁面已跳轉至下載頁面,因此對已設置的settimeout需要做一個清除處理;

當本地app被喚起,app處於設備可視窗口最上層,則瀏覽器進入后台程序頁面會隱藏掉,會觸發pagehide與visibilitychange事件,此時應該清除setimeout事件,於此同時,document.hide屬性為true,因此setimeout內也不做跳轉動作,防止頁面跳轉至下載頁面; 此時,有幾個事件比較關鍵:

pagehide: 頁面隱藏時觸發

visibilitychange: 頁面隱藏沒有在當前顯示時觸發,比如切換tab,也會觸發該事件

document.hidden 當頁面隱藏時,該值為true,顯示時為false

為了盡可能的兼容多的瀏覽器,所以講這幾個事件都進行綁定! 代碼如下。


測試結果

  1. Android平台(小米3 手機測試)

    • 經測試,可喚起chrome,Firefox,uc,360,mibrowser,sogou,liebao,mobileQQ瀏覽器;
    • 新版opera瀏覽器采用webkit內核,但是當客戶端未安裝時跳轉下載頁會會出錯,提示頁面不存在;
    • 微信不支持登陸,直接做了跳轉到下載頁處理;
    • Android上啟動相對比較慢,導致很容易啟動超時而跳轉到下載頁面;
    • 測試頁面在本機,百度瀏覽器會上報檢測url合法性,導致喚醒不成功

2 . IOS平台(ip4,ip6+,ipad mini2)

  • os7上Safari可用,其他瀏覽器為測試,條件限制;
  • Safari,UC瀏覽器,Chrome 瀏覽器能喚起nn客戶端,但是Safari會有 是否打開的提示;
  • QQ webviwe上能打開,偶爾會失敗;
  • IOS上啟動速度相對較快

相關代碼

對代碼進行簡單的封裝,代碼如下,在使用時需要針對當前的app做必要設置,采用UMD的寫法:

代碼見tool-nativeSchema.js

調用方式:

// COMMONJS 的方式引用,不能直接在瀏覽器中運行,需要打包轉換
var nativeSchema = require("tool-nativeSchema.js");

// Amd的方式
require(["tool-nativeSchema.js"],function(nativeSchema){

});

// 直接引入
<script type="text/javascript" src="xxxx/tool-nativeSchema.js"></script>
// 使用
nativeSchema.loadSchema({
    // 某個schema協議,例如login,
    schema: "",

    //schema頭協議,
    protocal:"xxx",

    //發起喚醒請求后,會等待loadWaiting時間,超時則跳轉到failUrl,默認3000ms
    loadWaiting:"3000",

    //喚起失敗時的跳轉鏈接,默認跳轉到應用商店下載頁
    failUrl:"xxx",

    // Android 客戶端信息,可以詢問 Android同事
	apkInfo:{
        PKG:"",
        CATEGORY:"",
        ACTION:""
	}
});

研究意義

便於通過相關H5頁面進入Native客戶端,提升用戶體驗,提升App用戶粘度; 對於未安裝客戶端的用戶,可引導進入下載通道,如下場景圖:

存在的問題

  1. 在沒有安裝客戶端程序的時候,opera無法跳轉到指定頁的失敗頁;
  2. 通過微信喚醒客戶端目前不可行,Android上需要微信設置白名單;IOS上,需要微信設置白名單或者通過Universal links(IOS9+)協議;
  3. 尚未對IOS9的 Universal links協議進行功能測試。
  4. 代碼中使用的各種時間如:settimeout定時時間均根據本機測試進行的調整,普遍性需要進一步驗證

最后

  1. 經過自行測試及網上查閱資料,目前尚未找到完美的解決方案;
  2. 對於文中的不足和錯誤,歡迎指出。
  3. 轉載請說明出處,以方便追本溯源修正文中錯誤

相關閱讀鏈接


免責聲明!

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



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