I am trying to send a file to server using Multipart. This is how I am sending the request
MultipartRequest request = new MultipartRequest(putURLPath,
hashMap,
null,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
Log.d(TAG, "FILE_UPLOAD_RESPONSE: " + response);
Logger.writeToFile(TAG, "FILE_UPLOAD_RESPONSE: " + response);
if (fileUploadListener != null)
fileUploadListener.onAttachmentFileUpload(generateImageUploadResponse(false, getURLPath), message, isRetry);
// fileDownload(getURLPath);
} catch (Exception e) {
e.printStackTrace();
if (fileUploadListener != null)
fileUploadListener.onAttachmentFileUpload(generateImageUploadResponse(true, ""), message, isRetry);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Logger.writeToFile(TAG, "FILE_UPLOAD_RESPONSE--Error: " + error.getMessage());
/* byte[] bytes = ((NetworkResponse)((AuthFailureError)error).networkResponse).data;
WAAFILogger.d(TAG, "XML: " + bytes.);*/
if (fileUploadListener != null)
fileUploadListener.onAttachmentFileUpload(generateImageUploadResponse(true, ""), message, isRetry);
error.printStackTrace();
}
}, new IMultipartProgressListener() {
@Override
public void transferred(long transferred, int progress) {
WAAFILogger.d(TAG, "Transferred : " + transferred + "\n" + " Progress : " + progress);
try {
if (fileUploadListener != null) {
fileUploadListener.onProgressChanged(message, progress);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, bytesArray) {
@Override
public String getBodyContentType() {
return fileInfo.fileMimeType;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("content-length", String.valueOf(bytesArray.length));
params.put("host", IMConstant.XMPP_SERVER + ":9000");
Logger.writeToFile(TAG, params.get("content-length"));
Logger.writeToFile(TAG, params.get("host"));
return params;
}
};
request.setRetryPolicy(com.safarifone.settings.Settings.policy);
VolleyQueManager.getInstance().addToRequestQueue(request);
I have used a custom request and the link is here Custom Request Repo Link and the code is below
public class MultipartRequest extends Request<String> {
private final byte[] byteArray;
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
// CounterHttpEntity httpentity;
HttpEntity httpentity;
// CountingHttpEntity httpentity;
private FileUploadManager.IMultipartProgressListener mProgressListener;
private final Response.Listener<String> mListener;
private HashMap<String, File> mFiles;
private HashMap<String, String> mBody;
private long fileLength = 0L;
public MultipartRequest(String url,
HashMap<String, File> mFiles,
HashMap<String, String> body,
Response.Listener<String> listener,
Response.ErrorListener errorListener,
FileUploadManager.IMultipartProgressListener progressListener, byte[] bytesArray) {
super(Method.PUT, url, errorListener);
this.mListener = listener;
this.mFiles = mFiles;
this.mBody = body;
this.fileLength = /*getFileLength()*/ bytesArray.length;
this.mProgressListener = progressListener;
this.byteArray = bytesArray;
entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
try {
entity.setCharset(CharsetUtils.get("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
buildMultipartEntity();
httpentity = entity.build();
/*httpentity.setFileLength(fileLength);
httpentity.setmProgressListener(progressListener);*/
}
private void buildMultipartEntity() {
for (Map.Entry<String, File> entry : mFiles.entrySet()) {
if (entry.getValue() != null) {
entity.addPart(entry.getKey(), new FileBody(entry.getValue()));
}
}
if (mBody != null) {
for (Map.Entry<String, String> entry : mBody.entrySet()) {
if (entry.getValue() != null) {
entity.addTextBody(entry.getKey(), entry.getValue());
}
}
}
}
private int getFileLength() {
int lgth = 0;
for (Map.Entry<String, File> entry : mFiles.entrySet()) {
if (entry.getValue() != null) {
lgth += entry.getValue().length();
}
}
System.out.println("lgth = " + lgth);
return lgth;
}
@Override
public String getBodyContentType() {
return super.getBodyContentType();
/*return httpentity.getContentType().getValue();*/
}
@Override
public byte[] getBody() throws AuthFailureError {
Thread thread = new Thread() {
@Override
public void run() {
super.run();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
bos.write(byteArray, 0, byteArray.length);
httpentity.writeTo(new CountingOutputStream(bos, fileLength,
mProgressListener));
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
}
};
thread.start();
return /*bos.toByteArray()*/ byteArray;
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(jsonString,
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
public static class CountingOutputStream extends FilterOutputStream {
private final FileUploadManager.IMultipartProgressListener progressListener;
private long transferred;
private long fileLength;
private int lastProgress = 0;
public CountingOutputStream(final OutputStream out, long fileLength,
final FileUploadManager.IMultipartProgressListener listener) {
super(out);
this.fileLength = fileLength;
this.progressListener = listener;
this.transferred = 0;
}
public void write(byte[] buffer, int offset, int length) throws IOException {
out.write(buffer, offset, length);
if (progressListener != null) {
this.transferred += length;
int progress = (int) ((transferred * 1000.0f) / fileLength);
if (lastProgress != progress) {
this.progressListener.transferred(this.transferred, progress);
}
}
}
public void write(int oneByte) throws IOException {
out.write(oneByte);
if (progressListener != null) {
this.transferred++;
int progress = (int) ((transferred * 1000.0f) / fileLength);
if (lastProgress != progress) {
this.progressListener.transferred(this.transferred, progress);
}
}
}
}
}
as you can see I am calulating the progress in the function -> write of class CountingOutputStream. But the issue i am facing is that the write function calls too fast and due to this progress bar updates fast but the response of successfully file uploaded took long time even after the progress bar is completed. My guess is that write function fast therefore progress bar is updated but somehow file is not uploading that fast due to which it is still taking time after completed progress.