现在各类app,分享出去的H5页面中,一般都会带着一个立即打开的按钮,如果本地安装了app,那么就直接唤起本地的app,如果没有安装,则跳转到下载。这是一个很正常的推广和导流量的策略,最近产品经理就提出了这样的一个需求,做一个像今日头条功能一样的带打开app的下载条。

实现这个功能,我们需要解决两个问题
1、js如何唤起本地app
2、js如何知道手机已经安装了对应的应用

js如何唤起本地app

既然是通过网页调用app,这个当然涉及到与app的通信。通过咨询ios和android的同事,ios与android都支持一种叫做schema协议的链接。这种协议的类似于我们熟悉的http协议,我们只要跟app协商好协议头,app通过拦截到这个协议头的请求就可以知道有网页要求调用。而对于js来说,我们这要像a标签的href一样来激活这个协议的链接就行了。

比如:

<a href="myapp://">调起app</a>

这种方式ios和android都可以共用

2、如何知道手机已经安装的对应的应用对于这个功能的实现,首先想到的是查询应用是否存在,但是这种方法显而易见是行不通的,比如说你在UC浏览器,微信中,我们无法主动的去查询我们系统中是否安装了该应用。所以这个判断是无法实现。所以我们就需要采用曲线救国的方式来实现。既然我们可以唤起app,那我们就可以忽略判断,直接唤起app,如果用户没有安装,我们做一个容错处理。

结合这个思路,我们基本可以得到我们的实现方案

var iframe = document.createElement('iframe');
var body = document.body;
iframe.style.display = "none";
ar timer = null; var openapp = document.getElementById('openapp');
openapp.addEventListener('click', function() {
body.appendChild(iframe);
iframe.src = "appschema://";
timer = setTimeout(function() {
wondow.location.href = "download.html"; //容错的下载页面
}, 500);
}, false)

写完代码,做了测试,发现这样的实现有很多问题
1、微信无法调起。微信对于链接的跳转限制很严重,很多下载外链都引导到浏览器打开
2、调起app返回浏览器的时候,会跳转到下载页面,既然用户已经下载了app,再让页面跳转到下载页很不友好
3、ios9+的safari无法通过iframe跳转到其他页面

有问题就需要解决

1、对于微信或者QQ空间,在网上查找资料,如果是在应用宝上线的应用,应用宝提供了微下载来实现微信和QQ打开app,先跳转到应用宝的的下载链接,然后下载宝链接会判断打开对应的app,具体参考(http://wiki.open.qq.com/index.php?title=mobile/%E5%BA%94%E7%94%A8%E5%AE%9D%E5%BE%AE%E4%B8%8B%E8%BD%BD)但是应用宝的微下载有个问题,ios微信和QQ中无法打开对应的应用,只是会通过你应用宝配置的appstore下载链接跳转到对应的下载页面,再从appstore里面打开应用。所以这个问题还是不能完全解决,只能完美解决android的机器

2、针对问题2,网上有人通过监控页面的pagehide和visibilitychange方法来实现禁止跳转,具体的实现思路是监控页面是否隐藏,利用延时如果页面已经打开app,此时页面会是隐藏状态,触发页面的隐藏事件,clear延时事件,禁止跳转,不过这个方案会出现问题,有一些浏览器在app打开,离开浏览器之后,js事件不在执行,也就是此时无法监控的页面的隐藏,在返回页面的时候,js继续执行,但是事件监控的还是页面展示的状态,无法clear延时事件,所以该方式无法完美解决这个问题

后来找到了另外的解决方案,调起app需要唤起另外的进程,所以js的进程会挂起,导致前后有一个时间差,记录前后的事件差对比就可以判断是否调起了app了

iframe.src = "appschema://";
var timer = null,
t = Date.now();
timer = setTimeout(function() {
if (Date.now() - t > 1200) {
clearTimeout(timer);
return false;
}
}, 1000);

3、对于问题3,Apple为iOS 9发布了一个所谓的通用链接的深层链接特性,即Universal links。只要在app中授权好域名,在网页中只要打开对应域名链接,都会检测与域名绑定的app是否存在,如果存在,直接调起app,具体参考(http://stackoverflow.com/questions/31891777/ios-9-safari-iframe-src-with-custom-url-scheme-not-working),并且该方法不会被微信拦截,可以在微信中使用,这样也就解决了我们在腾讯平台下ios无法通过微下载打开的问题

最后再来整理一下我们的思路
1、ios通过Universal links,针对ios9一下和以前版本没有实现Universal links,在绑定好的域名下做一个中间页,直接跳转到中间页
2、android分平台,如果是微信或者QQ(可以通过用户代理检测),直接通过微下载,其他浏览器,直接用schema协议

具体代码实现如下

var url = {
open: 'duchuang://',
down: 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework'
},
iframe = document.createElement('iframe');
iframe.style.cssText = 'display:none;width=0;height=0';
var timer = null,
//点击第三方下载
isAndroid = !!navigator.userAgent.match(/android/ig),
isIos = !!navigator.userAgent.match(/iphone|ipod/ig),
isIpad = !!navigator.userAgent.match(/ipad/ig),
isWeixin = (/MicroMessenger/ig).test(navigator.userAgent),
isQQ = (/qq/ig).test(navigator.userAgent),
openapp = document.getElementById('cal-app');
openapp.addEventListener('click', function() {
if (isIos) {
window.location.href = "https://appdetail.netwin.cn/download.html"
} if (isAndroid) {
if (isWeixin || isQQ) { //andorid微信和QQ走微下载
window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework&android_schema=' +  url;
} else {
body.appendChild(iframe);
iframe.src = url.open;
var t = Date.now();
timer = setTimeout(function() {
if (Date.now() - t > 1200) {
clearTimeout(timer);
return false;
}
if (document.webkitHidden || document.hidden) {
return false;
}
window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.nayun.framework';
}, 1000);
}
}
}, false) document.addEventListener("webkitvisibilitychange", function() {
var tag = document.hidden || document.webkitHidden;
if (tag) {
clearTimeout(timer);
}
}); window.addEventListener('pagehide', function() {
clearTimeout(timer);
})

H5页面中唤起native app的更多相关文章

  1. 浏览器中唤起native app || 跳转到应用商城下载

    前段时间遇到一个小需求:要求在分享出来的h5页面中,有一个立即打开的按钮,如果本地安装了我们的app,那么点击就直接唤起本地app,如果没有安装,则跳转到下载. 因为从来没有做过这个需求,因此这注定是 ...

  2. Android/IOS 微信及浏览器(h5)中唤起本地APP,唤起浮层,然后用外部浏览器打开唤起某本地APP

    1 前言 微信点击链接,点击唤起某APP,在微信点开,默认是微信浏览器,点击button唤起,则会先提示浮层,然后用外部浏览器打开即可. 作为记录使用. 2 代码 相关源码如下: html: < ...

  3. H5页面中判断是安卓手机还是ios手机的方法;APP页面中嵌套的H5跳转到APP其他页面的方法。

    (一).在H5页面中,可以直接利用如下的方法来进行判断是安卓还是ios. var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linu ...

  4. 前端视频直播技术总结及video.js在h5页面中的应用

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/12557070.html,多谢,=.=~ (如果对你有帮助的话请帮我点个赞啦) 目前有一个需求是在 ...

  5. H5页面中尝试调起APP

    安卓版本5.0以上 IOS版本10.0以上 采用事件触发的方式处理唤醒APP 市面上常见的功能 这种功能现如今应该非常普遍了,淘宝H5,知乎H5等等... 点击后会调起APP或者打开下载页面或者直接进 ...

  6. iOS/Android 浏览器(h5)及微信中唤起本地APP

    在移动互联网,链接是比较重要的传播媒质,但很多时候我们又希望用户能够回到APP中,这就要求APP可以通过浏览器或在微信中被方便地唤起. 这是一个既直观又很好的用户体验,但在实现过程中会遇到各种问题: ...

  7. 客户端相关知识学习(四)之H5页面如何嵌套到APP中

    Android原生如何渲染H5页面 Android与 H5 的交互方式大概有以下 1 种: 利用WebView进行交互(系统API) iOS原生如何渲染H5页面 iOS 与 H5 的交互方式大概有以下 ...

  8. 前端:微信支付和支付宝支付在pc端和h5页面中的应用

    1:h5微信支付 使用的是https://pay.weixin.qq.com/wiki/doc/api/index.html  中的 (1):公司需要首先要配置公众号微信支付地址和测试白名单(支付的时 ...

  9. 混合app开发,h5页面调用ios原生APP的接口

    混合APP开发中,前端开发H5页面,不免会把兼容性拉进来,在做页面的兼容性同事,会与原生app产生一些数据交互: 混合APP开发,安卓的兼容性倒是好说,安卓使用是chrome浏览器核心,已经很好兼容H ...

随机推荐

  1. 用jar包运行带GUI的java游戏

    这是从某论坛下载的java游戏demo,由于年代久远,所以没有记下出处.重要的是,这是一个带GUI的java程序. 链接: https://pan.baidu.com/s/1LjQ2bQPXvW-ti ...

  2. OSG学习:计算纹理坐标

    在很多时候,直接指定纹理坐标是非常不方便的,如曲面纹理坐标,只有少数的曲面(如圆锥.圆柱等)可以在不产生扭曲的情况下映射到平面上,其他的曲面在映射到表面时都会产生一定程度的扭曲.一般而言,曲面表面的曲 ...

  3. sql%bulk_rowcount && sql%rowcount 的使用

    说明: %BULK_ROWCOUNT 属性计算FORALL迭代影响行数 在进行SQL数据操作语句时,SQL引擎打开一个隐式游标(命名为SQL),该游标的标量属性(scalar attribute)有 ...

  4. PHP 常用函数总结(三)

    7.PHP JSON 格式 json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] ) 返回字符串,包含了 valu ...

  5. windows多线程(六) 互斥量Mutex与关键段CriticalSection比较

    一.关键段CS 和 互斥量Mutex 的相同点:都有线程拥有权 关键段和互斥量都有线程拥有权,即可以被一个线程拥有.在 前面讲关键段CS的文章中有说到,关键段结构体的第四个参数保存着拥有该关键段的线程 ...

  6. BZOJ5120 无限之环(费用流)

    方案合法相当于要求接口之间配对,黑白染色一波,考虑网络流.有一个很奇怪的限制是不能旋转直线型水管,考虑非直线型水管有什么特殊性,可以发现其接口都是连续的.那么对于旋转水管,可以看做是把顺/逆时针方向上 ...

  7. Jmeter—添加断言 判断接口响应数据是否符合预期

    发出请求之后,通过添加断言可以判断响应数据是否是我们的预期结果. 1 在Jmeter中发送一个状态返回200的http请求(参数故意输入错误).结果肯定是不是返回200啦. 但结果树中http请求的图 ...

  8. es各类SearchType的意思

    元素 含义 QUERY_THEN_FETCH 查询是针对所有的块执行的,但返回的是足够的信息,而不是文档内容(Document).结果会被排序和分级,基于此,只有相关的块的文档对象会被返回.由于被取到 ...

  9. Linux内核分析实验四----

    一.用户态.内核态 权限分级——为了系统本身更稳定,使系统不宜崩溃.(并不是所有程序员缩写的代码都很健壮!!) x86 CPU四种不同的执行级别:0(内核态)—3(用户态) 区分方法:CS:EIP(C ...

  10. linux内核分析 第七周 Linux内核如何装载和启动一个可执行程序

    一.编译链接的过程和ELF可执行文件格式 vi hello.c gcc -E -o hello.cpp hello.c -m32 //预处理.c文件,预处理包括把include的文件包含进来以及宏替换 ...