Как сохранить PDF в хранилище с ограниченным объемом? - PullRequest
0 голосов
/ 09 мая 2020

До введения хранилища с ограниченным объемом я использовал Диспетчер загрузок для загрузки PDF-файла в свое приложение и получения PDF-файла из getExternalStorageDirectory, но из-за ограниченного хранилища я больше не могу использовать getExternalStorageDirectory, поскольку он устарел. Я решил отказаться от диспетчера загрузок, так как он загружает файлы в каталог publi c и вместо этого использовать модификацию для загрузки файла PDF. Я знаю, что могу использовать тег requiredLegacyStorage в манифесте Android, но он неприменим к Android 11, поэтому я его не использую.

Вот мой код

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 загружен, но файл никогда не сохраняется с использованием вспомогательной функции InputStream, которую я написал. Мне нужно добавить этот PDF-файл во внутреннее хранилище моего приложения, а также отрендерить его, который я визуализирую с помощью PDFRenderer.

1 Ответ

1 голос
/ 19 мая 2020

Вы можете использовать приведенный ниже код для загрузки и сохранения PDF с использованием ограниченного хранилища. Здесь я использую каталог Загрузки . Не забудьте предоставить необходимые разрешения.

@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()
        }
    }
}
...