Search code examples
androidandroid-resourcesandroid-fileproviderandroid-sharing

Share raw resources android


I have .mp3, .mp4 and .jpg files in my raw resources. I want to share those files with social apps. I have tried to set up a file provider for that reason, but it didn't work.

Manifest:

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

paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>

<files-path name="file_path" path="."/>

<external-files-path name="external_path" path="/" />

</paths>

This is how I try to share the files (in this case audio):

File file = new File(mAudio.getSoundUri().getEncodedPath());
Uri soundUri = FileProvider.getUriForFile(
                getContext(),
                "com.my.packagename.fileprovider",
                file);
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("audio/mp3");
sharingIntent.putExtra(Intent.EXTRA_STREAM, mAudio.getSoundUri());
startActivity(Intent.createChooser(sharingIntent, "Send"));

The mAudio object's getSoundUri() returns a Uri like this: android.resource://com.my.packagename/raw/sound.mp3

When I run this I either don't get any error but the intent doesn't show up and my activity is rebuilt or I get this:

java.lang.IllegalArgumentException: Failed to find configured root that contains /raw/sound.mp3

I have tried to remove /raw from the Uri but I get the same error:

java.lang.IllegalArgumentException: Failed to find configured root that contains /sound.mp3

Why is this happening?


Solution

  • Why is this happening?

    Resources are files on your development machine. They are not files on the device. There is no filesystem path on the device for a resource, and so FileProvider cannot serve them.

    Your two main options are:

    1. Copy the resources to files (e.g., in getCacheDir()), then use FileProvider to serve the files

    2. Write your own ContentProvider to serve the raw resources directly (use getResources() on a Context to get a Resources object, and from there you can get an InputStream on a raw resource)