前言



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

效果预览

Uri Scheme

配置 intent-filter

AndroidManifest.xml

<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 展示,来进行测试。

index.html:

<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 加载:

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

目标页面

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

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);
}

打印消息如下:

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 这个类中。代码如下:

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」,获取这次练习的完整示例。

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

公众号

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

Android 从 Web 唤起 APP的更多相关文章

  1. h5移动网页唤起App

    最近这个困惑了很久,不断的有一些坑,目前还有疑问关于iOS唤起无效时会出现弹框的问题,这个最后再说 1.首先可能需要判断当前浏览器的来源(目前开发的App还没有上架,所以针对腾讯出品的大家广为人知的微 ...

  2. h5页面唤起app(iOS和Android),没有安装则跳转下载页面

    浏览器和app没有通信协议,所以h5不知道用户的手机释放安装了app.因此只能是h5去尝试唤起app,若不能唤起,引导用户去下载我们的app. 微信里屏蔽了 schema 协议,如果在微信中打开h5, ...

  3. H5如何实现唤起APP

    前言 写过hybrid的同学,想必都会遇到这样的需求,如果用户安装了自己的APP,就打开APP或跳转到APP内某个页面,如果没安装则引导用户到对应页面或应用商店下载.这里就涉及到了H5与Native之 ...

  4. Android N 新特性 + APP开发注意事项

    1. 多窗口MultiWindow 多窗口MultiWindow,这是Android N里对开发者影响比较大的特性,也是大家疑问比较多的地方.站在开发者的角度其实不必太担心这个特性会导致我们需要修改很 ...

  5. WEB和APP谁是互联网未来

    据中国多家权威报告显示,作为多年专业化互联网公司炎帝网络科技综合评估预测,预计2016年全球互联网设备将达到100亿部.如果届时全球人口达到73亿,意味着平均每人将有1.4部设备.智能交通将增长50倍 ...

  6. Web/app端自动化测试对比

    Web/app端自动化测试 做了一段时间的Android自动化测试,对比个人之前做的web端自动化测试,有一些感想.(由于个人接触的时间也不是太久,很多东西理解也并不深刻,先写下菜鸟时期的感想.) 区 ...

  7. H5 唤起 APP的解决方案

    H5 页面唤起APP或跳转到下载APP的某个链接地址.总结如下: 在 IOS 中, 系统版本在 8 以下时,可以监听页面的 pagehide / visibilitychange 事件. 系统版本大于 ...

  8. 【js】手机浏览器端唤起app,没有app就去下载app 的方法

    这种功能的作用: 1.一般公司有自己的app,而app是需要不断有新用户涌入才能持续运营,达到不错的收入.就需要使用这种方式进行引入新的用户. 2.一些内容在网页端体验不好,或者一些功能需要app内才 ...

  9. IOS, Android, Java Web Rest : RSA 加密和解密问题

    IOS, Android, Java Web Rest :  RSA 加密和解密问题 一对公钥私钥可以使用 OpenSSL创建, 通常 1024位长度够了. 注意: 1. 公钥私钥是BASE64编码的 ...

随机推荐

  1. linux系统下的日志,此日志对于系统安全来说是非常重要的一 个机制!!

    var/log/messages /etc/logrotate.conf 日志切割配置文件 (参考https://my.oschina.net/u/2000675/blog/908189) dmesg ...

  2. mysql 5.7.22 解压缩安装

    1.下载地址:https://dev.mysql.com/downloads/mysql/5.7.html#downloads 直接点击下载项 下载后: 2.可以把解压的内容随便放到一个目录,我的是如 ...

  3. springcloud微服务总结二 注册中心

    一:netflix和springcloud关系 netflix公司开源了很多组件,包括服务注册与发现(Netflix Eureka).断路器(Netflix Hystrix).负载均衡(Netflix ...

  4. mysql 创建表时注意事项

    mysql  创建表时注意事项 mysql 想必大家都不会陌生吧  是我学习中第一个接触的的数据库 已学习就很快上手的   这是一个关系型数据库  不懂什么是关系型数据库 啊哈哈哈  现在知道啦  因 ...

  5. python get() 和getattr()

    get() Python 字典 get() 函数返回指定键的值,如果值不在字典中返回默认值. 语法: dict.get(key, default=None) 实例1: d={'A':1,'b':2} ...

  6. C++_类和动态内存分配2-改进后的String类

    添加前面介绍过的复制构造函数和赋值运算符,使类能够正确管理类对象使用的内存. 知道对象何时被创建和释放. =================================== 修订后的默认构造函数 ...

  7. P4449 于神之怒加强版 (莫比乌斯反演)

    [题目链接] https://www.luogu.org/problemnew/show/P4449 给定n,m,k,计算 \(\sum_{i=1}^n \sum_{j=1}^m \mathrm{gc ...

  8. 在URL地址栏中显示ico

             <!-- 在URL地址栏中显示ico -->         <link Rel="SHORTCUT ICON" href="imag ...

  9. Week 3: Structured Types 5. Tuples and Lists Exercise: odd tuples

    Exercise: odd tuples 5/5 points (graded) ESTIMATED TIME TO COMPLETE: 5 minutes Write a procedure cal ...

  10. HDU 6301 (贪心+优先队列)

    题目大意: 求一个长度为n的数列, 给出m个区间,这m个区间各自区间内的数不同 题解: 用优先队列来模拟过程 , 解题思路是想到了 , 可是不知道如何实现 , 果然还须继续努力呀 这道题思路是去掉重复 ...