【问题标题】:Downloading PDF from app is not working on Android 11从应用程序下载 PDF 不适用于 Android 11
【发布时间】:2021-12-06 11:26:50
【问题描述】:

我想在我的应用程序中下载 PDF 并在 PDF 查看器中显示它。我没有使用临时文件,因为我不想使用随机文件名(在某些设备上它会导致“文件名太长”错误)。它在除 Android 11 之外的所有设备上都能完美运行。(我什至不需要在应用设置中打开存储权限即可下载该 PDF)。但以防万一我的清单中有 uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 和 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

导致此错误:

open failed: EACCES (Permission denied) Can't open file

这是用于将数据下载并解析到我的 PDF 的代码:

val dlg = Dialog(a).apply {
            setMessage(R.string.downloading)
            setNegativeButton {
                downloadTask?.cancel()
            }
            show()
        }
        downloadTask = asyncTask({
            try {
                val dir = app.externalCacheDir!!
                dir.mkdirs()
                File(dir, "client-invoice.pdf").also { f ->
                    f.deleteOnExit()
                    URL(receiptUrl).openStream().use { s ->
                        FileOutputStream(f).use { d ->
                            s.copyTo(d)
                        }
                    }
                }
            } catch (e: IOException) {
                e
            }
        }, onDone = {
            downloadTask = null
            dlg.dismiss()
        }){ r->
            try {
                if (r is Exception) {
                    throw r
                } else if (r is File) {
                    tempFile = r
                    val int = Intent(Intent.ACTION_VIEW).apply {
                        setDataAndType(Uri.parse("file://" + r.absolutePath), "application/pdf")
                    }
                    startActivityForResult(int, 1)
                }
            } catch (e: ActivityNotFoundException) {
                tempFile?.delete()
                a.openPlayStoreLinkWithDialog("com.google.android.apps.pdfviewer", "PDF")
            } catch (e: Exception) {
                app.showToast(e.message?:"")
            }
        }

【问题讨论】:

  • 你试过在清单文件中使用android:preserveLegacyExternalStorage="true"标签吗?
  • 是的,但它也不起作用。
  • 下载只需要互联网权限。创建文件或文件夹需要存储权限。看起来您在创建文件时遇到了问题。
  • 只有在目录不存在时才调用 mkdirs。如果你调用它然后检查返回值。如果为 false 则停止,因为尝试在不存在的目录中创建文件是没有意义的。
  • 请告诉目录的完整路径。 Can't open file 那么是哪个文件呢?

标签: android android-permissions android-file


【解决方案1】:

file 作为Uri 方案自 Android 7.0 以来已被有效禁止。你应该会因为FileUriExposedException 而崩溃。使用 FileProvidergetUriForFile() 使您的内容可供其他应用使用,因为它们无法访问外部存储上您应用的应用特定位置中的文件。

然后,您可以摆脱为通过FileUriExposedException 而应用的任何黑客攻击。

【讨论】:

    猜你喜欢
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多