在移動端瀏覽器H5頁面中,點擊按鈕打開本地應用主要經過 scheme 協議。本文主要介紹如何在瀏覽器H5頁面中經過 scheme 協議打開本地應用。javascript
scheme 是一種頁面之間跳轉的協議,不只能夠用於app之間進行跳轉,還能夠用於 H5 頁面跳轉到app頁面。html
不管Android仍是IOS,均可以經過在H5頁面中打開 scheme 協議的地址,從而打開本地app。java
scheme 協議定義和 http 協議相似,都是標準的 URI 結構。android
[scheme:][//host:port][path][?query][#fragment]
下面看一個例子:web
wexin://tencent.com:8080/dl/news/open?data=902323¶ms=test
URI中的參數若是包含特殊字符,須要預先進行url編碼,不然的話URI可能不能打開。數組
要使得在瀏覽器或者別的應用中經過打開 scheme 協議來喚起應用,須要對該應用進行相關的配置。瀏覽器
首先須要在Android工程的 Manifest文件,給想要接收跳轉的Activity添加 intent-filter 節點的配置攔截器規則微信
<activity <!--定義響應該scheme協議的 activity 的名稱 --> android:name=".DeepLinkActivity" <!--須要添加下面的intent-filter配置--> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <!--scheme 容許在瀏覽器中打開--> <category android:name="android.intent.category.BROWSABLE"/> <!--scheme 相關信息配置--> <data android:scheme="uuopen" android:host="uusama.com"/> </intent-filter> </activity>
上面的 data 節點中能夠包含下面的信息來對相應的scheme進行過濾,通常須要配置 scheme 和 host。app
<data android:scheme="" android:host="" android:port="" android:path="" android:mimeType="" android:pathPattern="" android:pathPrefix="" android:ssp="" android:sspPattern="" android:sspPrefix=""/>
而後在相應的 activity 能夠獲取 uri 中參數。ide
public class DeepLinkActivity extends AppCompatActivity { private static final String TAG = "DeepLinkActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = getIntent(); Log.e(TAG, "scheme:" + intent.getScheme()); Uri uri = intent.getData(); Log.e(TAG, "scheme: " + uri.getScheme()); // 獲取 scheme 名稱 Log.e(TAG, "host: " + uri.getHost()); // 獲取 scheme 的host Log.e(TAG, "path: " + uri.getPath()); // 獲取 scheme 的路徑 Log.e(TAG, "queryString: "+ uri.getQuery()); // 獲取 scheme 的參數,?後面的部分 Log.e(TAG, "queryParameter: " + uri.getQueryParameter("param")); // 獲取 scheme 中的 param 參數 } }
其中的 intent 實例有下面的方法能夠獲取相應的 scheme 信息:
在瀏覽器中打開 scheme 就像打開一個不一樣的http地址同樣。能夠在一個 a 標籤中打開。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Scheme</title> </head> <body> <a href="wexin://" id="open">打開應用</a> </body> </html>
點擊上面的H5頁面中的連接將會嘗試喚醒微信,在一些瀏覽器中,可能會彈出一個提示框,詢問用戶是否容許打開應用。
若是打開的 scheme 在本地沒有對應的 app,則點擊鏈接不會反應。
固然還可使用 JavaScript 代碼打開,只須要添加相應的事件觸發和處理便可。
在JavaScript代碼中打開鏈接有如下幾種方式:
// 打開url的方式 var urlOpen = { 'iframe' : function(url) { var iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = url; document.body.appendChild(iframe); }, 'location' : function(url) { window.location = url; }, 'href' : function(url) { var a = document.createElement('a'); a.style.display = 'none'; a.href = url; document.body.appendChild(a); a.click(); }, 'script' : function(url) { var script = document.createElement('script'); script.setAttribute('type', 'test/javascript'); script.innerHTML = '(function(){' + 'var a = document.createElement("a");' + 'a.style.display = "none";' + 'a.href = "' + url.replace(/"/g, '\\"') + '";' + 'document.body.appendChild(a);' + 'a.click();' + '})()'; document.body.appendChild(script); }, 'open' : function(url) { window.open(url); } };
不少時候用戶在瀏覽器中打開 scheme 連接的時候,用戶不必定安裝了應用,這個時候打開會失效,咱們但願打開這個動做應該下載應用。這個時候須要判斷用戶是否安裝應用。
其實判斷用戶是否安裝某個應用的方法,就是直接打開這個應用的 scheme,查看是否打開成功。可是這就是問題之所在。
咱們沒法在瀏覽器中準確地知道打開 scheme 是否成功,瀏覽器或者系統沒有給我麼這樣的回調。咱們只能用迂迴的方法去判斷。
好比在JavaScript中判斷頁面是否進入後臺來判斷打開成功。有下面這些事件和屬性能夠利用:
上面這些事件或者屬性並非全部瀏覽器都支持。下面是一個給出爲 id 爲 open 的按鈕添加打開scheme或者下載事件的例子。
var downloader, scheme = 'weixin://', // 須要打開的 scheme 地址 download='index'; // 若是打開scheme失效的app下載地址 // 給 id 爲 open 的按鈕添加點擊事件處理函數 document.getElementById('open').onclick = function () { window.location.href = scheme; // 嘗試打開 scheme // 設置3秒的定時下載任務,3秒以後下載app downloader = setTimeout(function(){ window.location.href = download; }, 3000); }; document.addEventListener('visibilitychange webkitvisibilitychange', function () { // 若是頁面隱藏,推測打開scheme成功,清除下載任務 if (document.hidden || document.webkitHidden) { clearTimeout(downloader); } }); window.addEventListener('pagehide', function() { clearTimeout(downloader); }); }
對於經過判斷打開 scheme 的耗時來確實是否打開應用的作法是很容易失效的,由於沒法判斷打開成功之後,頁面的JS是否還在執行,並且打開應用的耗時也是不可控的。
總之,沒有完美的解決方案在H5頁面中判斷本地是否安裝了某個應用,不過使用監聽當前頁面是否隱藏的方法可以很大程度的做爲判斷依據。
也有的應用無論用戶是否安裝應用,用戶點擊連接的時候,同時打開 scheme 和拉起下載頁面,這種方式犧牲了很大的用戶體驗。
這種經過 scheme 打開本地應用的方式並非全部瀏覽器都支持,尤爲是在微信瀏覽器中是不支持使用 scheme 打開應用的,除非微信官方添加了白名單。QQ瀏覽器中卻是支持。
並且一些瀏覽器會詢問用戶是否打開,而另一些則直接打開應用。
通常的作法是,判斷當前瀏覽器是否爲微信,若是是微信的話,則彈出一個遮罩層,提示用戶使用其餘瀏覽器打開。
還有就是在微信瀏覽器中使用應用寶的微下載,將當前頁面重定向到應用寶的下載頁面,不過這種方式的轉化率很低。
有一個好消息是,在IOS9.0以上的系統中,可使用 universal links 打開本地應用,不過Android不支持。
另一個備選方案是,在微信瀏覽器中,使用iframe的方式打開一個包體地址(.apk結尾的url)進行下載時,會拉起一個選擇框,讓你選擇打開的應用。不過這種方式對於某些域名無效,對於一些特殊的下載文件無效,如不能下載.rar的文件。並且對於已經安裝了應用的用戶來講,用戶體驗也很差。
使用這種技術的同時,考慮到其不肯定性,應該作好備選方案。充分考慮到該頁面的用戶羣體是否主要爲新用戶,以及訪問的瀏覽器分佈,從而制定相應的對用戶來講比較友好的引導和備選方案。