Невозможно программно прикрепить файл к намерению электронной почты с помощью FileProvider

Я создаю намерение электронной почты и прикрепляю файл (используя FileProvider), но клиент Gmail сообщает, что «невозможно прикрепить файл».

Раньше у меня это работало, но теперь оно сломано. Я не менял свой код (о котором мне известно), но обновил как ОС, так и клиент Gmail.

// 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 представляет черновик письма с темой и телом, но сообщает, что «невозможно прикрепить файл».

Я также пробовал использовать альтернативные методы, показанные для создания Uri. Первый работал до того, как FileProviders стал обязательным. Второй терпит неудачу так же, как приведенный выше код.

В LOGCAT есть несколько сообщений об ошибках Gmail:

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

Использование «content://» Uri сообщает об аналогичной ошибке, за исключением строки: fwt: Null AssetFileDescriptor while calling openAssetFileDescriptor.

[Фрагмент манифеста] <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_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>


person T Clulow    schedule 27.08.2019    source источник
comment
Это выглядит нормально. Это может быть ошибка в Gmail. Если вы еще этого не сделали, напишите инструментальный тест, который подтвердит, что вы можете читать содержимое, предоставляемое вашим FileProvider.   -  person CommonsWare    schedule 27.08.2019
comment
Оказалось, что это небольшая ошибка в имени пути (так что действительно сообщение об ошибке было правильным). ОЧЕНЬ помогло бы, если бы Gmail сообщил о пути, который не смог найти.   -  person T Clulow    schedule 27.10.2019


Ответы (3)


Похоже, Gmail не может найти файл, который вы пытаетесь прикрепить. Он говорит: «FileNotFoundException, когда openAssetFileDescriptor»

Убедитесь, что созданный здесь файл имеет допустимый путь к существующему файлу.

File attachFile = new File(aDirectory, aFileName);

Дополнительные примечания:

  • FileProvider.getUriForFile() - это то, что нужно в наши дни. То есть ваши альтернативные подходы не сработают.
  • При передаче объекта File в FileProvider.getUriForFile() убедитесь, что подчеркнутый путь к этому файлу не содержит префикса uri, такого как "://file" или "://content". Это должно быть простое представление пути. Например: "/storage/emulated/0/myapp/myfile.jpg". В частности, не используйте кодировку URL в вашем пути. Например, если в вашем пути есть пробел, сделайте: "/storage/emulated/0/myapp/my attachments/myfile.jpg", а не "/storage/emulated/0/myapp/my%20attachments/myfile.jpg"
person HaimS    schedule 26.10.2019
comment
Я думаю, что пространство не будет проблемой, потому что у меня есть файл без пробелов, но проблема все еще существует. - person Prasad G Kulkarni; 23.12.2019

для меня это сработало после того, как я применил createNewFile

// Build the attachment URI
File attachFile = new File(aDirectory, aFileName);
attachFile.createNewFile();
person Lucacel Razvan Cristian    schedule 17.09.2020

Если вы также добавите его как ClipData, разрешение будет работать успешно:

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

Виновником является то, что Intent.FLAG_GRANT_READ_URI_PERMISSION будет работать только для Intent.data и Intent.clipData, а не для дополнительных функций, если только предоставление разрешения uri не было дано явно (неудобно) или не было дано путем добавления ClipData.

person Louis CAD    schedule 14.01.2021