android中的文件(圖片)上傳其實沒什麼複雜的,主要是對 multipart/form data 協議要有所瞭解。 關於 multipart/form data 協議,在 RFC文檔中有詳細的描述 [RFC 2388 Returning Values from Forms: multipart/
android中的文件(圖片)上傳其實沒什麼複雜的,主要是對 multipart/form-data 協議要有所瞭解。
關於 multipart/form-data 協議,在 RFC文檔中有詳細的描述 RFC 2388 - Returning Values from Forms: multipart/form-data
大家有興趣的話可以去看看,這裡有一篇非常好的文章進行了介紹:Http協議中的數據傳送之多重表單提交--multipart/form-data
那麼在Android中如何實現呢?這裡寫了一個簡單的工具類,供大家使用
UploadUtil
package com.atwal.util;
import android.util.Log;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;
/**
* Created by atwal on 2016/3/11.
*/
public class UploadUtil {
private static final String TAG = "uploadFile";
private static final int TIME_OUT = 10 * 1000; //超時時間
private static final String CHARSET = "utf-8";
private static final String BOUNDARY = UUID.randomUUID().toString(); //邊界標識隨機生成
private static final String PREFIX = "--";
private static final String LINE_END = "\r\n";
private static final String CONTENT_TYPE = "multipart/form-data"; //內容類型
/**
* 上傳文件
* @param file 文件
* @param RequestURL post地址
* @param params 除文件外其他參數
* @param uploadFieldName 上傳文件key
* @return
*/
public static String uploadFile(File file, String RequestURL, Map<String, String> params, String uploadFieldName) {
String result = null;
try {
URL url = new URL(RequestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(TIME_OUT);
conn.setConnectTimeout(TIME_OUT);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Charset", CHARSET);
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
StringBuffer sb = new StringBuffer();
sb.append(getRequestData(params));
if (file != null) {
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);
sb.append("Content-Disposition: form-data; name=\"" + uploadFieldName + "\"; filename=\"" + file.getName() + "\"" + LINE_END);
sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
sb.append(LINE_END);
}
dos.write(sb.toString().getBytes());
if (file != null) {
InputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = is.read(bytes)) != -1) {
dos.write(bytes, 0, len);
}
is.close();
dos.write(LINE_END.getBytes());
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
dos.write(end_data);
}
dos.flush();
int res = conn.getResponseCode();
Log.e(TAG, "response code:" + res);
if (res == 200) {
Log.e(TAG, "request success");
InputStream input = conn.getInputStream();
StringBuffer sb1 = new StringBuffer();
int ss;
while ((ss = input.read()) != -1) {
sb1.append((char) ss);
}
result = sb1.toString();
Log.i(TAG, "result : " + result);
} else {
Log.e(TAG, "request error");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 對post參數進行編碼處理
* @param params post參數
* @return
*/
private static StringBuffer getRequestData(Map<String, String> params) {
StringBuffer stringBuffer = new StringBuffer();
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
stringBuffer.append(PREFIX);
stringBuffer.append(BOUNDARY);
stringBuffer.append(LINE_END);
stringBuffer.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINE_END);
stringBuffer.append(LINE_END);
stringBuffer.append(URLEncoder.encode(entry.getValue(), CHARSET));
stringBuffer.append(LINE_END);
}
} catch (Exception e) {
e.printStackTrace();
}
return stringBuffer;
}
}
代碼比較簡單,就不細說了,主要就是把參數及文件按協議進行拼接。
註:本類代碼參考了android上傳文件到伺服器 一文,做了優化修改
調用
調用代碼比較簡單,這裡需要註意的是,文件上傳是一個網路操作,要另開線程處理。另外要給應用網路和SD卡讀寫許可權。
String requestURL = "伺服器地址";
String picPath = "圖片地址";
File file = new File(picPath);
Log.i("upload", "file exists:" + file.exists());
if (file.exists()) {
Map<String, String> params = new HashMap<>();
params.put("id", "1");
//...如果有其他參數添加到這裡
String request = UploadUtil.uploadFile(file, requestURL, params, "image");
Log.i("upload", request);
}
當然,此工具類對異常信息並未處理,大家可根據自己的情況進行優化。