Android – Gmail 5.0 app fails with “Permission denied for the attachment” when it receives ACTION_SEND intent

androidandroid-intent

My app creates mails with attachments, and uses an intent with Intent.ACTION_SEND to launch a mail app.

It works with all the mail apps I tested with, except for the new Gmail 5.0 (it works with Gmail 4.9), where the mail opens without attachment, showing the error: "Permission denied for the attachment".

There are no useful messages from Gmail on logcat. I only tested Gmail 5.0 on Android KitKat, but on multiple devices.

I create the file for the attachment like this:

String fileName = "file-name_something_like_this";
FileOutputStream output = context.openFileOutput(
        fileName, Context.MODE_WORLD_READABLE);

// Write data to output...

output.close();
File fileToSend = new File(context.getFilesDir(), fileName);

I'm aware of the security concerns with MODE_WORLD_READABLE.

I send the intent like this:

public static void compose(
        Context context,
        String address,
        String subject,
        String body,
        File attachment) {

    Intent emailIntent = new Intent(Intent.ACTION_SEND);
    emailIntent.setType("message/rfc822");
    emailIntent.putExtra(
            Intent.EXTRA_EMAIL, new String[] { address });
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
    emailIntent.putExtra(Intent.EXTRA_TEXT, body);

    emailIntent.putExtra(
            Intent.EXTRA_STREAM,
            Uri.fromFile(attachment));

    Intent chooser = Intent.createChooser(
            emailIntent, 
            context.getString(R.string.send_mail_chooser));

    context.startActivity(chooser);
}

Is there anything I do wrong when creating the file or sending the intent? Is there a better way to start a mail app with attachment? Alternatively – has someone encountered this problem and found a workaround for it?

Thanks!

Best Answer

I was able to pass a screenshot .jpeg file from my app to GMail 5.0 through an Intent. The key was in this answer.

Everything I have from @natasky 's code is nearly identical but instead, I have the file's directory as

context.getExternalCacheDir();

Which "represents the external storage directory where you should save cache files" (documentation)

Related Topic