H5页面app应用程序跳转探索
2016-02-14 12:05
706 查看
很多做 web 开发的一定遇到过这种需求:点一个链接或按钮时,如果装了应用,就用该应用打开;没装的时候,iOS 跳 App Store 下载,Android 直接下载 apk 包。
在做读读日报的时候,就被这玩意花费了好长时间;然而 iOS 9 发布后,方案又失效了,于是又折腾了我几个小时。
首先做个科普,浏览器是无法知道应用有没有安装的。
应用可以设置一个(或多个)自己能打开自定义 URL scheme,例如 Twitter 就声明自己能打开「twitter://」。
iOS 应用中可以用 UIApplication 的 canOpenUrl 方法来检测对应的 URL 是否能打开。如果「twitter://」能被打开,也就说明安装了 Twitter 应用。再用 UIApplication 的 openURL 方法,就能跳转到对应的应用了。Android
中也是类似的做法。
接着看看浏览器应该怎么处理。
以 iOS 8 及更早的版本为例,Safari 在尝试打开自定义 URL scheme 时,会自动用相应的应用来打开。
而打开有两种方式:
直接跳转:例如点击链接、修改 window.location 等。
iframe 跳转:在 body 上添加一个 iframe,把它的 src 指定成要跳转的地址。
后一种方法不会引起页面可见的变化(例如页面内容变成一个新页面),不会导致浏览器历史记录的变化,大致实现如下:
这样在点击这个 a 标签时,会先尝试打开自定义 URL scheme。如果成功,则跳到应用里去了;如果失败,则跳转到 href 属性,即下载页。
然而这个方案在很多安卓机型和 WebView 中不可用,为了保证可用,就只好用第一种方案了:
这里是让浏览器尝试打开自定义 URL scheme,并且忽略浏览器默认行为(跳转到 href 属性)。等待一秒后,再检查当前时间,如果超过 1100 毫秒,说明跳转 app 成功了(跳转 app 会让浏览器的定时器变慢),什么也不用干;如果没超过 1100
毫秒,很可能是没有安装应用,就跳到下载地址。
而在 iOS 9 上,iframe 方案也不可用了,必须用第一种方法。
不过照抄 Android 的代码也没用,因为在打开自定义 URL scheme 时,会弹出一个对话框,询问是否用 xx 应用来打开。在用户还没来得及点打开按钮前,定时器又触发了,导致跳到 App Store。
经过一番探索后发现,尝试打开自定义 URL scheme 后,接一个页面跳转,会把对话框覆盖掉,再刷新页面,就能无需确认跳转应用了:
其中,下载页是一个 HTML 页面,用 JavaScript 延时 2 秒跳转到 App Store。如果直接在 HTTP 头里用 Location 跳转到 App Store,则会立刻跳到 App Store,没机会跳应用。
但是这仅仅解决了已安装应用的时候,能跳到应用的场景;而没装应用时,跳 App Store 的请求会被取消掉。
于是我用到了两个很神奇的定时器:
如果想尝试修改这两个值,可以自己试试,失败了不要找我。它的原理大概是跳应用需要一个准备时间,在这个期间内都能被其他跳转打断。而如果跳应用失败,reload 并不会打断 App Store 的跳转。
终于能让它可用了,但是从应用返回时,会发现 Safari 停留在了下载页,而不是最初的网页。因此可以在下载页加上这样的代码:
也就是让它 2 秒后回到前一个页面,这样从应用返回时,就不会停留在下载页了。
最后,iOS 9 还支持应用打开所拥有的域名的 http scheme,不过对于这种可以自动选择下载和跳应用的场景没有帮助,这里就不提了。
转载于此:keakon的涂鸦馆
在做读读日报的时候,就被这玩意花费了好长时间;然而 iOS 9 发布后,方案又失效了,于是又折腾了我几个小时。
首先做个科普,浏览器是无法知道应用有没有安装的。
应用可以设置一个(或多个)自己能打开自定义 URL scheme,例如 Twitter 就声明自己能打开「twitter://」。
iOS 应用中可以用 UIApplication 的 canOpenUrl 方法来检测对应的 URL 是否能打开。如果「twitter://」能被打开,也就说明安装了 Twitter 应用。再用 UIApplication 的 openURL 方法,就能跳转到对应的应用了。Android
中也是类似的做法。
接着看看浏览器应该怎么处理。
以 iOS 8 及更早的版本为例,Safari 在尝试打开自定义 URL scheme 时,会自动用相应的应用来打开。
而打开有两种方式:
直接跳转:例如点击链接、修改 window.location 等。
iframe 跳转:在 body 上添加一个 iframe,把它的 src 指定成要跳转的地址。
后一种方法不会引起页面可见的变化(例如页面内容变成一个新页面),不会导致浏览器历史记录的变化,大致实现如下:
<a href="下载地址">下载或打开 app</a> <script> $('a').click(function() { var ifr = document.createElement('iframe'); ifr.src = '自定义 URL scheme'; ifr.style.display = 'none'; document.body.appendChild(ifr); setTimeout(function(){ document.body.removeChild(ifr); }, 3000); }); </script>
这样在点击这个 a 标签时,会先尝试打开自定义 URL scheme。如果成功,则跳到应用里去了;如果失败,则跳转到 href 属性,即下载页。
然而这个方案在很多安卓机型和 WebView 中不可用,为了保证可用,就只好用第一种方案了:
$('a').click(function() { location.href = '自定义 URL scheme'; t = Date.now(); setTimeout(function(){ if (Date.now() - t < 1100) { location.href = 'Android 下载地址'; } }, 1000); return false; }
这里是让浏览器尝试打开自定义 URL scheme,并且忽略浏览器默认行为(跳转到 href 属性)。等待一秒后,再检查当前时间,如果超过 1100 毫秒,说明跳转 app 成功了(跳转 app 会让浏览器的定时器变慢),什么也不用干;如果没超过 1100
毫秒,很可能是没有安装应用,就跳到下载地址。
而在 iOS 9 上,iframe 方案也不可用了,必须用第一种方法。
不过照抄 Android 的代码也没用,因为在打开自定义 URL scheme 时,会弹出一个对话框,询问是否用 xx 应用来打开。在用户还没来得及点打开按钮前,定时器又触发了,导致跳到 App Store。
经过一番探索后发现,尝试打开自定义 URL scheme 后,接一个页面跳转,会把对话框覆盖掉,再刷新页面,就能无需确认跳转应用了:
$('a').click(function() { location.href = '自定义 URL scheme'; location.href = '下载页'; location.reload(); }
其中,下载页是一个 HTML 页面,用 JavaScript 延时 2 秒跳转到 App Store。如果直接在 HTTP 头里用 Location 跳转到 App Store,则会立刻跳到 App Store,没机会跳应用。
但是这仅仅解决了已安装应用的时候,能跳到应用的场景;而没装应用时,跳 App Store 的请求会被取消掉。
于是我用到了两个很神奇的定时器:
$('a').click(function() { location.href = '自定义 URL scheme'; setTimeout(function() { location.href = '下载页'; }, 250); setTimeout(function() { location.reload(); }, 1000); }
如果想尝试修改这两个值,可以自己试试,失败了不要找我。它的原理大概是跳应用需要一个准备时间,在这个期间内都能被其他跳转打断。而如果跳应用失败,reload 并不会打断 App Store 的跳转。
终于能让它可用了,但是从应用返回时,会发现 Safari 停留在了下载页,而不是最初的网页。因此可以在下载页加上这样的代码:
setTimeout(function() {history.back()}, 2000);
也就是让它 2 秒后回到前一个页面,这样从应用返回时,就不会停留在下载页了。
最后,iOS 9 还支持应用打开所拥有的域名的 http scheme,不过对于这种可以自动选择下载和跳应用的场景没有帮助,这里就不提了。
转载于此:keakon的涂鸦馆
相关文章推荐
- CWinAPP类的成员变量和成员方法
- Android仿微信雷达辐射搜索好友(逻辑清晰实现简单)
- 与ios相比,android为什么越用越卡
- LinearLayout的weight(权值)详解
- android:Activity启动模式之singleTask(二)
- Android中实现监听ScrollView滑动事件
- android开发中经常看到@Override是什么意思呢?
- IOS 处理分页数据的上拉下拉刷新
- 微信红包随机算法初探
- IOS 时时刷新函数
- iOS 程序的生命周期
- android 资源
- IOS 添加标题
- Android getTopActivity的方法
- Android 动画 ObjectAnimator基本使用
- IOS 设置label背景颜色
- IOS文件系统与操作方式概括
- 移动端HTML5开发心得(转)
- 访问者模式--Android源码设计模式笔记
- Android——Animator笔记:属性动画