通过浏览器直接打开Android应用程序

介绍如何通过点击手机浏览器中的链接,直接打开本地Android App。

实现方式不太完美,最近看了微博、京东的手机版网页,感觉他们的实现方式很不错,研究了一下,实现以下效果:

如果本地已经安装了指定Android应用,就直接打开它;如果没有安装,则直接下载该应用的安装文件(也可以跳转到下载页面)。

实现效果

如下图所示,在手机浏览器中访问京东的手机版网站(m.jd.com),顶部会有一个广告图,点击这个广告图,如果手机上已经安装了京东App,则直接打开,如果没有安装,则开始下载。

实现方式

1.为Android应用的启动Activity设置一个Schema,如下:

<data android:host="splash" android:scheme="cundong"/>

2.用户点击浏览器中的链接时,在动态创建一个不可见的iframe,并且让这个iframe去加载步骤1中的Schema,如下:

var ifr = document.createElement('iframe');
ifr.src="cundong://splash"

3,如果在指定的时间内没有跳转成功,则当前页跳转到apk的下载地址(或下载页),如下:

window.location = download_url;

HTML代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<! doctype  html>
< html >
     < head >
         < meta  http-equiv = "Content-Type"  content = "text/html; charset=utf-8" >
 
         < meta  name = "apple-mobile-web-app-capable"  content = "yes" >
         < meta  name = "apple-mobile-web-app-status-bar-style"  content = "black" />
 
         < title >this's a demo</ title >
         < meta  id = "viewport"  name = "viewport"  content = "width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui" >
     </ head >
     < body >
         < div >
             < a  id = "J-call-app"  href = "javascript:;"  class = "label" >立即打开&gt;&gt;</ a >
             < input  id = "J-download-app"  type = "hidden"  name = "storeurl"  value = "http://m.chanyouji.cn/apk/chanyouji-2.2.0.apk" >
         </ div >
 
         < script >
             (function(){
                 var ua = navigator.userAgent.toLowerCase();
                 var t;
                 var config = {
                     /*scheme:必须*/
                     scheme_IOS: 'cundong://',
                     scheme_Adr: 'cundong://splash',
                     download_url: document.getElementById('J-download-app').value,
                     timeout: 600
                 };
 
                 function openclient() {
                     var startTime = Date.now();
 
                     var ifr = document.createElement('iframe');
 
 
                     ifr.src = ua.indexOf('os') > 0 ? config.scheme_IOS : config.scheme_Adr;
                     ifr.style.display = 'none';
                     document.body.appendChild(ifr);
 
                     var t = setTimeout(function() {
                         var endTime = Date.now();
 
                         if (!startTime || endTime - startTime < config.timeout + 200) { 
                             window.location = config.download_url;
                         } else {
                             
                         }
                     }, config.timeout);
 
                     window.onblur = function() {
                         clearTimeout(t);
                     }
                 }
                 window.addEventListener("DOMContentLoaded", function(){
                     document.getElementById("J-call-app").addEventListener('click',openclient,false);
 
                 }, false);
             })()
         </ script >
     </ body >
</ html >

AndroidMainfext.xml

<activity
     android:name=".activity.LauncherActivity"
     android:configChanges="orientation|keyboardHidden|navigation|screenSize"
     android:label="@string/app_name"
     android:screenOrientation="portrait" >
        <intent-filter>
           <action android:name="android.intent.action.MAIN" />
           <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <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="splash" android:scheme="cundong" />
       </intent-filter>
</activity>
 
 
 

为了实现这个功能可折腾了我好久,先上一份代码,经楼主验证是绝对可以用的而且也比较清晰的代码!(ps:还是先剧透下吧,第三方大部分浏览器无法成功。)

点击浏览器中的URL链接,启动特定的App。

首先做成HTML的页面,页面内容格式如下:

<a href="[scheme]://[host]/[path]?[query]">启动应用程序</a> 

这一句就可以了。

各个项目含义如下所示:

scheme:判别启动的App。 ※详细后述

host:适当记述

path:传值时必须的key     ※没有也可以

query:获取值的Key和Value  ※没有也可以

 

作为测试好好写了一下,如下:

<a href="myapp://jp.app/openwith?name=zhangsan&age=26">启动应用程序</a>  

接下来是Android端。

首先在AndroidManifest.xml的MAIN Activity下追加以下内容。(启动Activity时给予)

※必须添加项

<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:scheme="myapp" android:host="jp.app" android:pathPrefix="/openwith"/>  

</intent-filter>

HTML记述的内容加入<data …/>。

其中必须的内容仅scheme,没有其他内容app也能启动。

※注意事项:intent-filter的内容【android.intent.action.MAIN】和 【android.intent.category.LAUNCHER】这2个,不能与这次追加的内容混合。

                 所以,如果加入了同一个Activity,请按以下这样做,否则会导致应用图标在桌面消失等问题。

复制代码

<intent-filter>  

    <action android:name="android.intent.action.MAIN"/>  

    <category android:name="android.intent.category.LAUNCHER" />  

</intent-filter>  

<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:scheme="myapp" android:host="jp.app" android:pathPrefix="/openwith"/>  

</intent-filter> 

复制代码

这样的话,没有问题。

 

接下来在Activity中需要取值的地方添加以下代码,我是直接写在OnCreate函数里的:

Intent i_getvalue = getIntent();  

String action = i_getvalue.getAction();  

  

if(Intent.ACTION_VIEW.equals(action)){  

    Uri uri = i_getvalue.getData();  

    if(uri != null){  

        String name = uri.getQueryParameter("name");  

        String age= uri.getQueryParameter("age");  

    }  

}

这样就能获取到URL传递过来的值了。

——————————————————————————————————我是分割线————————————————————————————————————

代码copy完了,是不是很惊奇的发现用浏览器输入

myapp://jp.app/openwith?name=zhangsan&age=26

是不是404,打不开?

楼主你这不是骗人么!楼主你个混蛋啊。

客官,稍安勿躁啊,你看看你用的浏览器是什么?UC,猎豹,欧朋?放弃吧,试试系统自带浏览器或者谷歌浏览器吧。肯定能成功的,不能成功的话再来坑我。哈哈。

——————————————————————————————————我是分割线————————————————————————————————————

突然觉得好悲哀,好不容易get了这个技能,却不能被第三方浏览器使用。在这个android浏览器大部分被第三方占据着的时代不得不说是个悲剧啊。

接下来还是说说为什么第三方浏览器不能成功吧。首先,我发现的是UC浏览器,如果你使用了自己的scheme,而不是http的话,uc会默认在你的scheme前面添加http://。这太坑爹了。其他浏览器没看是不是同样的情况。发现这个问题后我就试着把自己的scheme换成http。然后满怀期待的又跑了一遍,结果还是坑爹了。所以我想会不会是第三方浏览器对url做了处理。到这里,我也无可奈何了。我测试了UC,猎豹,欧朋,这3个都不支持。系统自带的和谷歌浏览器是支持的。

最后再补充个线索吧,在浏览器里搜索百度应用。进了他们的页面后,他们是可以实现在各种浏览器启动已经安装好的本地app的。看到这个后我就看了下他们页面的源码。

在这里他们页面添加了个data-sentintent的标签,看到这里,应该能确定第三方浏览器应该是默认都不支持发intent的,只能自己起一个。根据前端说,这个标签应该是自定义的。我们前端看源码的时候发现是这样的

所以最后的结果应该是百度这边是起了个端口,然后在应用里启用了一个服务,来监听这个端口,来获取这个intent。大概就这个思路了。不过楼主没有实际去操作。项目时间紧,太麻烦了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值