Android 从 Web 唤起 APP

前言

知乎在手机浏览器打开,会有个 App 内打开的按钮,点击直接打开且跳转到该详情页,是不是有点神奇,是如何做到的呢?

效果预览

Uri Scheme

配置 intent-filter

AndroidManifest.xml

1<activity android:name=".MainActivity"> 2 <!-- 需要添加下面的intent-filter配置 --> 3 <intent-filter> 4 <action android:name="android.intent.action.VIEW" /> 5 <category android:name="android.intent.category.DEFAULT" /> 6 <category android:name="android.intent.category.BROWSABLE" /> 7 <data 8 android:host="myhost" 9 android:path="/main" 10 android:port="1024" 11 android:scheme="myscheme" /> 12 </intent-filter> 13</activity>

测试网页

main 下新建 assets 文件,写了简单的 Html 网页用于 WebView 展示,来进行测试。

index.html:

1<html> 2<head> 3 <meta charset="UTF-8"> 4</head> 5<body> 6<h1>这是一个 WebView</h1> 7 8<a href="market://details?id=com.tencent.mm">open app with market</a> 9<br/> 10<br/> 11 12<a href="myscheme://myhost:1024/main?key1=value1&key2=value2">open app with Uri Scheme</a> 13 14<br/> 15<br/> 16 17 18</body> 19</html>

Web View 加载:

webView.loadUrl("file:///android_asset/index.html");

目标页面

接受参数,做相应的处理。

1Intent intent = getIntent(); 2if (null != intent && null != intent.getData()) { 3 // uri 就相当于 web 页面中的链接 4 Uri uri = intent.getData(); 5 Log.e(TAG, "uri=" +uri); 6 String scheme = uri.getScheme(); 7 String host = uri.getHost(); 8 int port = uri.getPort(); 9 String path = uri.getPath(); 10 String key1 = uri.getQueryParameter("key1"); 11 String key2 = uri.getQueryParameter("key2"); 12 Log.e(TAG, "scheme=" + scheme + ",host=" + host 13 + ",port=" + port + ",path=" + path 14 + ",query=" + uri.getQuery() 15 + ",key1=" + key1 + ",key2=" + key2); 16}

打印消息如下:

1uri=myscheme://myhost:1024/main?key1=value1&key2=value2 2scheme=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 这个类中。代码如下:

1final static String SCHEME_WTAI = "wtai://wp/"; 2final static String SCHEME_WTAI_MC = "wtai://wp/mc;"; 3boolean shouldOverrideUrlLoading(Tab tab, WebView view, String url) { 4 if (view.isPrivateBrowsingEnabled()) { 5 // Don't allow urls to leave the browser app when in 6 // private browsing mode 7 return false; 8 } 9 if (url.startsWith(SCHEME_WTAI)) { 10 // wtai://wp/mc;number 11 // number=string(phone-number) 12 if (url.startsWith(SCHEME_WTAI_MC)) { 13 Intent intent = new Intent(Intent.ACTION_VIEW, 14 Uri.parse(WebView.SCHEME_TEL + 15 url.substring(SCHEME_WTAI_MC.length()))); 16 mActivity.startActivity(intent); 17 // before leaving BrowserActivity, close the empty child tab. 18 // If a new tab is created through JavaScript open to load this 19 // url, we would like to close it as we will load this url in a 20 // different Activity. 21 mController.closeEmptyTab(); 22 return true; 23 } 24 //…… 25 }

源码

公众号「吴小龙同学」回复「SchemeSample」,获取这次练习的完整示例。

Deep Links

如图,在 Android M 之前,如果点击一个链接有多个 APP 符合,会弹出一个对话框,询问用户使用哪个应用打开 - 包括浏览器应用。谷歌在Android M 上实现了一个自动认证(auto-verify)机制,让开发者可以避开这个弹出框,使用户不必去选择一个列表,直接跳转到他们的 APP。

创建

Android M的App Links实现详解

Android M App Links: 实现, 缺陷以及解决办法

我没有验证,因为我玩不起来,有条件更新下 Deep Links 这块内容,可以自己搭个本地服务器。

弊端

需要 Android M

需要 Android 6.0(minSdkVersion 级别23)及更高版本上的才能使用。

.well-known/assetlinks.json

开发者必须维护一个与app相关联的网站,通过在以下位置托管数字资产链接 JSON 文件来声明您的网站与您的意图过滤器之间的关系:

https://domain.name/.well-known/assetlinks.json

参考

Android 使用Scheme实现从网页启动APP

Deep Link是什么

Android移动开发者必须知道的Deep Linking技术

Handling Android App Links

公众号

我的公众号:吴小龙同学,欢迎交流~

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )