android - 如何在kotlin协程中通过ok http从url下载pdf
问题描述
我想在 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 定义了以下与存储相关的权限: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
推荐阅读
- raspberry-pi - 创建 Raspberry Pi 的快照以保护其当前状态
- kentico-kontent - 自定义 Kentico 内容
- android - 如何在 NFC 标签中保存视频、音频?
- flutter - 如何避免在颤振中使用 setState 重建所有小部件
- python - 是否可以将用户输入从 dag 传递到气流中的子 dag?
- linux - 为什么程序会在推送指令上捕获 SIGSEGV?
- javascript - 有条件地防止 Vue 中的点击事件
- jenkins - 每次推送任何分支后如何构建 Jenkins?
- sql - 您能否将标量函数的输出与检查语句中的标量进行比较?SQL
- laravel - 如何使用 Laravel 排队上传到 s3?