Since none of the other answers here worked for me (in 2019) I made a workaround by copying the asset to the app's internal file directory and then sharing this file.
In my case, I needed to share a pdf file from the assets folder.
In the AndroidManifest.xml add a file provider (no need to use a custom one):
<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>
Create a filepaths.xml file in res/xml/
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path
name="root"
path="/" />
</paths>
Of course you should use a subdirectory here if you manage other files in your app directory.
Now in the class where you want to trigger the share intent.
1. Create an empty file in the files directory
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. Copy the content of the asset to the file
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. Create a share intent for the file
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. Execute 1-3 and fire the intent
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. Call the function
sharePdfAsset("your_pdf_asset.pdf", Intent.ACTION_SEND)
If you want to delete the file after sharing it, you probably could use startActivityForResult()
and delete it afterwards. By changing the intentAction
you can also use this process for an "open with..." action by using Intent.ACTION_VIEW
.
For assets
, filesDir
, ... you need to be in an Activity
or have a Context
of course.