如何在HTML网页中调起APP

html-css07

如何在HTML网页中调起APP,第1张

对于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本地的app

1、首先在编写一个简单的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

}

})