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"));
 
17
Kudos
 
17
Kudos

Now read this

My Learning Target in 2015

Facing the 2015 i have write the strategy to improve my knowledge and my softskill. Source to improve that is by using online course, study, and reading some book. For online course i’m using coursera (http://coursera.org) and Harvard... Continue →