由于其他答案在我这里(2019年)都没有用,所以我通过将资产复制到应用程序的内部文件目录,然后共享此文件来解决了问题。 在我的情况下,我需要共享位于assets文件夹中的PDF文件。
在AndroidManifest.xml中添加一个文件提供程序(无需使用自定义提供程序):
<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/filepaths" />
</provider>
在res/xml/目录下创建一个filepaths.xml文件。
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="root"
path="/" />
</paths>
当然,如果您在应用程序目录中管理其他文件,则应在此处使用子目录。
现在,在您想要触发共享意图的类中。
1. 在文件目录中创建一个空文件
private fun createFileInFilesDir(filename: String): File {
val file = File(filesDir.path + "/" + filename)
if (file.exists()) {
if (!file.delete()) {
throw IOException()
}
}
if (!file.createNewFile()) {
throw IOException()
}
return file
}
2. 将资产的内容复制到文件中
private fun copyAssetToFile(assetName: String, file: File) {
val buffer = ByteArray(1024)
val inputStream = assets.open(assetName)
val outputStream: OutputStream = FileOutputStream(file)
while (inputStream.read(buffer) > 0) {
outputStream.write(buffer)
}
}
3. 为文件创建共享意图
private fun createIntentForFile(file: File, intentAction: String): Intent {
val uri = FileProvider.getUriForFile(this, applicationContext.packageName + ".provider", file)
val intent = Intent(intentAction)
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
intent.setDataAndType(uri, "application/pdf")
return intent
}
4. 执行1-3并触发意图
private fun sharePdfAsset(assetName: String, intentAction: String) {
try {
val file = createFileInFilesDir(assetName)
copyAssetToFile(assetName, file)
val intent = createIntentForFile(file, intentAction)
startActivity(Intent.createChooser(intent, null))
} catch (e: IOException) {
e.printStackTrace()
AlertDialog.Builder(this)
.setTitle(R.string.error)
.setMessage(R.string.share_error)
.show()
}
}
5. 调用函数
sharePdfAsset("your_pdf_asset.pdf", Intent.ACTION_SEND)
如果你想分享文件后删除它,你可以使用
startActivityForResult()
并在之后删除它。通过更改
intentAction
,您还可以使用
Intent.ACTION_VIEW
对其进行“打开方式”操作。
对于
assets
,
filesDir
,... 当然需要在一个
Activity
中或具有
Context
。