MultiPart Upload File using Retrofit
We can upload file to server using several technique. But this one i want to demonstrate how to upload file using Retrofit. To upload file using retrofit, you need to wrap your file to TypedFile. How to do it ?
Basically TypeFile is retrieve 2 paramter in their constructor MimeType and File :
TypedFile uploadFile = new TypedFile("video/mp4", new File("/sdcard/path/to/video.mp4"))
If you want to read MimeType you can use this Utility Class.
This is code in your service interface
@Multipart
@POST("/upload/file")
Observable<String> upload(@Part("file") TypedFile file)
First you need to add annotation @Multipart to your method, and then specify @Part which is part of your multipart and what is the parameter name.
i’m using RxJava for Android, the code above is when we upload a file to server, after finished the upload it will return the url of upload file. Easy right ?
But what if you want to trap progress/percentage of your upload file. The straightforward ways to do it is by extend the TypedFile and inject a listener to list while the file write into Stream.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import retrofit.mime.TypedFile;
public class ProgressedTypedFile extends TypedFile {
private static final int BUFFER_SIZE = 4096;
Listener listener;
long totalSize = 0;
public ProgressedTypedFile(String mimeType, File file, Listener listener) {
super(mimeType, file);
this.listener = listener;
totalSize = file.length();
}
@Override
public void writeTo(OutputStream out) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
FileInputStream in = new FileInputStream(super.file());
long total = 0;
try {
int read;
while ((read = in.read(buffer)) != -1 && !listener.isCanceled()) {
total += read;
int percentage = (int) ((total / (float) totalSize) * 100);
out.write(buffer, 0, read);
this.listener.onUpdateProgress(percentage);
}
} finally {
in.close();
}
}
public interface Listener {
void onUpdateProgress(int percentage);
}
}
as you can see, while it write the file to stream, it will listen using an interface progress of your file write. And how to implement it :
This is code in your service interface
@Multipart
@POST("/upload/file")
Observable<String> upload(@Part("file") ProgressedTypedFile file)
This code for implement the ProgressTypedFile :
ProgressedTypedFile.Listener listener = new ProgressedTypedFile.Listener() {
@Override
void onUpdateProgress(int percentage) {
Log.v("update", "progress update " + percentage);
}
};
ProgressedTypedFile uploadFile = new ProgressedTypedFile("video/mp4", new File("/sdcard/path/to/video.mp4"), listener);
And this how to use it in your service :
service.upload(uploadFile).subscribe(url -> Log.e("Result", "url"));