package com.zulip.android.networking;
import android.os.Handler;
import android.os.Looper;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.BufferedSink;
/**
* Decorated retrofit RequestBody to intercept progress during network call.
* Implement UploadCallbacks interface {@link UploadCallbacks} to receive progress update.
*/
public class UploadProgressRequest extends RequestBody {
private static final int DEFAULT_BUFFER_SIZE = 2048;
private File mFile;
private UploadCallbacks mListener;
private int mNotificationId;
public UploadProgressRequest(final File file, final UploadCallbacks listener, int notificationId) {
mFile = file;
mListener = listener;
mNotificationId = notificationId;
}
@Override
public MediaType contentType() {
return MediaType.parse("multipart/form-data");
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
long fileLength = mFile.length();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
FileInputStream in = new FileInputStream(mFile);
long uploaded = 0;
try {
int read;
Handler handler = new Handler(Looper.getMainLooper());
while ((read = in.read(buffer)) != -1) {
uploaded += read;
sink.write(buffer, 0, read);
// update progress on UI thread only
handler.post(new ProgressUpdater(uploaded, fileLength));
}
} finally {
in.close();
}
}
public interface UploadCallbacks {
void onProgressUpdate(int percentage, String progress, int notificationId);
}
private class ProgressUpdater implements Runnable {
private long mUploaded;
private long mTotal;
public ProgressUpdater(long uploaded, long total) {
mUploaded = uploaded;
mTotal = total;
}
@Override
public void run() {
double currentProgress = Math.round((mUploaded / Math.pow(1024, 2)) * 100) / 100.0;
double totalProgress = Math.round((mTotal / Math.pow(1024, 2)) * 100) / 100.0;
String progress = currentProgress + " MB"
+ " / " + totalProgress + " MB";
mListener.onProgressUpdate((int) (100 * mUploaded / mTotal), progress, mNotificationId);
}
}
}