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:
- Make sure your
refrofitclient’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
downloadFileto call this from ViewModel, I have usedviewModelScope.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
- 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.