Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android http文件上傳-本地+服務器一條龍分析

Android http文件上傳-本地+服務器一條龍分析

編輯:關於Android編程

本地:

先看下項目結構

\

MainActivity.java<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush: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的時候顯示dialog if (!dialog.isShowing()) { Log.i("process", "show"); dialog.show(); } else { if (msg.arg1 == 100) {// 提示用戶上傳完成 dialog.dismiss(); toast("上傳完成!"); } } }; }; @Override protected 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(); } @Override public 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方法的參數值設為true
		con.setDoInput(true);
		//上傳需要將setDoOutput方法的參數值設為true
		con.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();
	}

	@Override
	public 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;
	}

	@Override
	public 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來接收文件流,然後寫入磁盤就行了。

\

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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved