我在创建一个将大量原始数据写入文本文件然后共享该文本文件以通过电子邮件/ whatsapp发送的功能时遇到了一些麻烦。从Android 10开始,由于隐私原因,无法再使用Environment.getExternalStorageDir()
。现在看来,我的文件对其他应用程序不可见,因此无法被其他应用程序打开。我的代码如下:
负责导出的片段:
CoroutineScope(Dispatchers.IO).launch {
withContext(Dispatchers.IO) {
val data: String = retrieveData() ?: return@withContext
val file = File(requireContext().getExternalFilesDir(null), "export.xml")
val outputStream =
requireContext().openFileOutput("export.xml", Context.MODE_PRIVATE)
outputStream.write(data.toByteArray())
outputStream.close()
val uri = FileProvider.getUriForFile(requireContext(),BuildConfig.APPLICATION_ID, file)
val shareIntent = Intent().apply {
type = "text/plain"
putExtra(Intent.EXTRA_STREAM, uri)
putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_file_subject))
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(
Intent.createChooser(
shareIntent,
getString(R.string.share_file_subject)
)
)
}
}
清单中:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="files"
path="/" />
</paths>
[使用Android Studio文件浏览器时,我可以看到该文件是用正确的内容创建的。 Uri指向:content://myApplicationId/files/export.xml
,文件位于我的设备上的data/data/myApplicationId/files
,但我似乎无法弄清楚如何使其他应用程序可以打开它。有什么建议吗?
提前感谢。
Uri指向:content://myApplicationId/files/export.xml
但是您没有使用该Uri
。您正在使用Uri.fromFile()
:
val shareIntent = Intent().apply {
type = "text/plain"
putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file))
putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_file_subject))
您应该在Android 7.0+上使用FileUriExposedException
崩溃,因此您已经应用了破解方法来解决此问题。只是现在,在Android 10+上,这种黑客攻击的价值是有限的。
因此,将Uri.fromFile(file)
替换为uri
。另外,将addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
包括在apply {}
lambda中。并至少在StrictMode
构建中找到要在代码中配置FileUriExposedException
的地方并让它抱怨debug
。