我最近开发了一个应用程序,可以从服务器下载 pdf 并将其保存在本地存储中。 如果我不卸载该应用程序,我可以打开该文件。如果我重新安装该应用程序,我将无法打开该文件。
此外,我不需要访问其他文件夹,因为我只定位下载文件夹中的一个文件夹(将创建的文件夹)。
我尝试使用各种方法,如媒体存储或其他新方法,但无法解决问题。
fun openPdfIntent(filePath: File, context: Context) {
Log.i("Pdf", "openPdfIntent: ${filePath.absolutePath} ")
val pdfIntent = Intent(Intent.ACTION_VIEW)
val path =
FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", filePath)
pdfIntent.setDataAndType(
path,
"application/pdf"
)
pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
if (filePath.canRead()) {
Log.i("Pdf", "openPdfIntent: exists and open")
context.startActivity(pdfIntent)
} else {
pdfIntent.setDataAndType(
filePath.toUri(),
"application/pdf"
)
pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Log.i("Pdf", "openPdfIntent: Doesn't exists ")
}
} catch (e: Exception) {
Toast.makeText(context, "Please Install Pdf Viewer", Toast.LENGTH_SHORT).show()
if (filePath.exists()) {
filePath.delete()
Log.i("Pdf", "openPdfIntent: Deleted ")
}
}
}
//function to download files.
fun onDownload(
index: Int,
url: String,
unitName: String,
subjectName: String,
context: Context,
) {
viewModelScope.launch(IO) {
val kDownloader = KDownloader.create(context)
withContext(
IO
) {
this.async {
val req = kDownloader.newRequestBuilder(
url,
getFileDirectory(context).path + "/KIET PDFS/$subjectName",
"${subjectName}_${unitName}.pdf"
).build()
kDownloader.enqueue(req,
onStart = {
Log.i("Downloads", "onDownload: Started for file $unitName.pdf")
downloadStatus[index] = downloadStatus[index].copy(
downloadProgress = DownloadProgress.Running
)
},
onCompleted = {
Log.i("Downloads", "onDownload: Success for $unitName.pdf ")
downloadStatus[index] = downloadStatus[index].copy(
downloadProgress = DownloadProgress.Success
)
}, onError = {
Log.i("Downloads", "onDownload: Error $it")
downloadStatus[
index
] = downloadStatus[index].copy(
downloadProgress = DownloadProgress.Failed
)
}
)
}.await()
}
}
}
fun getFileDirectory(context: Context): File {
return if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)!!
} else {
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
}
}
Android 清单
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
文件路径.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path path="Android/data/${applicationId}/" name="files_root" />
<root-path
name="root"
path="/" />
</paths>
如果我重新安装应用程序,则无法打开该文件。
正确。您的应用程序只能访问
Download/
中的内容,此特定应用程序安装将这些文件放入 Download/
中。任何其他应用程序(包括重新安装的应用程序副本)都无法访问原始应用程序安装所放置的内容。并且您的应用程序无法访问任何其他应用程序放置在那里的文件。
这就是为什么多年来,Google 一直引导开发人员使用存储访问框架,例如
ACTION_OPEN_DOCUMENT
/ ActivityResultContracts.OpenDocument
。这些不需要任何权限,并允许用户从更广泛的位置选择内容,包括您的应用程序没有文件系统级访问权限的位置。