浏览器判断是否安装了ios/android客户端程序
最近在做一个项目,该项目的前身是为mobile browser量身打造的一个网站。现在有这样一个需求:
当用户在用mobile browser浏览该网站的时候会点击一个按钮/超链接,通过这个按钮的点击事情需要打开安装在本机的应用程序,或者如果本机没有安装该应用程序则打开应用商店并打开该程序在商店中的搜索结果页面。
刚开始的时候iPhone team的人给出一个solution,下面是实施跳转的HTML + javascript源代码。
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- </head>
- <body>
- <h2><a id="applink1" href="mtcmtc://profile/116201417">Open scheme(mtcmtc) defined in iPhone with parameters </a></h2>
- <h2><a id="applink2" href="unknown://nowhere">open unknown with fallback to appstore</a></h2>
- <p><i>Only works on iPhone!</i></p>
- <script type="text/javascript">
- // To avoid the "protocol not supported" alert, fail must open another app.
- var appstore = "itms://itunes.apple.com/us/app/facebook/id284882215?mt=8&uo=6";
- function applink(fail){
- return function(){
- var clickedAt = +new Date;
- // During tests on 3g/3gs this timeout fires immediately if less than 500ms.
- setTimeout(function(){
- // To avoid failing on return to MobileSafari, ensure freshness!
- if (+new Date - clickedAt < 2000){
- window.location = fail;
- }
- }, 500);
- };
- }
- document.getElementById("applink1").onclick = applink(appstore);
- document.getElementById("applink2").onclick = applink(appstore);
- </script>
- </body>
- </html>
其原理就是为HTML页面中的超链接点击事件增加一个setTimeout方法.
如果在iPhone上面500ms内,本机有应用程序能解析这个协议并打开程序,则这个回调方法失效;如果本机没有应用程序能解析该协议或者500ms内没有打开个程序,则执行setTimeout里面的function,就是跳转到apple的itunes。
我用同样的原理来处理android的javascript跳转,发现如果本机没有程序注册intent-filter for 这个协议,那么android内置的browser就会处理这个协议并且立即给出反应(404,你懂的),不会像iPhone一样去执行setTimeout里面的function,即便你把500ms改成0ms也不管用。
我就开始了我的Google search之旅,最终在stackoverflow一个不起眼的地方找到solution。
不解释,先给出源代码
android里面androidManifest.xml文件对activity的配置,如何配置就不表述了,表达能力有限,请参考developer.android.com
- <activity android:name=".ui.UploadActivity" android:screenOrientation="portrait">
- <intent-filter>
- <data android:scheme="http" android:host="192.168.167.33" android:port="8088" android:path="/mi-tracker-web/download.html"/>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- </intent-filter>
- </activity>
HTML页面中指向该应用程序的hyperlink
- <a id="applink1" href="http://192.168.167.33:8088/mi-tracker-web/download.html">
- Open Application</a>
不难发现,在androidManifest.xml中配置的filter中data的属性表述,在下面的HTML.href中全部看到了。请注意,这两个路径要全部一致,不能有差别,否则android系统就不会拦截这个hyperlink。
好了,为什么我说这个solution能解决我们当初提出来的需求呢,答案在这里:
如果说本机安装了这个应用程序
在android browser中点击HTML中的applink1,browser会重定向到指定的链接,但是由于我们的应用程序在android OS中配置了一个intent-filter,也是针对这个制定的链接。就是说现在android系统有两个程序能处理这个链接:一个是系统的browser,一个是配置了intent-filter的activity。现在点击这个链接,系统就会弹出一个选择:是用browser还是你指定的activity打开。如果你选择你的activity,系统就会打开你的应用程序,如果你继续选择用browser,就没有然后了。
如果说本机木有安装这个应用程序
那么这个HTML里面的这个超链接就起很重要的左右了,这个download.html里面可以forward到android的应用商店
download.jsp源代码如下。具体为什么请求的是download.html这个地址却访问到了download.jsp,就不解释了,struts2的东西。
- <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
- pageEncoding="ISO-8859-1"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
- <title>Insert title here</title>
- </head>
- <body>
- <script type="text/javascript">
- <span style="white-space:pre"> </span>window.location="market://search?q=com.singtel.travelbuddy.android";
- </script>
- </body>
- </html>
唉,文笔不行,估计我写出来自己都不怎么看得懂。就再把跳转的关键点说一下:
在androidManifest.xml中定义intent-filter的时候定义的scheme,host,port,path拼凑起来是一个有用的HTTP路径,这样就算本机没有activity定义了intent-filter来捕获这个链接,那这个链接也会重定向到打开android market place的页面,继而打开应用商店。因为每个android手机都会捕获到market这个协议(如果android手机里面没有market商店,不怪我哈),系统就会自动打开market place应用商店并根据参数进入搜索页面并显示结果。
浏览器判断是否安装了ios/android客户端程序的更多相关文章
- js判断是否是PC,IOS,Android客户端
写在前面 在项目中使用html5,需要针对不同的客户端浏览器有不一样的处理方式,这就需要对请求中的useragent进行分析,并进行处理. 一个例子 <%@ Page Language=&quo ...
- 浏览器网页判断手机是否安装IOS/Android客户端程序
IOS 原理如下: 为HTML页面中的超链接点击事件增加一个setTimeout方法. 如果在iPhone上面500ms内,本机有应用程序能解析这个协议并打开程序,则这个回调方法失效: 如果本机没有应 ...
- 浏览器判断是否安装APP
浏览器判断是否安装APP http://blog.csdn.net/henrywulibin/article/details/52087041 从浏览器中打开我们的应用 http://blog.csd ...
- fir.im Weekly - iOS/Android 应用程序架构解析
假如问你一个iOS or Android app的架构,你会从哪些方面来说呢? 本期 fir.im Weekly 收集了关于 iOS/Android 开发资源,也加入了一些关于 Web 前端方面的分 ...
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端一)
介绍完了服务器,这篇我们就要介绍重点了,写我们自己的IOS客户端程序 先看一下我们完成的效果图 首先下载xmppframework这个框架,下载 点ZIP下载 接下来,用Xcode新建一个工程 将以下 ...
- Gradle Android客户端程序打包(基于gradle 1.12版本验证通过)
一.前言 android客户端开发进入尾声,负责SEO同事突然发给我一个涉及45个发布渠道的噩耗,之前只发布自有渠道的工作方式(手动修改参数打包)已经不满足需求,所以引入最近比较流行的gradle打包 ...
- 通过js自动判断移动终端设备(ios\android等)
当用户用移动设备扫描一个二维码是,将扫描后的链接链接到一个页面,该页面只包含判断移动终端设备的js,判断好后自动跳转到对应的链接 或下载对应的内容. html代码如下: <script> ...
- 上传图片转为base64格式预览并压缩图片(不兼容IE9以下浏览器,兼容移动端ios,android)
前些天公司要求在微信移动端做上传图片并预览的功能,要求能够调用摄像头拍照并立即预览. 在网上搜了一些方法,开始自己写了个简单的功能实现代码.结果发现移动端拍照出来的图片动不动就2M+,又因为要批量上传 ...
- 在浏览器判断是否安装app,并打开相应的页面
1.代码功能: 判断手机/平板是否安装app 如果安装 则调用app的scheme,传入url当作参数,来做后续操作 如果没有安装 则跳转到app store/google play 下载app 2. ...
随机推荐
- Oracle反向字符截取逗號分隔字符串
DECLARE M ); BEGIN FOR I IN ( WITH T AS (SELECT REVERSE('i,am,a,test,hahahhah') AS STR FROM DUAL) SE ...
- Java 字符串格式化 String.format() 的使用
常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得c语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...
- mysql5大引擎之间的区别和优劣之分
数据库引擎介绍 MySQL数据库引擎取决于MySQL在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另 ...
- CAD交互绘制带颜色宽度的直线(com接口)
用户可以在控件视区任意位置绘制直线. 主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下: 参数 说明 DOUBLE dX1 直线的开始点x坐标 DOUBLE dY ...
- Web项目ConcurrentModificationException异常
后台SSH在做Session删除的时候,遇到了ConcurrentModificationException异常. 参考资料:http://blog.csdn.net/idesvo/article/d ...
- C++ 指针形参和指针引用形参的原理分析
C++ 函数的参数传递可以分为:值传递和引用传递. 两者的最大区别也很简单,如果该函数的参数只是读的话,值传递就可以满足.如果该函数的参数需要进行修改并返回的时候,就应该进行引用传递. C++指针作为 ...
- 笔试算法题(20):寻找丑数 & 打印1到N位的所有的数
出题:将只包含2,3,5的因子的数称为丑数(Ugly Number),要求找到前面1500个丑数: 分析: 解法1:依次判断从1开始的每一个整数,2,3,5是因子则整数必须可以被他们其中的一个整除,如 ...
- 测试第一个Oracle存储过程
存储过程语句 //简单存储过程的例子 //每调用一次打印一次hello world create or replace procedure sayhelloworld as begin dbms_ou ...
- Spring 事物注解属性
@Transactional属性 . propagation 事物的传播属性 . isolation 事物的隔离属性 . readonly 设置只读属性 . timeout 设置超时属性 . roll ...
- AutoMapper 使用总结1
初识AutoMapper 在开始本篇文章之前,先来思考一个问题:一个项目分多层架构,如显示层.业务逻辑层.服务层.数据访问层.层与层访问需要数据载体,也就是类.如果多层通用一个类,一则会暴露出每层的字 ...