Search code examples
androidandroid-intentandroid-fileprovider

Sharing a file with a FileProvier


I'm attempting a file created by my app using a FileProvider and a chooser. However, in my implementation after the chooser completes the chosen app throws up an error saying that it can't "get share data from intent" (signal), or does nothing (whatsapp, editor, ...).

I've added a FileProvider stanza to my AndroidManifest.xml within my applications tag:

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

My file_paths.xml contains

<paths>
  <files-path path="." name="root" />
  <files-path path="shared/" name="shared" />
</paths>

and my implementation is

    File filesDir = getApplicationContext().getFilesDir();
    File shareDir = new File(filesDir, "shared/");
    File file = new File(shareDir, "filename.txt");

    Uri fileUri = FileProvider.getUriForFile(getApplicationContext(),
                                             "com.domain.name.fileprovider",
                                             file);

    // Create the text message with a string
    Intent sendIntent = new Intent(Intent.ACTION_SEND);
    sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    sendIntent.setData(fileUri);
    sendIntent.setType("text/plain");

    startActivity(Intent.createChooser(sendIntent, getString(R.string.share_title)));

The fileUri gets populated successfully, and I can see from AndroidStudio's device explorer that the file exists and has the contents I'd expect.

I've been working from Sharing Files and FileProvider, but haven't spotted what I've missed yet.

What have I done which means I haven't correctly granted read permission to the intent's recipient? Thanks!


Solution

  • ACTION_SEND does not use setData().

    The best solution is to use ShareCompat.IntentBuilder, which handles a lot of ACTION_SEND idiosyncrasies for you. Per Ian Lake's post, you would replace:

        Intent sendIntent = new Intent(Intent.ACTION_SEND);
        sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        sendIntent.setData(fileUri);
        sendIntent.setType("text/plain");
    

    with:

    Intent shareIntent = ShareCompat.IntentBuilder.from(this)
      .setType("text/plain")
      .setStream(fileUri)
      .getIntent();