对于app打开而言最常规的打开就是通过url scheme的方式去打开你的app,如下的
myapp://myapp://open
myapp://type=1&id=2sdeo223lwe
这些抛出都是以url的方式进行抛出,app捕捉到这些抛出去做相应的处理,本文对app的处理不做详细描述,app开发请自行谷歌百度。对于前端而言抛出的方式也有很多,而最理想的方式是通过iframe的src对其进行链抛出,来!说的在多都没有代码来的清晰,请看下面。
//实际上就是新建一个iframe的生成器var createIframe=(function(){
var iframe
return function(){
if(iframe){
return iframe
}else{
iframe = document.createElement('iframe')
iframe.style.display = 'none'
document.body.appendChild(iframe)
return iframe
}
}
})()
之后我们还需要一个url scheme:
//生成一个url scheme,假设我们约定的scheme是myApp://type=1&id=iewo212j32这种形式的var baseScheme = "myApp://"
var createScheme=function(options){
var urlScheme=baseScheme
for(var item in options){
urlScheme=urlScheme+item + '=' + encodeURIComponent(options[item]) + "&"
}
urlScheme = urlScheme.substring(0, urlScheme.length - 1)
return encodeURIComponent(urlScheme)
}
这种scheme形式的其实不是最好的,根据我们踩过的坑,觉得约定为与http协议相近可能更好一些,具体的协议需要前端人员自己去和app端人员约定。
ok万事具备,iframe有了,urlScheme也有了,该去打开app了
var openApp=function(){var localUrl=createScheme()
var openIframe=createIframe()
if(isIos()){
//判断是否是ios,具体的判断函数自行百度
window.location.href = localUrl
var loadDateTime = Date.now()
setTimeout(function () {
var timeOutDateTime = Date.now()
if (timeOutDateTime - loadDateTime < 1000) {
window.location.href = "你的下载页面"
}
}, 25)
}else if(isAndroid()){
//判断是否是android,具体的判断函数自行百度
if (isChrome()) {
//chrome浏览器用iframe打不开得直接去打开,算一个坑
window.location.href = localUrl
} else {
//抛出你的scheme
openIframe.src = localUrl
}
setTimeout(function () {
window.location.href = "你的下载页面"
}, 500)
}else{
//主要是给winphone的用户准备的,实际都没测过,现在winphone不好找啊
openIframe.src = localUrl
setTimeout(function () {
window.location.href = "你的下载页面"
}, 500)
}
}
以上就是你要打开scheme的主要代码了,好吧,实际上不只是打开app,还要实现未打开的时候跳到下载页去。其中安卓实际上无论有没有打开都会跳到下载页去,而ios........好吧!按照网上的说法是浏览器失焦后会挂起脚本,呵呵,这是多老的ios版本的表现了,实际上现在的ios已经没有这么做,有些版本会跟安卓的表现一样,而有些则是直接跳转根本不会去打开,还有打开的时候那个恶心的系统弹窗是什么鬼。好吧,实际上至此你会发现,ios9.0以上的有些打不开直接跳,有些打得开还会有允许弹窗,而微信则是无论如何都打不开,实际上微信会在他的浏览器里拦截掉所有未经其允许的scheme包括app store。
转自:《怎么在网页中打开你的app》@AlfredMou -- segmentfault
window.NRUM = window.NRUM || {}window.NRUM.config = {
key:'27e86c0843344caca7ba9ea652d7948d',
clientStart: +new Date()
}
(function() {
var n = document.getElementsByTagName('script')[0],
s = document.createElement('script')
s.type = 'text/javascript'
s.async = true
s.src = '//nos.netease.com/apmsdk/napm-web-min-1.1.3.js'
n.parentNode.insertBefore(s, n)
})()
(function(window,doc){
// http://apm.netease.com/manual?api=web
NRUM.mark &&NRUM.mark('pageload', true)
var list = []
var config = null
// jsonp
function jsonp(a, b, c) {
var d
d = document.createElement('script')
d.src = a
c &&(d.charset = c)
d.onload = function() {
this.onload = this.onerror = null
this.parentNode.removeChild(this)
b &&b(!0)
}
d.onerror = function() {
this.onload = this.onerror = null
this.parentNode.removeChild(this)
b &&b(!1)
}
document.head.appendChild(d)
}
function localParam(search,hash){
search = search || window.location.search
hash = hash || window.location.hash
var fn = function(str,reg){
if(str){
var data = {}
str.replace(reg,function( $0, $1, $2, $3 ){
data[ $1 ] = $3
})
return data
}
}
return {search: fn(search,new RegExp( "([^?=&]+)(=([^&]*))?", "g" ))||{},hash: fn(hash,new RegExp( "([^#=&]+)(=([^&]*))?", "g" ))||{}}
}
jsonp('http://active.163.com/service/form/v1/5847/view/1047.jsonp')
window.search = localParam().search
window._callback = function(data) {
window._callback = null
list = data.list
if(search.s &&!!search.s.match(/^wap/i)) {
config = list.filter(function(item){
return item.type === 'wap'
})[0]
return
}
config = list.filter(function(item){
return item.type === search.s
})[0]
}
var isAndroid = !!navigator.userAgent.match(/android/ig),
isIos = !!navigator.userAgent.match(/iphone|ipod/ig),
isIpad = !!navigator.userAgent.match(/ipad/ig),
isIos9 = !!navigator.userAgent.match(/OS 9/ig),
isYx = !!navigator.userAgent.match(/MailMaster_Android/i),
isNewsapp = !!navigator.userAgent.match(/newsapp/i),
isWeixin = (/MicroMessenger/ig).test(navigator.userAgent),
isYixin = (/yixin/ig).test(navigator.userAgent),
isQQ = (/qq/ig).test(navigator.userAgent),
params = localParam().search,
url = 'newsapp://',
iframe = document.getElementById('iframe')
var isIDevicePhone = (/iphone|ipod/gi).test(navigator.platform)
var isIDeviceIpad = !isIDevicePhone &&(/ipad/gi).test(navigator.platform)
var isIDevice = isIDevicePhone || isIDeviceIpad
var isandroid2_x = !isIDevice &&(/android\s?2\./gi).test(navigator.userAgent)
var isIEMobile = !isIDevice &&!isAndroid &&(/MSIE/gi).test(navigator.userAgent)
var android_url = (!isandroid2_x) ? "http://3g.163.com/links/4304" : "http://3g.163.com/links/6264"
var ios_url = "http://3g.163.com/links/3615"
var wphone_url = "http://3g.163.com/links/3614"
var channel = params.s || 'newsapp'
// 判断在不同环境下app的url
if(params.docid){
if(params['boardid'] &&params['title']){
url = url + 'comment/' + params.boardid + '/' + params.docid + '/' + params.title
}else{
url = url + 'doc/' + params.docid
}
}else if(params.sid){
url = url + 'topic/' + params.sid
}else if(params.pid){
var pid = params.pid.split('_')
url = url + 'photo/' + pid[0] + '/' + pid[1]
}else if(params.vid){
url = url + 'video/' + params.vid
}else if(params.liveRoomid){
url = url + 'live/' + params.liveRoomid
}else if(params.url){
url = url + 'web/' + decodeURIComponent(params.url)
}else if(params.expertid){
url = url + 'expert/' + params.expertid
}else if(params.subjectid){
url = url + 'subject/' + params.subjectid
}else if(params.readerid){
url = url + 'reader/' + params.readerid
}else{
url += 'startup'
}
if(url.indexOf('?') >= 0){
url += '&s=' + (params.s || 'sps')
}else{
url += '?s=' + (params.s || 'sps')
}
// ios &&易信 用iframe 打开
if((isIos||isIpad) &&navigator.userAgent.match(/yixin/i)) {
document.getElementById('iframe').src = url
}
var height = document.documentElement.clientHeight
// 通常情况下先尝试使用iframe打开
document.getElementById('iframe').src = url
// 移动端浏览器中,将下载页面显示出来
if(!isWeixin &&!isQQ &&!isYixin &&!isYx){
document.querySelector('.main-body').style.display = 'block'
if(isIos9){
document.querySelector('.main-body').classList.add('showtip')
}
setTimeout(function(){
document.body.scrollTop = 0
},200)
}else{
document.getElementById('guide').style.display = 'block'
}
// Forward To Redirect Url
// Add by zhanzhixiang 12/28/2015
if (params.redirect) {
var redirectUrl = decodeURIComponent(params.redirect)
if ( typeof(URL) === 'function' &&new URL(redirectUrl).hostname.search("163.com") !== -1) {
window.location.href = redirectUrl
} else if (redirectUrl.search("163.com") !== -1){
window.location.href = redirectUrl
}
}
// Forward To Redirect Url End
if ((isWeixin || isQQ) &&isAndroid) {
window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=com.netease.newsreader.activity&ckey=CK1331205846719&android_schema=' + url.match(/(.*)\?/)[1]
}
if(isIos||isIpad){
document.getElementById("guide").classList.add('iosguideopen')
}else if (isAndroid){
document.getElementById("guide").classList.add('androidguideopen')
}else{
// window.location.href = 'http://www.163.com/newsapp'
}
document.getElementById('link').addEventListener('click', function(){
// 统计
neteaseTracker &&neteaseTracker(false,'http://sps.163.com/func/?func=downloadapp&modelid='+modelid+'&spst='+spst+'&spsf&spss=' + channel,'', 'sps' )
if (config) {
android_url = config.android
}
if (config &&config.iOS) {
ios_url = config.iOS
}
if(isWeixin || isQQ){
return
}
var msg = isIDeviceIpad ? "检测到您正在使用iPad, 是否直接前往AppStore下载?" : "检测到您正在使用iPhone, 是否直接前往AppStore下载?"
if (isIDevice){
window.location = ios_url
return
}else if(isAndroid){
// uc浏览器用iframe唤醒
if(navigator.userAgent.match(/ucbrowser|yixin|MailMaster/i)){
document.getElementById('iframe').src = url
} else {
window.location.href = url
}
setTimeout(function(){
if(document.webkitHidden) {
return
}
if (confirm("检测到您正在使用Android 手机,是否直接下载程序安装包?")) {
neteaseTracker &&neteaseTracker(false,'http://sps.163.com/func/?func=downloadapp_pass&modelid='+modelid+'&spst='+spst+'&spsf&spss=' + channel,'', 'sps' )
window.location.href = android_url
} else {
neteaseTracker &&neteaseTracker(false,'http://sps.163.com/func/?func=downloadapp_cancel&modelid='+modelid+'&spst='+spst+'&spsf&spss=' + channel,'', 'sps' )
}
},200)
return
}else if(isIEMobile){
window.location = wphone_url
return
}else{
window.open('http://www.163.com/special/00774IQ6/newsapp_download.html')
return
}
}, false)
setTimeout(function(){
if(isIDevice &&params.notdownload != 1 &&!isNewsapp &&!isIos9){
document.getElementById('link').click()
}
}, 1000)
})(window,document)
一、通过html页面打开Android本地的app1、首先在编写一个简单的html页面
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="m://my.com/">打开app</a><br/>
</body>
</html>
2、在Android本地app的配置
在AndroidManifest的清单文件里的intent-filte中加入如下元素:
<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="my.com"
android:scheme="m" />
</intent-filter>
示例截图如下:
然后使用“手机浏览器”或者“webview”的方式打开这个本地的html网页,点击“打开APP”即可成功开启本地的指定的app
二、如何通过这个方法获取网页带过来的数据
只能打开就没什么意思了,最重要的是,我们要传递数据,那么怎么去传递数据呢?
我们可以使用上述的方法,把一些数据传给本地app,那么首先我们更改一下网页,代码修改后:
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="m://my.com/?arg0=0&arg1=1">打开app</a><br/>
</body>
</html>
(1).假如你是通过浏览器打开这个网页的,那么获取数据的方式为:
Uri uri = getIntent().getData() String test1= uri.getQueryParameter("arg0") String test2= uri.getQueryParameter("arg1")
(2)如果使用webview访问该网页,获取数据的操作为:
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Uri uri=Uri.parse(url)
if(uri.getScheme().equals("m")&&uri.getHost().equals("my.com")){
String arg0=uri.getQueryParameter("arg0")
String arg1=uri.getQueryParameter("arg1")
}else{
view.loadUrl(url)
}
return true
}
})