Download a file from Server using Retrofit2

suggest change

Interface declaration for downloading a file

public interface ApiInterface {
    Call<MovieResponse> getNowPlayingMovies(@Query("api_key") String apiKey, @Query("page") int page);

    // option 1: a resource relative to your base URL
    Call<ResponseBody> downloadFileWithFixedUrl();

    // option 2: using a dynamic URL
    Call<ResponseBody> downloadFileWithDynamicUrl(@Url String fileUrl);

The option 1 is used for downloading a file from Server which is having fixed URL. and option 2 is used to pass a dynamic value as full URL to request call. This can be helpful when downloading files, which are dependent of parameters like user or time.

Setup retrofit for making api calls

public class ServiceGenerator {

    public static final String API_BASE_URL = "http://your.api-base.url/";

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()

    public static <S> S createService(Class<S> serviceClass){
        Retrofit retrofit = builder.client(;
        return retrofit.create(serviceClass);


Now, make implementation of api for downloading file from server

private void downloadFile(){
        ApiInterface apiInterface = ServiceGenerator.createService(ApiInterface.class);

        Call<ResponseBody> call = apiInterface.downloadFileWithFixedUrl();

        call.enqueue(new Callback<ResponseBody>() {
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful()){
                    boolean writtenToDisk = writeResponseBodyToDisk(response.body());

                    Log.d("File download was a success? ", String.valueOf(writtenToDisk));

            public void onFailure(Call<ResponseBody> call, Throwable t) {


And after getting response in the callback, code some standard IO for saving file to disk. Here is the code:

private boolean writeResponseBodyToDisk(ResponseBody body) {
        try {
            // todo change the file location/name according to your needs
            File futureStudioIconFile = new File(getExternalFilesDir(null) + File.separator + "Future Studio Icon.png");

            InputStream inputStream = null;
            OutputStream outputStream = null;

            try {
                byte[] fileReader = new byte[4096];

                long fileSize = body.contentLength();
                long fileSizeDownloaded = 0;

                inputStream = body.byteStream();
                outputStream = new FileOutputStream(futureStudioIconFile);

                while (true) {
                    int read =;

                    if (read == -1) {

                    outputStream.write(fileReader, 0, read);

                    fileSizeDownloaded += read;

                    Log.d("File Download: " , fileSizeDownloaded + " of " + fileSize);


                return true;
            } catch (IOException e) {
                return false;
            } finally {
                if (inputStream != null) {

                if (outputStream != null) {
        } catch (IOException e) {
            return false;

Note we have specified ResponseBody as return type, otherwise Retrofit will try to parse and convert it, which doesn’t make sense when you are downloading file.

If you want more on Retrofit stuffs, got to this link as it is very useful. [1]:

Feedback about page:

Optional: your email if you want me to get back to you:

Table Of Contents