如果想把一个apk的能力对外提供,常用的方法是通过进程间通信的方式和第三方apk进行交互,但是针对web应用,这种交互方式就不太合适,但是也不是不可以解决,web应用和本地的native应用进行交互(通过javaScript,可参考android+html5+javascript 混合开发教程),本地的native在和能力提供者进行进程间通信,但是这样就比较麻烦,也不是我们今天想要讲的重点,我们今天介绍另外一种方式,将native应用作为服务端,第三方可以使用http请求进行交互,以下是集成步骤。
1. 在网上下载nanohttp.jar放在项目的libs目录下,或者使用依赖的方式也可(compile ‘org.nanohttpd:nanohttpd:2.2.0’)
2. 新建class继承NanoHTTPD,重写构造方法用于定义端口,重写server(IHTTPSession session)方法用于接受客户端的回调,在客户端进行网络请求时此方法就会被调用。
public class ClientServerHttpd extends NanoHTTPD {
private static final String TAG = "ClientServerHttpd";
private static final int PORT = 13245;
private ArrayList<File> mFiles = new ArrayList<>();
public ClientServerHttpd(ArrayList<File> files) {
super(PORT);
if (files != null && files.size() > 0) {
this.mFiles = files;
}
}
@Override
public Response serve(IHTTPSession session) {
String uri = session.getUri();
Log.d(TAG, "serve: uri:" + uri);
Response response ;
if (TextUtils.isEmpty(uri) || uri.equals("/")) {
response = operateRoot(session);
} else {
response = operateFile(session);
}
Log.d(TAG, "serve: response:" + response);
return response;
}
private Response operateRoot(IHTTPSession session) {
StringBuilder sb = new StringBuilder();
sb.append("<!DOCTYPE html><html><body>");
sb.append("<ol>");
for (int i = 0; i < mFiles.size(); i++) {
File file = mFiles.get(i);
if (file != null && file.exists()) {
sb.append("<li> <a href=\"" + file.getPath() + "\">" + file.getName() + "</a> </li>");
}
}
sb.append("<li>" + "文件个数:" + mFiles.size() + "</li>");
sb.append("</ol>");
sb.append("</body></html>\n");
Log.d(TAG, "operateRoot: "+sb.toString());
return newFixedLengthResponse(sb.toString());
}
private Response operateFile(IHTTPSession session) {
String uri = session.getUri();
File file = new File(uri);
if (!file.exists()){
return null;
}
for (int i = 0; i < mFiles.size(); i++) {
if (mFiles.get(i).getPath().equals(uri)) {
try {
FileInputStream fileInputStream = new FileInputStream(uri);
return newFixedLengthResponse(Response.Status.OK, "application/octet-stream", fileInputStream, fileInputStream.available());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return error404(session);
}
private Response error404(IHTTPSession session){
String uri = session.getUri();
StringBuilder sb = new StringBuilder();
sb.append("<!DOCTYPE html>")
.append("<html>")
.append("<body>")
.append("没有找到文件"+uri)
.append("</body>")
.append("</html>");
return newFixedLengthResponse(sb.toString());
}
}
3. 调用start方法开启客户端的服务(否则外界无法调用)
files.add(new File("sdcard/33870569245018351.jpg"));
files.add(new File("sdcard/_0ServerSendToService.txt"));
files.add(new File("sdcard/deviceId.txt"));
ClientServerHttpd clientServerHttpd = new ClientServerHttpd(files);
try {
clientServerHttpd.start();
} catch (Exception e) {
e.printStackTrace();
}
4. 在浏览器中输入:127.0.0.1:13245,即可看到网页加载文件列表了