Ktorで、ファイルのダウンロードでプログレスを表示する


Ktorで、ダウンロード

ktorの導入は、下記を参照してください。

Ktorで、ダウンロードする際にプログレスを表示したいと思ったのですが、公式サイトに記載されてる内容が動作しなかったので、実際に動作する実装を記載します。

KtorのonDownloadを使う

onDownloadを使う場合、callbackFlowで受信する必要があります。
callbackFlowを使用する場合、callbackFlowをクローズする際にonDownloadを初期化する必要がありますので、awaitCloseで初期化します。

    suspend fun downloadFile(url: String, context: Context): Flow<DownloadFileResult> = callbackFlow {
            val httpClient = HttpClient(OkHttp) {
            }
            val httpRequestBuilder = HttpRequestBuilder().apply {
                url(url)
                onDownload { bytesSentTotal, contentLength ->
                    val progress = (bytesSentTotal * 100f / contentLength).roundToInt()
                    trySend(DownloadFileResult.Progress(progress))
                }
            }

            try {
                httpClient.apply {
                    val httpResponse = get<HttpResponse>(httpRequestBuilder)
                    val responseBody: ByteArray = httpResponse.receive()

                    val file = File(context.cacheDir, "file")
                    file.writeBytes(responseBody)

                    trySend(DownloadFileResult.Success("ok"))
                }
            } catch (e: Exception) {
                trySend(DownloadFileResult.Failure(e.message))
            }
            awaitClose {
                httpRequestBuilder.onDownload(null)
            }
        }
sealed class DownloadFileResult {

    data class Progress(val progress: Int) : DownloadFileResult()
    data class Success(val result: String) : DownloadFileResult()
    data class Failure(val errorMessage: String) : DownloadFileResult()
}

KtorのonDownloadで簡単にプログレスを表示したかったけど、公式サイトのonDownloadだと機能しなかったので、こちらで試してみてください。