Skip to content

Instantly share code, notes, and snippets.

@siweng
Created June 18, 2014 10:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save siweng/12eba45babcf67e8f3bd to your computer and use it in GitHub Desktop.
Save siweng/12eba45babcf67e8f3bd to your computer and use it in GitHub Desktop.
从手机端浏览器呼起本地应用逻辑
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>redirectToNative的demo</title>
</head>
<body>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<div style="font-size:16px;color:#333">如果没有自动下载,请手动<a style="color:red;font-size:20px" href="http://m.etao.com/download.php?src=unsupport">点此下载一淘客户端</a>,安装后用一淘客户端的扫描功能重新扫描二维码即可;</br></br>如果您不想安装客户端,也可以<a style="color:red;font-size:20px" id="J_gotoH5" href="http://m.etao.com/#item/">直接访问etao触屏版</a>,同样有手机专享价以及优惠券和返利!</div>
<script>
/**
* @fileoverview
* @author miaojing<miaojing@taobao.com>
* @module redirectToNative 移动页面中间跳转页面使用,打开native app,没安装则引导去下载app,不依赖任何kissy模块
* @ps 线上运行数月至今,目前测试发现魅族手机无法识别etao://item 怀疑手机系统不支持,具体原因客户端开发排查目前无果,这种情况可在跳转页面添加文本再次引导用户
**/
/**
* @class RedirectToNative
* @constructor
*/
var RedirectToNative = {
/**
* iosNativeUrl: string 必选 ios app上自定义的url scheme) 如 taobao://home(淘宝首页) etao://item?nid=xxx(一淘商品详情页)
* andriodNativeUrl: string 必选 android app自定义的url scheme
* iosInstallUrl: string 必选 ios app store里的安装地址
* androidInstallUrl: string 必选 android app的apk地址
* package: string 可选 默认com.taobao.taobao android的包名,如淘宝为com.taobao.taobao,etao为com.taobao.etao
* iosOpenTime: int 可选默认800ms, 启动ios客户端所需时间,一般ios平台整体性能不错,打开速度较快
* androidOpenTime: int 可选默认2000ms,启动android客户端所需时间,android系统性能参差不齐所需启动时间也不齐,和android客户端本身启动时间也有关,比如3.0版本启动一淘客户端就平均比淘宝客户端要慢200ms
*/
init: function(config) {
var self = this;
self.platform = self._UA();
// pc下 什么都不处理 pc访问下可能href可以链接去其他地址
if(!self.platform) return;
if (self.platform == 'ios') {
self.installUrl = config.iosInstallUrl;
self.nativeUrl = config.iosNativeUrl;
self.openTime = config.iosOpenTime || 800;
} else {
self.installUrl = config.androidInstallUrl;
self.nativeUrl = config.andriodNativeUrl;
self.openTime = config.androidOpenTime || 3000;
self.package = config.package || 'com.taobao.taobao';
}
//只有android下的chrome要用intent协议唤起native
if (self.platform != 'ios' && !!navigator.userAgent.match(/Chrome/i)) {
self._hackChrome();
} else {
self._gotoNative();
}
},
/**
* _hackChrome 只有android下的chrome要用intent协议唤起native
* https://developers.google.com/chrome/mobile/docs/intents
* @return {[type]}
*/
_hackChrome: function() {
var self = this;
var startTime = Date.now();
var paramUrlarr = self.nativeUrl.split('://'),
scheme = paramUrlarr[0],
schemeUrl = paramUrlarr[1];
window.location = 'intent://' + schemeUrl + '#Intent;scheme=' + scheme + ';package=' + self.package + ';end';
setTimeout(function() {
self._gotoDownload(startTime);
}, self.openTime);
},
/**
* [_gotoNative 跳转至native,native超时打不开就去下载]
* @return
*/
_gotoNative: function() {
var self = this;
var startTime = Date.now(),
doc = document,
body = doc.body,
iframe = doc.createElement('iframe');
iframe.id = 'J_redirectNativeFrame';
iframe.style.display = 'none';
iframe.src = self.nativeUrl;
//运行在head中
if(!body) {
setTimeout(function(){
doc.body.appendChild(iframe);
}, 0);
} else {
body.appendChild(iframe);
}
setTimeout(function() {
doc.body.removeChild(iframe);
self._gotoDownload(startTime);
/**
* 测试时间设置小于800ms时,在android下的UC浏览器会打开native app时并下载apk,
* 测试android+UC下打开native的时间最好大于800ms;
*/
}, self.openTime);
},
/**
* [_gotoInstall 去下载]
* @param {[type]} startTime [开始时间]
* @return
*/
_gotoDownload: function(startTime) {
var self = this;
var endTime = Date.now();
if (endTime - startTime < self.openTime + 500) {
window.location = self.installUrl;
}
},
/**
* [_UA 检测平台]
* @return string [ios|android| ]
*/
_UA: function() {
var ua = navigator.userAgent;
// ios
if (!!ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {
return 'ios';
} else if (!!ua.match(/Android/i)) {
return 'android';
} else {
return '';
}
}
}
//透传参数
var searchStr = location.search,
iosNativeUrl = 'etao://home' + searchStr,
andriodNativeUrl = 'etao://home' + searchStr,
downloadUrl = 'http://m.etao.com/download.php' + searchStr,
configObj = {
iosInstallUrl: downloadUrl,
androidInstallUrl: downloadUrl,
iosNativeUrl: iosNativeUrl,
andriodNativeUrl: andriodNativeUrl,
package: 'com.taobao.etao'
};
RedirectToNative.init(configObj);
</script>
</body>
</html>
@lyk248
Copy link

lyk248 commented Jun 7, 2016

关于 intent 方法,官方说 versions 25 and later 支持,但我这 chrome/30 和 chrome/37 的安卓原生浏览器都不行,三星的 chrome/28 却可以,感觉这个兼容性实在是太复杂了。另外,UC浏览器中的超时问题就算把延时设置成5000ms还是会打开同时进入下载。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment