Miquel Perez
Miquel Perez

Reputation: 455

Share audio file from the res/raw folder thorugh Share Intent in Android

I'm trying to share an audio file from my res/raw folder. What I've done so far is:

Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.sound); //parse path to uri
Intent share = new Intent(Intent.ACTION_SEND); //share intent
share.setType("audio/*");
share.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(share, "Share sound to"));

When I choose to share it on GMail, for example, it says something like "Failed to attach empty file". Looks like I'm not getting the right file path, so I'm basically sharing nothing. What am I doing wrong?

Any help would be much appreciated.

Upvotes: 2

Views: 3575

Answers (3)

user5968678
user5968678

Reputation: 2094

Copy the audio file from the resource to external storage and then share it:

InputStream inputStream;
FileOutputStream fileOutputStream;
try {
    inputStream = getResources().openRawResource(R.raw.sound);
    fileOutputStream = new FileOutputStream(
            new File(Environment.getExternalStorageDirectory(), "sound.mp3"));

    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) > 0) {
        fileOutputStream.write(buffer, 0, length);
    }

    inputStream.close();
    fileOutputStream.close();
} catch (IOException e) {
    e.printStackTrace();
}

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM,
        Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/sound.mp3" ));
intent.setType("audio/*");
startActivity(Intent.createChooser(intent, "Share sound"));

Add WRITE_EXTERNAL_STORAGE permission to AndroidManifest.xml file:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Upvotes: 4

Miquel Perez
Miquel Perez

Reputation: 455

EDIT: It was causing a NullPointException. This is what was I doing:

File dest = Environment.getExternalStorageDirectory();
                InputStream in = getResources().openRawResource(R.raw.sound);

try
{
    OutputStream out = new FileOutputStream(new File(dest, "sound.mp3"));
    byte[] buf = new byte[1024];
    int len;
    while ( (len = in.read(buf, 0, buf.length)) != -1){
        out.write(buf, 0, len);
    }
    in.close();
    out.close();

}catch (Exception e) {}


 final Uri uri = FileProvider.getUriForFile(Soundboard.this, "myapp.folagor.miquel.folagor", dest); //NullPointerException right here!!

 final Intent intent = ShareCompat.IntentBuilder.from(Soundboard.this)
                        .setType("audio/*")
                        .setSubject(getString(R.string.share_subject))
                        .setStream(uri)
                        .setChooserTitle(R.string.share_title)
                        .createChooserIntent()
                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
                        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

  startActivity(intent);

The code was just fine. The only problem was that on the Manifest's permisions, I had "WRITE_EXTERNAL_STORAGE" instead of "android.permissions.WRITE_EXTERNAL_STORAGE". So I was not having permision to write in the external storage, which caused a FileNotFoundException due to the lack of permision. Now it works fine!

Upvotes: 0

CommonsWare
CommonsWare

Reputation: 1006614

What am I doing wrong?

Few apps handle android.resource Uri values correctly. Your choices are:

  1. Drop the feature, or

  2. Copy the data from the resource into a file, then use FileProvider, perhaps in conjunction with my LegacyCompatCursorWrapper, or

  3. Use my StreamProvider, which can serve raw resources directly, or

  4. Copy the data from the resource into a file, then use Uri.fromFile(), but this looks like it will stop working with the next version of Android, based on preliminary results from testing with the N Developer Preview

Upvotes: 1

Related Questions