知乎在手機瀏覽器打開,會有個 App 內打開的按鈕,點擊直接打開且跳轉到該詳情頁,是否是有點神奇,是如何作到的呢?html
AndroidManifest.xmljava
<activity android:name=".MainActivity"> <!-- 須要添加下面的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="myhost" android:path="/main" android:port="1024" android:scheme="myscheme" /> </intent-filter> </activity>
main 下新建 assets 文件,寫了簡單的 Html 網頁用於 WebView 展現,來進行測試。android
index.html:git
<html> <head> <meta charset="UTF-8"> </head> <body> <h1>這是一個 WebView</h1> <a href="market://details?id=com.tencent.mm">open app with market</a> <br/> <br/> <a href="myscheme://myhost:1024/main?key1=value1&key2=value2">open app with Uri Scheme</a> <br/> <br/> </body> </html>
Web View 加載:github
webView.loadUrl("file:///android_asset/index.html");
接受參數,作相應的處理。web
Intent intent = getIntent(); if (null != intent && null != intent.getData()) { // uri 就至關於 web 頁面中的連接 Uri uri = intent.getData(); Log.e(TAG, "uri=" +uri); String scheme = uri.getScheme(); String host = uri.getHost(); int port = uri.getPort(); String path = uri.getPath(); String key1 = uri.getQueryParameter("key1"); String key2 = uri.getQueryParameter("key2"); Log.e(TAG, "scheme=" + scheme + ",host=" + host + ",port=" + port + ",path=" + path + ",query=" + uri.getQuery() + ",key1=" + key1 + ",key2=" + key2); }
打印消息以下:json
uri=myscheme://myhost:1024/main?key1=value1&key2=value2 scheme=myscheme,host=myhost,port=1024,path=/main,query=key1=value1&key2=value2,key1=value1,key2=value2
myscheme://myhost:1024/main?key1=value1&key2=value2,經過一個連接,爲何能啓動相應的 APP 呢?Web 喚起 Android app 的實現及原理,一文說到關鍵代碼在 Android 6.0 的原生瀏覽器的 shouldOverrideUrlLoading 方法,核心實如今 UrlHandler 這個類中。代碼以下:segmentfault
final static String SCHEME_WTAI = "wtai://wp/"; final static String SCHEME_WTAI_MC = "wtai://wp/mc;"; boolean shouldOverrideUrlLoading(Tab tab, WebView view, String url) { if (view.isPrivateBrowsingEnabled()) { // Don't allow urls to leave the browser app when in // private browsing mode return false; } if (url.startsWith(SCHEME_WTAI)) { // wtai://wp/mc;number // number=string(phone-number) if (url.startsWith(SCHEME_WTAI_MC)) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(WebView.SCHEME_TEL + url.substring(SCHEME_WTAI_MC.length()))); mActivity.startActivity(intent); // before leaving BrowserActivity, close the empty child tab. // If a new tab is created through JavaScript open to load this // url, we would like to close it as we will load this url in a // different Activity. mController.closeEmptyTab(); return true; } //…… }
公衆號「吳小龍同窗」回覆「SchemeSample」,獲取此次練習的完整示例。瀏覽器
如圖,在 Android M 以前,若是點擊一個連接有多個 APP 符合,會彈出一個對話框,詢問用戶使用哪一個應用打開 - 包括瀏覽器應用。谷歌在Android M 上實現了一個自動認證(auto-verify)機制,讓開發者能夠避開這個彈出框,使用戶沒必要去選擇一個列表,直接跳轉到他們的 APP。服務器
Android M App Links: 實現, 缺陷以及解決辦法
我沒有驗證,由於我玩不起來,有條件更新下 Deep Links 這塊內容,能夠本身搭個本地服務器。
須要 Android 6.0(minSdkVersion 級別23)及更高版本上的才能使用。
開發者必須維護一個與app相關聯的網站,經過在如下位置託管數字資產連接 JSON 文件來聲明您的網站與您的意圖過濾器之間的關係:
https://domain.name/.well-known/assetlinks.json
Android移動開發者必須知道的Deep Linking技術
個人公衆號:吳小龍同窗,歡迎交流~