您的位置:首页 > 其它

对安卓在浏览器中判断是否有本地应用安装,并打开本地应用的总结

2014-10-30 00:00 281 查看
摘要: 这几天工作需要,碰到这样一个需求。就是在浏览器中点击一个下载链接,进行判断本地是否安装了下载平台这个应用。如果安装则直接打开应用进行下载,如果没有就跳转到下载链接先下载平台应用,应用开启的时候自动下载需要下载的目标软件。实际上百度手机助手等都是这样做的。

开始拿到这个需求,我是首先解决软件启动的时候自动下载这个功能。拿到目标软件的url就行了。这里就借鉴百度手机助手,看了他们的应用之后,如果手机没有装百度手机助手。我又点击了高速下载想下一个其它软件,他们每次从浏览器下载平台应用都是以一个appName_id_code.apk命名。然后将这个apk丢在download文件夹下面。就猜想肯定是应用第一次启动的时候去扫描download、UCdownload等一系列可能存放apk的位置。然后直接根据文件名匹配。在匹配到他的平台应用apk。然后取出了中间的我要下载的目标软件的id然后应用中进行自动下载的。这个需求这样做了。这是手机没有安装平台应用好说。好问题是安装了就直接打开下载。当然第一反应是用sheme 如果安装直接通过设置:

<intent-filter>
<data
android:host="hostname"
android:pathPrefix="路径"
android:scheme="myapp" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.VIEW" />
</intent-filter>

这样开启应用传递值过去,

if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {

//如果是跳转过来的得重置下这个状态让不要扫描SD卡

Env.isFirstDownLoad = false;

Intent intent = getIntent();

Uri uri = intent.getData();

if (uri != null) {

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

String url = AppDetailUtils.APP_DETAIL_URL + "?masterId=" + dId;

toDownload(url);

}

}

获取传递的值就行了。

接下来问题就来了。浏览器中怎么判断是否安装了本地应。。。在网上找了各种js方法都不能如意得到。不是浏览器打不开,就是各种弹窗。最后想到了是看网上有网友提出了一个起一个服务监听端口的方案。没找到代码 于是就凑合的写的试试。以手机作为服务端起一个服务监听一个定义的端口。如果在浏览器对这个地址有请求则证明安装了该应用就直接跳转。如果是没有响应就直接跳转到下载链接(其实主要是浏览器中怎么判断手机安装了应用的问题)。于是就试着写了很简单的服务器端口监听例子:

//服务端监听端口 然后页面进行访问

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import android.util.Log;
public class HttpSocketServer extends Thread {
private Socket socket;
public HttpSocketServer(Socket socket) {
this.socket = socket;
}
public void run() {
String data = "getAppData && getAppData({\"error\":4});";
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// jsonp处理,暂时没必要
Map<String, String> headMaps = new HashMap<String, String>();
String path = reader.readLine();
String headerStr;
while (null != (headerStr = reader.readLine())) {
if (headerStr.equals("")) {
break;
}
}
path = path.substring(path.indexOf(" "), path.lastIndexOf(" "))
.trim();
String paramstr;
if (path.indexOf("?") != -1) {
paramstr = path.substring(path.indexOf("?") + 1);
} else {
paramstr = path;
}
String[] strs = paramstr.split("&");
for (String ss : strs) {
int index = ss.indexOf("=");
if (index == -1)
break;
String key = ss.substring(0, ss.indexOf("="));
String value = ss.substring(ss.indexOf("=") + 1, ss.length());
headMaps.put(key, value);
Log.i("pconline", key + "    " + value);
}
if (null != headMaps && headMaps.get("callback") != null) {
// data = headMaps.get("callback")+"("+data+")" ;
}
Log.i("pconline", "data=== " + data);
OutputStreamWriter streamWriter = new OutputStreamWriter(
socket.getOutputStream(), "utf-8");
BufferedWriter bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("HTTP/1.1 200 OK \r\n");
bufferedWriter.write("Content-Type: text/html\r\n");
bufferedWriter.write("Access-Control-Allow-Origin: *\r\n");
bufferedWriter.write("Date: Thu, 13 Nov 2014 01:27:22 GMT\r\n");
bufferedWriter.write("Connection: keep-alive\r\n");
bufferedWriter.write("Content-Length: " + data.length()
+ "\r\n\r\n");
bufferedWriter.write(data);
bufferedWriter.write("\r\n");
bufferedWriter.flush();
reader.close();
bufferedWriter.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

在电脑浏览器上面先试验肯定是可以的。写手机上面试了下。结果不错也很好。接下来就是手机浏览器中实验了。于是写了个测试例子:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>测试用</title>
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest()
{
if(window.ActiveXObject)
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
}
function startRequest(url)
{
createXMLHttpRequest();
try
{
xmlHttp.onreadystatechange = function(){
handleStateChange()};
xmlHttp.open("GET", url, false);
//xmlhttp.SetRequestHeader("Content-Type","text/html; charset=UTF-8")
xmlHttp.send(null);
}
catch(exception)
{
//这里跳转到下载链接
window.location.href="http://www1.pconline.com.cn/mobile/pconline.apk";
}
}
function handleStateChange()
{
if(xmlHttp.readyState == 4)
{
if (xmlHttp.status == 200)

{
// 测试如果安装就开启应用 下载id为357956 的应用
window.location="myapp://appcenter.download/downloadwith?dId=357945";

}else{
//跳转到下载地址
}
}
}
</script>
</head>
<body>
<a href="javascript:startRequest('http://localhost:5869/')">调用测试</a>
</body>
</html>

如果安装了应用就会响应监听给返回值。其实返回值对我没用。我只需要知道能访问通就行了。访问不通就直接去下载平台应用。

PS: 之前这个不是很稳定,原来是程序退出的时候代码上面用的不是finish(),而是用的system.exit(0)。这个方法会关闭所有的进程。导致服务可能是被关闭了又重新启动。这样用上面方法跳转就不稳定了。有时候跳的过去,有时候跳不过去了。所以最好是将监听服务另起,以后不能用system.exit(0)退出。这就是坑啊!统一写一个activity管理内进行finish退出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐