Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to download file in Android using Retrofit library?

I need to download all types of file (binary, image, text, etc) using Retrofit library in my app. All the examples on the net is using HTML GET method. I need to use POST to prevent automatic caching.

My question is how to download a file using POST method in Retrofit?

like image 227
Ehsan Avatar asked Oct 01 '15 02:10

Ehsan


People also ask

What is the use of Retrofit library in Android?

Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.

Is Retrofit a library Android?

Retrofit is a type-safe HTTP networking library used for Android and Java. Retrofit was even better since it was super fast, offered better functionality, and even simpler syntax. Most developers since then have switched to using Retrofit to make API requests.


3 Answers

In kotlin, Do this:

In your service add method:

    @Streaming
    @GET
    suspend fun downloadFile(@Url fileUrl:String): Response<ResponseBody>

To call this method, from ViewModel:

viewModelScope.launch {
     val responseBody=yourServiceInstance.downloadFile(url).body()
     saveFile(responseBody,pathWhereYouWantToSaveFile)
}

To save file:

fun saveFile(body: ResponseBody?, pathWhereYouWantToSaveFile: String):String{
        if (body==null)
            return ""
        var input: InputStream? = null
        try {
            input = body.byteStream()
            //val file = File(getCacheDir(), "cacheFileAppeal.srl")
            val fos = FileOutputStream(pathWhereYouWantToSaveFile)
            fos.use { output ->
                val buffer = ByteArray(4 * 1024) // or other buffer size
                var read: Int
                while (input.read(buffer).also { read = it } != -1) {
                    output.write(buffer, 0, read)
                }
                output.flush()
            }
            return pathWhereYouWantToSaveFile
        }catch (e:Exception){
            Log.e("saveFile",e.toString())
        }
        finally {
            input?.close()
        }
        return ""
    }

Note:

  1. Make sure your refrofit client's base url and the url passed to downloadFile makes valid file url:

Retrofit's Base url + downloadFile's method url = File url

  1. Here I am using suspend keyword before downloadFile to call this from ViewModel, I have used viewModelScope.launch {} you can use different coroutine scope according to your caller end.

  2. Now pathWhereYouWantToSaveFile, If you want to store file into project's file directory, you can do this:

val fileName=url.substring(url.lastIndexOf("/")+1)
val pathWhereYouWantToSaveFile = myApplication.filesDir.absolutePath+fileName
  1. If you are storing the downloaded file under file or cache directory, you don't need to acquire permission, otherwise for public storage, you know the process.
like image 110
Suraj Vaishnav Avatar answered Oct 16 '22 09:10

Suraj Vaishnav


Use @Streaming

Asynchronous

EDIT 1

//On your api interface
@POST("path/to/your/resource")
@Streaming
void apiRequest(Callback<POJO> callback);

restAdapter.apiRequest(new Callback<POJO>() {
        @Override
        public void success(POJO pojo, Response response) {
            try {
                //you can now get your file in the InputStream
                InputStream is = response.getBody().in();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void failure(RetrofitError error) {

        }
    });

Synchronous

//On your api interface
@POST("path/to/your/resource")
@Streaming
Response apiRequest();

Response response = restAdapter.apiRequest();

try {
    //you can now get your file in the InputStream
    InputStream is = response.getBody().in();
} catch (IOException e) {
    e.printStackTrace();
}
like image 37
NaviRamyle Avatar answered Oct 16 '22 11:10

NaviRamyle


This is How to DOWNLOAD file in Retrofit 2

public interface ServerAPI {
        @GET
        Call<ResponseBody> downlload(@Url String fileUrl);

        Retrofit retrofit =
                new Retrofit.Builder()
                        .baseUrl("http://192.168.43.135/retro/") // REMEMBER TO END with /
                        .addConverterFactory(GsonConverterFactory.create())
                 .build();

}

    //How To Call
public void download(){
        ServerAPI api = ServerAPI.retrofit.create(ServerAPI.class);
        api.downlload("http://192.168.43.135/retro/pic.jpg").enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        try {
                            File path = Environment.getExternalStorageDirectory();
                            File file = new File(path, "file_name.jpg");
                            FileOutputStream fileOutputStream = new FileOutputStream(file);
                            IOUtils.write(response.body().bytes(), fileOutputStream);
                        }
                        catch (Exception ex){
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                    }
                });
}
like image 12
ugali soft Avatar answered Oct 16 '22 09:10

ugali soft