How do I let the user share a file with an arbitrary app?

Viewed 35

I would like to share a file from my Android app. Say the user clicks on the "share..." button, and it opens a dialog that lets them choose which app they want to share it with. It could be an email app (in which case I'm hoping it goes as an attachment), or a messaging app (the message is sent as an attachment to the contact), etc.

It felt like the Sharing a file part in the documentation was about this, but somehow I don't get how to make it work. The documentation focuses on having another app "pick" a file from my app, where I just want my app to "share" a file with an arbitrary app.

I tried to set the provider in AndroidManifest.xml:

<provider
  android:authorities="com.test.fileprovider"
  android:name="androidx.core.content.FileProvider"
  android:grantUriPermissions="true"
  android:exported="false">
  <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/filepaths" />
</provider>

And I created the xml/filepaths file:

<paths>
    <files-path path="logs/" name="logs" />
</paths>

Then I write my file in logFile below:

val logDir = File(context.filesDir, "logs")
val logFile = File(logDir, "mylog.txt")

And I try to "share" it with:

val fileToShare = FileProvider.getUriForFile(
    context,
    "com.test.fileprovider",
    logFile
)

val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_STREAM, fileToShare)
    type = "*/*"
}

context.startActivity(sendIntent)

But though it does not crash, nothing happens.

What am I missing? Is it even the right way to share a file?

2 Answers

The documentation focuses on having another app "pick" a file from my app, where I just want my app to "share" a file with an arbitrary app.

You want this documentation instead. Their page titles (which drive the navigation) leave a lot to be desired.

What am I missing?

Try using the actual MIME type of the content, not */*.

I was missing Intent.createChooser, as described in @CommonsWare's link.

This works:

val fileToShare = FileProvider.getUriForFile(
    context,
    "com.test.fileprovider",
    logFile
)

val sendIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_STREAM, fileToShare)
    type = "*/*"
}

context.startActivity(Intent.createChooser(sendIntent, null))

Also the MIME type should be updated according to the file.

Related