本文介绍了如何在范围存储中保存pdf?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在引入范围存储之前,我曾使用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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 17:42