【问题标题】:How to download pdf from url through ok http in kotlin coroutine如何在kotlin协程中通过ok http从url下载pdf
【发布时间】:2021-07-31 19:29:36
【问题描述】:

我想在 kotlin 中使用 ok HTTP 从 url 下载 pdf。我没有在协程中找到正确的解决方案是如何完成的。下载后我想存储在设备中并在 pdf 查看器中显示。当用户关闭活动时,存储文件会自动从内部存储中删除。有谁知道这是怎么做到的吗。提前致谢

class FileDownloader {

    companion object {
        private const val BUFFER_LENGTH_BYTES = 1024 * 8
        private const val HTTP_TIMEOUT = 30
    }

    private var okHttpClient: OkHttpClient

    init {
        val okHttpBuilder = okHttpClient.newBuilder()
            .connectTimeout(HTTP_TIMEOUT.toLong(), TimeUnit.SECONDS)
            .readTimeout(HTTP_TIMEOUT.toLong(), TimeUnit.SECONDS)
        this.okHttpClient = okHttpBuilder.build()
    }

    fun download(url: String, file: File): {
            val request = Request.Builder().url(url).build()
            val response = okHttpClient.newCall(request).execute()
            val body = response.body
            val responseCode = response.code
            if (responseCode >= HttpURLConnection.HTTP_OK &&
                responseCode < HttpURLConnection.HTTP_MULT_CHOICE &&
                body != null) {
                val length = body.contentLength()
                body.byteStream().apply {
                    file.outputStream().use { fileOut ->
                        var bytesCopied = 0
                        val buffer = ByteArray(BUFFER_LENGTH_BYTES)
                        var bytes = read(buffer)
                        while (bytes >= 0) {
                            fileOut.write(buffer, 0, bytes)
                            bytesCopied += bytes
                            bytes = read(buffer)
                        }
                    }
                }
            } else {
                throw IllegalArgumentException("Error occurred when do http get $url")
            }
        }
    }
}

这也不起作用,当用户关闭活动时如何使用协程并删除文件。

【问题讨论】:

    标签: android kotlin httpurlconnection okhttp kotlin-coroutines


    【解决方案1】:

    您基本上可以将文件保存到您的下载文件夹中。

    你必须做的是; 首先为你的清单文件添加读、写权限,

    Android 定义了以下与存储相关的权限:READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE 和 MANAGE_EXTERNAL_STORAGE。

    那么你应该为高于 10 的 android 版本使用内容解析器。例如

        val content = ContentValues().apply {
                    put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
                    put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
                }
    val uri = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, content)
    uri?.let {
          contentResolver.openOutputStream(uri)?.apply {
              BufferedOutputStream(this).write(bytes)
              }
          }
    

    但是如果你的android版本低于10你可以使用这个例子

     val directory = File(
                        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath
                ).apply {
                    if (!exists()) {
                        mkdir()
                    }
                }
                val file = File(directory, fileName)
                if (!file.exists()) {
                    FileOutputStream(
                            File(directory, fileName)
                    ).write(bytes)
                }
                uri = Uri.fromFile(file)
    

    有关更多信息,请查看本指南https://developer.android.com/training/data-storage

    【讨论】:

    • 我在更高版本和更低版本中运行@arneca
    • 只需像这样创建函数并检查它的版本。 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { saveFileQ(byteArray, fileName, contentResolver) } else { saveFile(byteArray, fileName) }
    • 检查@Behruz Bahromzoda 答案
    • 但它使用ktor..我不知道..使用它是否安全..? @arneca
    • 我不喜欢 ktor 的东西
    猜你喜欢
    • 2019-11-20
    • 2022-01-10
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 2018-06-08
    • 2019-05-16
    • 1970-01-01
    相关资源
    最近更新 更多