本地:

先看下项目结构

MainActivity.java

package com.huxq.uploadexample;import java.io.File;import android.annotation.SuppressLint;import android.app.Activity;import android.app.ProgressDialog;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity implements OnUploadListener {// 服务器路径,换成自己的private String urlString = "http://192.168.1.2:8080/UploadTest/Upload";/** * 上传文件的路径 */String filePath;/** * 上传的文件名 */String fileName;ProgressDialog dialog;/** * 在读取文件流的时候,同一进度会多次回调,通过这个标记,只有在进度更新的情况下才会更新ui 节省资源 */int oldProcess;@SuppressLint("HandlerLeak")private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {Log.i("process", "process" + msg.arg1);dialog.setProgress(msg.arg1);// 第一次没有显示dialog的时候显示dialogif (!dialog.isShowing()) {Log.i("process", "show");dialog.show();} else {if (msg.arg1 == 100) {// 提示用户上传完成dialog.dismiss();toast("上传完成!");}}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initProgressDialog();}public void upLoad(View v) {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// toast("上传");String sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();filePath = sdcardPath + "/Abook/";File file = new File(filePath);// 这里我选的是Abook文件夹下第五个文件上传,得根据自己的实际情况来,否则肯定出错。fileName = file.list()[4];filePath += fileName;Log.i("file.size", "size=" + file.list().length + "filePath"+ filePath);} else {toast("没有内存卡");return;}new Thread() {public void run() {try {String response = HttpUtil.sendFile(urlString, filePath,fileName, MainActivity.this);Log.i("response", "response" + response);} catch (Exception e) {e.printStackTrace();}};}.start();}@Overridepublic void onUpload(double process) {process = process * 100;int currentProcess = (int) process;dialog.setProgress(currentProcess);// 避免重复发消息,可以把if给去掉看看会发生什么if (currentProcess > oldProcess) {Message msg = handler.obtainMessage();msg.arg1 = (int) process;handler.sendMessage(msg);}oldProcess = currentProcess;}public void initProgressDialog() {dialog = new ProgressDialog(this);dialog.setMax(100);dialog.setProgress(0);dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);dialog.setCancelable(false);dialog.setCanceledOnTouchOutside(false);dialog.setTitle("正在努力上传...");}public void toast(String text) {Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();}}
HttpUtil.java

public static String sendFile(String urlPath, String filePath,String newName,OnUploadListener listener) throws Exception {String end = "\r\n";String twoHyphens = "--";String boundary = "******";URL url = new URL(urlPath);HttpURLConnection con = (HttpURLConnection) url.openConnection();//下载需要将setDoInput方法的参数值设为truecon.setDoInput(true);//上传需要将setDoOutput方法的参数值设为truecon.setDoOutput(true);//禁止HttpURLConnection使用缓存con.setUseCaches(false);//使用POST请求,必须大写con.setRequestMethod("POST");//以下三行设置http请求头信息con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");//在模拟web页面向服务器端上传文件时,每个文件的开头需要有一个分界符,//分界符需要在http请求头中指定。boundary是任意一个字符串,一般为******con.setRequestProperty("Content-Type", "multipart/form-data;boundary="+ boundary);DataOutputStream ds = new DataOutputStream(con.getOutputStream());ds.writeBytes(twoHyphens + boundary + end);//上传文件相关信息,这些信息包括请求参数名,上传文件名,文件类型,但并不限于此ds.writeBytes("Content-Disposition: form-data; "+ "name=\"file1\";filename=\"" + newName + "\"" + end);ds.writeBytes(end);//获得文件的输入流,通过流传输文件。在这里我重写了FileInputStream,为了监听上传进度CustomFileInputStream fStream = new CustomFileInputStream(filePath);fStream.setOnUploadListener(listener);/* 设置每次写入1024bytes */int bufferSize = 1024;byte[] buffer = new byte[bufferSize];int length = -1;// 从文件读取数据至缓冲区 while ((length = fStream.read(buffer)) != -1) {//将资料写入DataOutputStream中 ds.write(buffer, 0, length);}ds.writeBytes(end);ds.writeBytes(twoHyphens + boundary + twoHyphens + end);fStream.close();ds.flush();//上传完成以后获取服务器的反馈InputStream is = con.getInputStream();int ch;StringBuffer b = new StringBuffer();while ((ch = is.read()) != -1) {b.append((char) ch);}ds.close();return b.toString();}
CustomFileInputStream.java

package com.huxq.uploadexample;import java.io.File;import java.io.FileDescriptor;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class CustomFileInputStream extends FileInputStream {private OnUploadListener listener;private int total, done;private double process;public CustomFileInputStream(File file) throws FileNotFoundException {super(file);available();}public CustomFileInputStream(FileDescriptor fd) {super(fd);available();}public CustomFileInputStream(String path) throws FileNotFoundException {super(path);available();}@Overridepublic int read(byte[] buffer, int byteOffset, int byteCount)throws IOException {done += byteCount;process = 1.0 * done / total;if (listener != null) {listener.onUpload(process);}return super.read(buffer, byteOffset, byteCount);}public void setOnUploadListener(OnUploadListener listener) {this.listener = listener;}@Overridepublic int available() {try {// 获取文件的总大小total = super.available();} catch (IOException e) {e.printStackTrace();}return total;}}
OnUploadListener.java

package com.huxq.uploadexample;public interface OnUploadListener {void onUpload(double process);}

服务器端:

服务器端通过一个servlet来接收文件流,然后写入磁盘就行了。

Android http文件上传-本地+服务器一条龙分析_第1张图片

Upload.java

package com.huxq.test;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.Iterator;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;/** * Servlet implementation class Upload */@WebServlet("/Upload")public class Upload extends HttpServlet {private static final long serialVersionUID = 1L;/** * 文件保存路径 */private final String savaPath="E:\\uploads/";/** * Default constructor. */public Upload() {}/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse *      response) */protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean isMultipart = ServletFileUpload.isMultipartContent(request);if (isMultipart) {FileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);List items;try {items = upload.parseRequest(request);Iterator iter = items.iterator();// 可以接收多个文件while (iter.hasNext()) {FileItem item = (FileItem) iter.next();if (item.isFormField()) {// 普通文本信息处理String paramName = item.getFieldName();String paramValue = item.getString();System.out.println(paramName + ":" + paramValue);} else {// 上传文件信息处理String fileName = item.getName();byte[] data = item.get();String filePath = savaPath + fileName;File file = new File(savaPath);if (!file.exists()) {file.mkdirs();}System.out.println("filePath:" + filePath);File file2 = new File(filePath);if (file2.exists())file2.delete();FileOutputStream fos = new FileOutputStream(file2);fos.write(data);fos.close();}}response.getWriter().write("UPLOAD_SUCCESS");} catch (FileUploadException e) {e.printStackTrace();response.getWriter().write("UPLOAD_FAILED");}}}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse *      response) */protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

这里需要两个jar包,分别是commons-fileupload-1.3.1.jar和commons-io-2.4.jar

所有想说的都在代码里了,如果有不清楚的可以下载下载Demo或者留言一起探讨。


更多相关文章

  1. Android 可選文件格式瀏覽器
  2. Android图片上传的工具类
  3. Android操作SD卡文件
  4. Android 之 将RAW资源文件写入SD卡工具类
  5. Android与服务器端数据交互(基于SOAP协议整合android+webservice)
  6. Android 上传文件[转]
  7. 挂载android只读文件系统为可读写
  8. android 之 读取本地json文件返回string
  9. 3.Retrofit上传头像给后端

随机推荐

  1. 2011.07.11(3)——— android xliff字符串
  2. android activity属性
  3. Android(安卓)UI设计:TextView与EditText
  4. 跟着Android官方培训课程学习,挖坑填坑记
  5. ubuntu下无法更新android sdk问题 adt更
  6. RelativeLayout用到的一些重要的属性
  7. 关于android LinearLayout的比例布局
  8. ImageView的属性android:scaleType
  9. androidx.core.widget.NestedScrollView
  10. android中的menu和子menu小结