android.content.ActivityNotFoundException:在 android 11 上打开 pdf 时找不到处理 Intent 的活动
Posted
技术标签:
【中文标题】android.content.ActivityNotFoundException:在 android 11 上打开 pdf 时找不到处理 Intent 的活动【英文标题】:android.content.ActivityNotFoundException: No Activity found to handle Intent when opening pdf at android 11 【发布时间】: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”?? 【参考方案1】:编辑:在您对问题的最新编辑后回答不相关。
如果您要使用外部存储,请按以下步骤操作:
val isExternalStorageWritable =
(Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED)
if (!isExternalStorageWritable )
// handle error: Storage not available
return
val rootFolder = context.getExternalFilesDir(null)
val downloadsFolder = File(rootFolder, "downloads")
val isDownloadsFolderCreated = downloadsFolder.mkdirs()
if (!isDownloadsFolderCreated)
// handle error: unable to create folder
return
val tempInputStream = FileInputStream(tempFile)
val targetFile = File(downloadsFolder, "targetFileName.pdf")
val isTargetFileCreated = targetFile.createNewFile()
if (!isTargetFileCreated)
// handle error: unable to create file
return
FileOutputStream(targetFile).use outputStream ->
tempInputStream.copyTo(outputStream)
确保从后台线程或 IO 协程调用它。
【讨论】:
【参考方案2】:我已经解决了这个问题。我一直以为我的模拟器已经安装了 PDF 阅读器(因为其他模拟器也有),但事实并非如此。无法打开活动,因为没有 PDF 阅读器。
修复:安装 PDF 阅读器。
【讨论】:
ActivityNotFoundException.以上是关于android.content.ActivityNotFoundException:在 android 11 上打开 pdf 时找不到处理 Intent 的活动的主要内容,如果未能解决你的问题,请参考以下文章