Skip to content

Instantly share code, notes, and snippets.

@avirias
Created February 22, 2022 17:15
Show Gist options
  • Save avirias/83695130257840f2599e694a2befc2a6 to your computer and use it in GitHub Desktop.
Save avirias/83695130257840f2599e694a2befc2a6 to your computer and use it in GitHub Desktop.
Download anything with work manager
class DownloadWorker(
private val context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
private val urlString: String? = inputData.getString("urlFile")
private val fileName: String? = inputData.getString("fileName")
override suspend fun doWork(): Result {
urlString ?: return Result.failure()
val notificationBuilder = NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle("Downloading")
.setContentText("0%")
.setSmallIcon(R.mipmap.ic_launcher)
val notificationManager = NotificationManagerCompat.from(context)
setForeground(
ForegroundInfo(
12, notificationBuilder
.setProgress(100, 0, false)
.build()
)
)
val result = download(urlString) {
val progress = workDataOf(Progress to it)
setProgress(progress)
notificationManager.notify(12,
notificationBuilder
.setProgress(100, it.toInt(), false)
.setContentText("${it.toInt()}%")
.build())
}
return if (result.isSuccess) {
val file = File(context.filesDir, fileName ?: "file-${Date().time}.jpg")
withContext(Dispatchers.IO) {
file.writeBytes(result.getOrThrow())
}
val output = workDataOf(Output to file.absolutePath)
Result.success(output)
} else Result.retry()
}
companion object {
const val Progress = "progress"
const val Output = "output"
}
private suspend fun download(
url: String,
progress: suspend (Double) -> Unit = {}
): kotlin.Result<ByteArray> {
return kotlin.runCatching {
val ktor = HttpClient(Android)
val response = ktor.get<HttpStatement> {
url(url)
onDownload { bytesSentTotal, contentLength ->
val l = bytesSentTotal.toDouble() / contentLength.toDouble()
progress(l * 100)
}
}.execute()
response.readBytes()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment