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?
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.
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.
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:
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
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.
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
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();
}
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) {
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With