【发布时间】:2021-11-24 07:26:58
【问题描述】:
我知道有很多类似的主题,但它们要么已经过时,要么不适用于 pdf。
我的问题是,如何从 Cloud Firestore 下载 pdf 并将其保存到内部存储中?我的常规方法是使用下载管理器并将 pdf 保存到外部存储中,但是由于范围存储,这不再起作用,我需要找到一种新方法。
目前,我只知道如何创建一个临时文件并将 pdf 从 firestore 下载到这个临时文件中,但不知道如何保存。
旧方法(使用下载管理器)
class PDFDownloader(private val context: Context) {
private val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
private val downloadDirectory = Environment.DIRECTORY_DOCUMENTS
private val authority = "${BuildConfig.APPLICATION_ID}.fileprovider"
private val pdfIntent = Intent(Intent.ACTION_VIEW).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
// DOWNLOADING THE PDF INTO EXTERNAL STORAGE
suspend fun downloadPDF(pdfUri: String, fileName: String) {
val pdfUrl = Firebase.storage.getReferenceFromUrl(pdfUri).downloadUrl.await()
// NOT WORKING ANYMORE BECAUSE OF SCOPED STORAGE
val request = DownloadManager.Request(pdfUrl)
.setTitle(fileName)
.setDestinationInExternalFilesDir(context, downloadDirectory, "$fileName.pdf")
downloadManager.enqueue(request)
}
// RETRIEVING THE PDF FROM EXTERNAL STORAGE
suspend fun getPDFFileAndOpen(fileName: String) {
val regex = "$fileName.pdf"
withContext(Dispatchers.IO) {
val fileList = context.getExternalFilesDir(downloadDirectory)?.listFiles()
val file = fileList?.find { it.name == regex }
pdfIntent.setDataAndType(FileProvider.getUriForFile(context, authority, file), "application/pdf")
context.startActivity(intent)
}
}
}
新方法(不带下载管理器)
class PDFDownloaderWithoutManager(private val context: Context) {
override suspend fun downloadPDF(uri: StorageReference, fileName: String) {
withContext(Dispatchers.IO) {
// Step 1: Creating a temporary file
val tempFile = File(context.filesDir, "$fileName.pdf")
// Step 2: Downloading the pdf from cloud-firestore into tempFile
uri.getFile(tempFile).await()
// Step 3: Saving the file into internal storage
// OR SAVING INTO EXTERNAL STORAGE WITH SCOPED STORAGE
// (I take whats easier)
?????????????????????????????????????????????????????
}
}
}
// RETRIEVING THE PDF FROM INTERNAL STORAGE
suspend fun getPDFFileAndOpen(fileName: String) {
val regex = "$fileName.pdf"
????????????????????????????????????????????????????????????
}
还有一个方法uri.getFile("URI TO SAVE FILE TO),不过我也不知道怎么用。
编辑
使用下载管理器按预期工作,它成功地从 firestore 下载文件 (yay)。我唯一的问题是,我无法在 android 11 上打开 pdf。我收到以下错误:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://com.example.app.fileprovider/external_files/Documents/Kalibrierung und Überprüfung.pdf typ=application/pdf flg=0x10000001 }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2067)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727)
at android.app.ContextImpl.startActivity(ContextImpl.java:1023)
at android.app.ContextImpl.startActivity(ContextImpl.java:994)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:403)
at com.example.app.business.domain.validator.document.FileLegacyValidator.openPdf(FileLegacyValidator.kt:38)
at com.example.app.business.domain.validator.document.FileLegacyValidator.openPDFFileOrNull(FileLegacyValidator.kt:35)
at com.example.app.presentation.documents.DocumentViewModel$setStateEvent$1$1.invokeSuspend(DocumentViewModel.kt:36)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
这不起作用:context.startActivity(intent)
【问题讨论】:
-
您可以像以前一样继续使用DownloadManager。
-
该异常与使用 DownloadManager 无关。我想知道您为什么首先从该目录中列出。在您知道文件名和目录的地方不需要。
-
@blackapps 是的,我知道,我更改了问题和标题。如何修复异常?
-
你应该意识到这不是 FileNotFoundException 而是一个 ActivityNotFoundException。
-
@blackapps 抱歉,我不明白你要我说什么。我可以自己阅读异常,我的问题是:当在 android 10 及更低版本中一切正常时,如何解决“ActivityNotFoundException”??
标签: android firebase google-cloud-firestore android-file scoped-storage