知乎在手机浏览器打开,会有个 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技术
个人公众号:吴小龙同窗,欢迎交流~