Я пытаюсь отправить файл на сервер, используя Multipart. Вот как я отправляю запрос
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);
Я использовал пользовательский запрос, ссылка здесь Ссылка на репо пользовательского запроса , код ниже
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);
}
}
}
}
}
как видите, я вычисляю прогресс в функции -> запись класса CountingOutputStream. Но проблема, с которой я сталкиваюсь, заключается в том, что функция записи вызывает слишком быстро, и из-за этого индикатор выполнения быстро обновляется, но ответ об успешной загрузке файла занял много времени даже после завершения индикатора выполнения. Я предполагаю, что функция записи выполняется быстро, поэтому индикатор выполнения обновляется, но каким-то образом файл загружается не так быстро, из-за чего все еще требуется время после завершения процесса.