提取apk文件 (三)
上两篇介绍了读取apk信息和保存apk文件到sdcard中。
这一篇再来讲讲如何能同步到PC或者其他的设备。
思来想去还是觉得http方式比较简单。在手机上开启http服务器(web server)。
在浏览器里输入网址就能得到地址了。PC端就不需要什么客户端了。麻烦。
闲话少说,先建个简单的http server。如果需要一个完整的微型http server可以参考http://elonen.iki.fi/code/nanohttpd/
public class HttpServer {
private ServerSocket server;
public void start(int port) {
//创建serversocket服务器
try {
server = new ServerSocket(port);
//等待http请求,有请求交给HttpThread去处理
while (true)
new HttpThread(server.accept()).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void stop(){
if(server!=null){
try {
server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
原理很简单,就不多说了。其实就是建立个ServerSocket然后等待客户端发请求,处理这些请求。
这些请求按照http协议的内容规范就是了。
下面在完成一个简单的http请求处理。
public class HttpThread extends Thread{
private Socket waiter;
public HttpThread(Socket accept) {
// TODO Auto-generated constructor stub
//小二来了
waiter=accept;
}
public void run(){
process();
}
private void process() {
// TODO Auto-generated method stub
//step1 获取 请求内容 小二 来两个包子
doRequest();
//step2 给与 回应内容
doResponse();
}
基本上就是这样一个思路。小二(waiter)获取请求的内容,分析下,把内容回应给浏览器就行啦。
下面的才真正是http协议处理的内容。
//先做简单的处理
if(query!=null){
try {
OutputStream out = waiter.getOutputStream();
DataOutputStream dos=new DataOutputStream(out);
if(query.equals("/")){
dos.writeBytes("HTTP/1.0 200 \r\n");
dos.writeBytes("\r\n");
dos.writeBytes("welcome to Android http server");
}else if(query.endsWith(".apk")){
dos.writeBytes("HTTP/1.0 200 \r\n");
dos.writeBytes("\r\n");
dos.writeBytes(query);
}
out.flush();
waiter.shutdownOutput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void doRequest() {
// TODO Auto-generated method stub
BufferedReader br=null;
try {
br = new BufferedReader(new InputStreamReader(waiter.getInputStream()));
String firstline=br.readLine();
if(firstline!=null){
String[] str = firstline.split(" ");
query=str[1];
System.out.println(""+new Date()+" "+query);
}
waiter.shutdownInput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
参看了网上的一些资料,目前的处理比较简单粗暴。估计会有不少的bug。
控制台输出结果
Sat Mar 17 22:56:44 CST 2012 /1.apk
Sat Mar 17 22:56:47 CST 2012 /favicon.ico
下一步的核心就是完成request的hanler设计了。目前是紧密的耦合在一起,显然不利于扩展。
if(query.equals("/")){
dos.writeBytes("HTTP/1.0 200 \r\n");
dos.writeBytes("\r\n");
dos.writeBytes("welcome to Android http server");
}else if(query.endsWith(".apk")){
dos.writeBytes("HTTP/1.0 200 \r\n");
dos.writeBytes("\r\n");
dos.writeBytes(query);
}
}
因为针对不同的query需要做出不同的输出,比如输出文件还是输出应用列表。显然放在httpthread类里面处理很不合适。
今天先到这里。明天继续写这篇。