import android.text.TextUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.message.BasicHeader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
/**
* Created by ares on 15/12/14.
*/
public class UploadFileEntity implements HttpEntity {
private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
.toCharArray();
/**
* 换行符
*/
private final String NEW_LINE_STR = "\r\n";
private final String CONTENT_TYPE = "Content-Type: ";
private final String CONTENT_DISPOSITION = "Content-Disposition: ";
/**
* 文本参数和字符集
*/
private final String TYPE_TEXT_CHARSET = "text/plain; charset=UTF-8";
/**
* 字节流参数
*/
private final String TYPE_OCTET_STREAM = "application/octet-stream";
/**
* 二进制参数
*/
private final byte[] BINARY_ENCODING = "Content-Transfer-Encoding: binary\r\n\r\n".getBytes();
/**
* 文本参数
*/
private final byte[] BIT_ENCODING = "Content-Transfer-Encoding: 8bit\r\n\r\n".getBytes();
/**
* 分隔符
*/
private String mBoundary = null;
/**
* 输出流
*/
ByteArrayOutputStream mOutputStream = new ByteArrayOutputStream();
public UploadFileEntity() {
this.mBoundary = generateBoundary();
}
/**
* 生成分隔符
*
* @return
*/
private final String generateBoundary() {
final StringBuffer buf = new StringBuffer();
final Random rand = new Random();
for (int i = 0; i < 30; i++) {
buf.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
}
return buf.toString();
}
/**
* 参数开头的分隔符
*
* @throws IOException
*/
private void writeFirstBoundary() throws IOException {
mOutputStream.write(("--" + mBoundary + "\r\n").getBytes());
}
/**
* 添加文本参数
*
* @param value
*/
public void addStringPart(final String paramName, final String value) {
writeToOutputStream(paramName, value.getBytes(), TYPE_TEXT_CHARSET, BIT_ENCODING, "");
}
/**
* 将数据写入到输出流中
*
* @param rawData
* @param type
* @param encodingBytes
* @param fileName
*/
private void writeToOutputStream(String paramName, byte[] rawData, String type,
byte[] encodingBytes,
String fileName) {
try {
writeFirstBoundary();
mOutputStream.write((CONTENT_TYPE + type + NEW_LINE_STR).getBytes());
mOutputStream
.write(getContentDispositionBytes(paramName, fileName));
mOutputStream.write(encodingBytes);
mOutputStream.write(rawData);
mOutputStream.write(NEW_LINE_STR.getBytes());
} catch (final IOException e) {
e.printStackTrace();
}
}
/**
* 添加二进制参数, 例如Bitmap的字节流参数
*
* @param rawData
*/
public void addBinaryPart(String paramName, final byte[] rawData) {
writeToOutputStream(paramName, rawData, TYPE_OCTET_STREAM, BINARY_ENCODING, "no-file");
}
/**
* 添加文件参数,可以实现文件上传功能
*
* @param key
* @param file
*/
public void addFilePart(final String key, final File file) {
InputStream fin = null;
try {
fin = new FileInputStream(file);
writeFirstBoundary();
final String type = CONTENT_TYPE + TYPE_OCTET_STREAM + NEW_LINE_STR;
mOutputStream.write(getContentDispositionBytes(key, file.getName()));
mOutputStream.write(type.getBytes());
mOutputStream.write(BINARY_ENCODING);
final byte[] tmp = new byte[4096];
int len = 0;
while ((len = fin.read(tmp)) != -1) {
mOutputStream.write(tmp, 0, len);
}
mOutputStream.flush();
} catch (final IOException e) {
e.printStackTrace();
} finally {
closeSilently(fin);
}
}
private void closeSilently(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (final IOException e) {
e.printStackTrace();
}
}
private byte[] getContentDispositionBytes(String paramName, String fileName) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(CONTENT_DISPOSITION + "form-data; name=\"" + paramName + "\"");
// 文本参数没有filename参数,设置为空即可
if (!TextUtils.isEmpty(fileName)) {
stringBuilder.append("; filename=\""
+ fileName + "\"");
}
return stringBuilder.append(NEW_LINE_STR).toString().getBytes();
}
@Override
public long getContentLength() {
return mOutputStream.toByteArray().length;
}
@Override
public Header getContentType() {
return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + mBoundary);
}
@Override
public boolean isChunked() {
return false;
}
@Override
public boolean isRepeatable() {
return false;
}
@Override
public boolean isStreaming() {
return false;
}
@Override
public void writeTo(final OutputStream outstream) throws IOException {
// 参数最末尾的结束符
final String endString = "--" + mBoundary + "--\r\n";
// 写入结束符
mOutputStream.write(endString.getBytes());
//
outstream.write(mOutputStream.toByteArray());
}
@Override
public Header getContentEncoding() {
return null;
}
@Override
public void consumeContent() throws IOException,
UnsupportedOperationException {
if (isStreaming()) {
throw new UnsupportedOperationException(
"Streaming entity does not implement #consumeContent()");
}
}
@Override
public InputStream getContent() {
return new ByteArrayInputStream(mOutputStream.toByteArray());
}
}
package com.kit.reporterdd.utils.UploadFile;
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.Listener;
import com.android.volley.Response.ErrorListener;
import com.android.volley.toolbox.HttpHeaderParser;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
public class UploadFileRequest extends Request {
UploadFileEntity mMultiPartEntity = new UploadFileEntity();
Map mHeaders = new HashMap();
private final Listener mListener;
/**
Creates a new request with the given url.
*
@param url URL to fetch the string at
@param listener Listener to receive the String response
*/
UploadFileRequest(String url, Listener listener) {
this(url, listener, null);
}
/**
Creates a new POST request.
*
@param url URL to fetch the string at
@param listener Listener to receive the String response
@param errorListener Error listener, or null to ignore errors
*/
UploadFileRequest(String url, Listener listener, ErrorListener errorListener) {
super(Method.POST, url, errorListener);
mListener = listener;
}
/**
@return
*/
UploadFileEntity getMultiPartEntity() {
return mMultiPartEntity;
}
@Override
String getBodyContentType() {
return mMultiPartEntity.getContentType().getValue();
}
void addHeader(String key, String value) {
mHeaders.put(key, value);
}
@Override
Map getHeaders() throws AuthFailureError {
return mHeaders;
}
@Override
byte[] getBody() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
// multipart body
mMultiPartEntity.writeTo(bos);
} catch (IOException e) {
Log.e("", "IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
Response parseNetworkResponse(NetworkResponse response) {
String parsed = "";
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
@Override
void deliverResponse(String response) {
if (mListener != null) {
mListener.onResponse(response);
}
}
}
/**
@param account
@param bitmap
@param webUrl
@param uploadListener
*/
static void uploadImage(String account, Bitmap bitmap, String webUrl, final UploadListener uploadListener) {
UploadFileRequest uploadFileRequest = new UploadFileRequest(webUrl, new Response.Listener() {
@Override
public void onResponse(String s) {
uploadListener.uploadComplete(s);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
uploadListener.uploadFail(volleyError);
}
});
// 获取MultipartEntity对象
UploadFileEntity multipartEntity = uploadFileRequest.getMultiPartEntity();
multipartEntity.addStringPart("account", account);
// 文件参数
uploadFileRequest.setTag("uploadImage");
//加入队列
ReporterApp.getQueue().add(uploadFileRequest);
}