Android 11 从应用程序下载 PDF 无效
Downloading PDF from app is not working on Android 11
我想在我的应用程序中下载 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?:"")
}
}
file
作为 Uri
方案实际上已从 Android 7.0 开始被禁止。你应该崩溃 FileUriExposedException
。使用 FileProvider
和 getUriForFile()
让其他应用可以访问您的内容,因为它们无法访问您应用在外部存储上的应用特定位置中的文件。
然后,您可以摆脱为通过 FileUriExposedException
.
而应用的任何 hack
我想在我的应用程序中下载 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?:"")
}
}
file
作为 Uri
方案实际上已从 Android 7.0 开始被禁止。你应该崩溃 FileUriExposedException
。使用 FileProvider
和 getUriForFile()
让其他应用可以访问您的内容,因为它们无法访问您应用在外部存储上的应用特定位置中的文件。
然后,您可以摆脱为通过 FileUriExposedException
.