使用Kotlin在APP中集成发送附件功能时找不到内置PDF如何解决
解决方案
1. 资源存放位置
你需要把 generalConditions.pdf 文件放到项目的 app/src/main/assets 目录下,如果你的项目还没有这个目录,手动新建即可,该目录和 res、java 目录同级。
注意:assets目录下的资源会被原封不动打包到APK中,不会被编译生成资源ID,需要通过AssetManager访问。
2. 新增资源拷贝逻辑
你当前的代码直接从应用私有文件目录 filesDir 读取文件,但内置在APK中的assets资源不会默认存在于这个目录,需要你在首次启动或者用到附件前,先把PDF从assets拷贝到filesDir,拷贝示例代码如下:
fun copyPdfFromAssetsToFilesDir(context: Context, fileName: String) { val targetFile = File(context.filesDir, fileName) // 如果文件已经存在就不用重复拷贝 if (targetFile.exists()) return try { val inputStream = context.assets.open(fileName) val outputStream = FileOutputStream(targetFile) val buffer = ByteArray(1024) var length: Int while (inputStream.read(buffer).also { length = it } > 0) { outputStream.write(buffer, 0, length) } inputStream.close() outputStream.flush() outputStream.close() } catch (e: Exception) { e.printStackTrace() } }
你可以在发送邮件的逻辑前先调用这个方法:
val fileName = "generalConditions.pdf" // 先拷贝资源 copyPdfFromAssetsToFilesDir(this, fileName) val file = File(this.filesDir,fileName) if (!file.exists()) { return }
3. 适配高版本系统URI权限问题
Android 7.0及以上系统直接使用Uri.fromFile(file)会抛出FileUriExposedException,你需要改用FileProvider生成可被外部邮件应用访问的URI,适配逻辑如下:
- 先在
AndroidManifest.xml中配置FileProvider
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
- 新建
res/xml/file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="internal_files" path="." /> </paths>
- 最后替换原来的URI生成逻辑:
// 替换val uri = Uri.fromFile(file) val uri = FileProvider.getUriForFile(this, "${packageName}.fileprovider", file) // 给邮件应用授予URI访问权限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
内容的提问来源于stack exchange,提问作者LastCard1440
相关产品推荐
相关产品推荐

