问题描述
在引入范围存储之前,我曾使用Download Manager在我的应用程序中下载pdf并从getExternalStorageDirectory
获取pdf,但是由于范围存储,我已不再使用getExternalStorageDirectory
,因为它已被弃用.我决定不使用Download Manager,而是下载公共目录中的文件,而改用pdf文件下载.我知道我可以在Android Manifest中使用requiredLegacyStorage
标记,但是它不适用于Android 11,因此我没有使用它.
Before the introduction of scoped storage i was using Download Manager to download pdf in my app and get the pdf from getExternalStorageDirectory
, but due to scoped storage i can no longer use getExternalStorageDirectory
as it is deprecated. I decided to move away from Download Manager as well as it downloads files in public directory and instead use retrofit to download pdf file.I know i can use the requiredLegacyStorage
tag in Android Manifest but it wont be applicable to Android 11 so i am not using that.
这是我的代码
fun readAndDownloadFile(context: Context) {
readQuraanInterface?.downloadFile()
Coroutines.io {
file = File(context.filesDir,"$DESTINATION_DIRECTORY/$FILE_NAME$FILE_EXTENSION")
if (file?.exists() == true) {
renderPDF()
showPdf(mPageIndex, Direction.None)
} else {
Log.i("new","new0")
val response = readQuraanRepository.downloadPdf()
if (response.isSuccessful) {
Log.i("new","new00 ${file!!.path} ${response.body()?.byteStream().toString()}")
response.body()?.byteStream()?.let {
file!!.copyInputStreamToFile(
it
)
}
Log.i("new","new1")
// renderPDF()
// showPdf(mPageIndex, Direction.None)
} else {
Log.i("new","new2")
Coroutines.main {
response.errorBody()?.string()
?.let { readQuraanInterface?.downloadFailed(it) }
}
}
}
}
}
private fun File.copyInputStreamToFile(inputStream: InputStream) {
this.outputStream().use { fileOut ->
Log.i("new","new30")
inputStream.copyTo(fileOut)
}
}
尽管下载了pdf id,但从未使用我编写的InputStream helper函数存储文件.我需要将该pdf添加到我的应用程序的内部存储中,并使用PDFRenderer对其进行渲染.
Though the pdf id downloaded but the file is never stored using InputStream helper function which i have written. I need to add that pdf to my app's internal storage as well as render it which i am rendering using PDFRenderer.
推荐答案
您可以使用以下代码使用范围存储来下载和保存PDF.在这里,我使用的是下载目录.不要忘记提供必需的权限.
You can use below code to download and save PDF using scoped storage. Here I am using Downloads directory. Don't forget to give required permissions.
@RequiresApi(Build.VERSION_CODES.Q)
fun downloadPdfWithMediaStore() {
CoroutineScope(Dispatchers.IO).launch {
try {
val url =
URL("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
val connection: HttpURLConnection = url.openConnection() as HttpURLConnection
connection.requestMethod = "GET"
connection.doOutput = true
connection.connect()
val pdfInputStream: InputStream = connection.inputStream
val values = ContentValues().apply {
put(MediaStore.Downloads.DISPLAY_NAME, "test")
put(MediaStore.Downloads.MIME_TYPE, "application/pdf")
put(MediaStore.Downloads.IS_PENDING, 1)
}
val resolver = context.contentResolver
val collection =
MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val itemUri = resolver.insert(collection, values)
if (itemUri != null) {
resolver.openFileDescriptor(itemUri, "w").use { parcelFileDescriptor ->
ParcelFileDescriptor.AutoCloseOutputStream(parcelFileDescriptor)
.write(pdfInputStream.readBytes())
}
values.clear()
values.put(MediaStore.Downloads.IS_PENDING, 0)
resolver.update(itemUri, values, null, null)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
这篇关于如何在范围存储中保存pdf?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!