5

I'm creating an email intent and attaching a file (using a FileProvider) but the Gmail client reports "impossible to attach the file".

I had this working previously but it's now broken. I didn't change my code (that I'm aware of) but have updated both the OS and the Gmail client.

// Build email Intent
Uri mailToUri = Uri.fromParts("mailto", "", null);
Intent emailIntent = new Intent(Intent.ACTION_SEND, mailToUri);
emailIntent.setType("text/plain");
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "A subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "A body");

// Build the attachment URI
File attachFile = new File(aDirectory, aFileName);
Uri attachmentUri = FileProvider.getUriForFile(this,
                        FILE_PROVIDER_AUTHORITY, attachFile);
emailIntent.putExtra(Intent.EXTRA_STREAM, attachmentUri);

// Start the share activity
startActivity(emailIntent);

// Alternative methods for creating the URI 
// Uri attachmentUri = Uri.parse("file://" 
//                   + attachFile.getAbsolutePath());
// Uri attachmentUri = Uri.parse("content://" 
//                   + FILE_PROVIDER_AUTHORITY
//                   + "/" + attachFileName)

Gmail client presents the draft email with subject and body, but reports "impossible to attach the file".

I've also tried using the alternative methods shown for creating the Uri. The first used to work before FileProviders became mandatory. The second fails in the same way as the above code.

There are some Gmail error messages in the LOGCAT:

08-27 17:15:39.463  8972  8972 W Gmail   : Gmail:No collectionId found for event forward
08-27 17:15:39.463  8972  8972 W Gmail   : Gmail:No itemId found for event forward
08-27 17:15:39.505  8972  8972 W Gmail   : Gmail:No collectionId found for event forward
08-27 17:15:39.505  8972  8972 W Gmail   : Gmail:No itemId found for event forward
08-27 17:15:39.514  8972  8972 W Gmail   : ComposeActivity:b/119949571:In finishSetup.
08-27 17:15:39.515  8972  8972 W Gmail   : Gmail:b/119949571:loading bodyWebView with template emit size of 2120.
08-27 17:15:39.576  8972  8972 E Gmail   : ComposeActivity:Error adding attachment
08-27 17:15:39.576  8972  8972 E Gmail   : fwt: FileNotFoundException when openAssetFileDescriptor.
08-27 17:15:39.576  8972  8972 E Gmail   :  at fww.a(SourceFile:7)
08-27 17:15:39.576  8972  8972 E Gmail   :  at fww.a(SourceFile:41)
08-27 17:15:39.576  8972  8972 E Gmail   :  at dfb.a(SourceFile:308)
08-27 17:15:39.576  8972  8972 E Gmail   :  at dhs.run(SourceFile:2)
08-27 17:15:39.576  8972  8972 E Gmail   :  at dfb.a(SourceFile:71)
08-27 17:15:39.576  8972  8972 E Gmail   :  at dfb.a(SourceFile:412)
08-27 17:15:39.576  8972  8972 E Gmail   :  at dfo.a(Unknown Source:9)
08-27 17:15:39.576  8972  8972 E Gmail   :  at adco.a(Unknown Source:6)
08-27 17:15:39.576  8972  8972 E Gmail   :  at afet.a(SourceFile:2)
08-27 17:15:39.576  8972  8972 E Gmail   :  at afeu.run(SourceFile:6)
08-27 17:15:39.576  8972  8972 E Gmail   :  at afgx.run(Unknown Source:7)
08-27 17:15:39.576  8972  8972 E Gmail   :  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
08-27 17:15:39.576  8972  8972 E Gmail   :  at adag.run(SourceFile:2)
08-27 17:15:39.576  8972  8972 E Gmail   :  at abno.run(Unknown Source:3)
08-27 17:15:39.576  8972  8972 E Gmail   :  at android.os.Handler.handleCallback(Handler.java:873)
08-27 17:15:39.576  8972  8972 E Gmail   :  at android.os.Handler.dispatchMessage(Handler.java:99)
08-27 17:15:39.576  8972  8972 E Gmail   :  at android.os.Looper.loop(Looper.java:193)
08-27 17:15:39.576  8972  8972 E Gmail   :  at android.app.ActivityThread.main(ActivityThread.java:6923)
08-27 17:15:39.576  8972  8972 E Gmail   :  at java.lang.reflect.Method.invoke(Native Method)
08-27 17:15:39.576  8972  8972 E Gmail   :  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
08-27 17:15:39.576  8972  8972 E Gmail   :  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:870)
08-27 17:15:39.653  8972  8972 W Gmail   : Gmail:No collectionId found for event forward
08-27 17:15:39.653  8972  8972 W Gmail   : Gmail:No itemId found for event forward
08-27 17:15:39.682  8972  8972 W Gmail   : Gmail:No collectionId found for event forward
08-27 17:15:39.682  8972  8972 W Gmail   : Gmail:No itemId found for event forward
08-27 17:15:39.842  8972  8972 E Gmail   : Gmail:EditWebView JS Console: b/119949571:draft.editor.onLoad; source: file:///android_asset/draft_editor_gmail_compiled.js at 87
08-27 17:15:39.917  8972  8972 E Gmail   : Gmail:EditWebView JS Console: b/119949571:draft.editor.onLoad is finished; source: file:///android_asset/draft_editor_gmail_compiled.js at 88

Using the "content://" Uri reports a similar error except for the line: fwt: Null AssetFileDescriptor while calling openAssetFileDescriptor.

[Snip of manifest] <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.pentad.bridge.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_paths"/> </provider>

[File file_provider_paths.xml] <?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="app_root" path="."/> </paths>

Cœur
  • 37,241
  • 25
  • 195
  • 267
T Clulow
  • 74
  • 7
  • That looks OK. It might be a bug in Gmail. If you have not done so already, write an instrumented test that confirms that you can read the content served by your `FileProvider`. – CommonsWare Aug 27 '19 at 16:41
  • Turned out to be a subtle error in the pathname (so indeed the error message was correct). It would have helped A LOT if Gmail had reported the path it couldn't find. – T Clulow Oct 27 '19 at 16:14

3 Answers3

2

If you also add it as ClipData, the permission grant will work successfully:

yourIntent.clipData = ClipData.newUri(context.contentResolver, fileName, contentUri)

The culprit is that Intent.FLAG_GRANT_READ_URI_PERMISSION will work only for Intent.data and Intent.clipData, and not for extras, unless the uri permission grant has been given explicitly (inconvenient), or has been given by also adding a ClipData.

Louis CAD
  • 10,965
  • 2
  • 39
  • 58
0

Looks like gmail can't find the file you are trying to attach. It says: "FileNotFoundException when openAssetFileDescriptor"

Make sure the file created here has a valid path to an existing file.

File attachFile = new File(aDirectory, aFileName);

Further notes:

  • FileProvider.getUriForFile() is the way to go these days. That is, your alternative approaches won't work.
  • When passing a File object to FileProvider.getUriForFile() make sure the underline path of that file doesn't contain any uri prefix such as "://file" or "://content". It should be a simple path representation. For example: "/storage/emulated/0/myapp/myfile.jpg". In particular, don't use URL encoding in your path. For example, if you have a space in your path do: "/storage/emulated/0/myapp/my attachments/myfile.jpg" rather than "/storage/emulated/0/myapp/my%20attachments/myfile.jpg"
HaimS
  • 824
  • 8
  • 18
0

for me it worked after I cast createNewFile

// Build the attachment URI
File attachFile = new File(aDirectory, aFileName);
attachFile.createNewFile();