Попытка прикрепить файл с SD-карты к электронной почте

Я пытаюсь запустить намерение отправить электронное письмо. Все это работает, но когда я пытаюсь отправить электронное письмо, происходит пара «странных» вещей.

вот код

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("image/jpeg");
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Photo");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://sdcard/dcim/Camera/filename.jpg"));
sendIntent.putExtra(Intent.EXTRA_TEXT, "Enjoy the photo");
startActivity(Intent.createChooser(sendIntent, "Email:"));

Поэтому, если я запускаю, используя контекст меню Gmail, он показывает вложение, позволяет мне ввести адрес электронной почты и отредактировать тело и тему. Ничего страшного. Я нажимаю отправить, и он отправляет. Единственное, вложение НЕ отправляется.

Так. Я подумал, почему бы не попробовать это с контекстом меню электронной почты (для моей резервной учетной записи электронной почты на моем телефоне). Он показывает вложение, но в теле или теме вообще нет текста. Когда я отправляю его, вложение отправляется правильно. Это заставило бы меня поверить, что что-то не так. Нужно ли мне новое разрешение в манифесте для запуска намерения отправить электронное письмо с вложением? Что я делаю неправильно?


person Chrispix    schedule 25.02.2009    source источник
comment
Спасибо Chrispix!, этот код работал в моем moto cliq.   -  person Jana    schedule 19.10.2010


Ответы (11)


Тоже получаю такую ​​же проблему

Код:

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); 
    emailIntent.setType("image/jpeg");
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] 
    {"[email protected]"}); 
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, 
    "Test Subject"); 
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, 
    "go on read the emails"); 
    Log.v(getClass().getSimpleName(), "sPhotoUri=" + Uri.parse("file:/"+ sPhotoFileName));
    emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:/"+ sPhotoFileName));
    startActivity(Intent.createChooser(emailIntent, "Send mail..."));

Из логарифма adb:

V/DumbDumpersMain( 3972):   sPhotoUri=file://sdcard/DumbDumpers/DumbDumper.jpg
I/ActivityManager(   56):   Starting activity: Intent { action=android.intent.action.CHOOSER comp={android/com.android.internal.app.ChooserActivity} (has extras) }
I/ActivityManager(   56):   Starting activity: Intent { action=android.intent.action.SEND type=jpeg/image flags=0x3000000 comp={com.google.android.gm/com.google.android.gm.ComposeActivityGmail} (has extras) }
I/ActivityManager(   56):   Starting activity: Intent { action=android.intent.action.SEND type=jpeg/image flags=0x2800000 comp={com.google.android.gm/com.google.android.gm.ComposeActivity} (has extras) }
D/gmail-ls(  120):      MailProvider.query: content://gmail-ls/labels/[email protected](null, null)
D/Gmail   ( 2507):      URI FOUND:file://sdcard/DumbDumpers/DumbDumper.jpg

Похоже, поставщик электронной почты прикрепляет файл нулевой длины. Когда я проверяю файловую систему, файл есть и правильный. Код, который создает файл изображения, хорошо закончен перед попыткой отправить его по электронной почте.

Кто-нибудь исправил это без волшебных перезагрузок (это я уже пробовал)?

С уважением,
Фин

Обновить

Путь для меня должен был быть

file:///sdcard/DumbDumpers/DumbDumper.jpg

вам нужен дополнительный /, так как он указывает на корневой каталог, т.е.:

file:// + /sdcard/DumbDumpers/DumbDumper.jpg

в сочетании как

file:///sdcard/DumbDumpers/DumbDumper.jpg

В приведенном выше фрагменте вам нужно:

emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+ sPhotoFileName));

Надеюсь, это поможет. Мне потребовались годы, чтобы отладить.

С уважением,
Финлей

person Community    schedule 14.08.2009
comment
Я проголосовал, но было бы еще лучше, если бы вы переработали это, чтобы окончательное решение было включено в код. Решение здесь важнее истории. - person Patrick O'Leary; 24.01.2010
comment
Я изменил ответ, чтобы отразить тот факт, что ему нужно 3 косых черты. Я также проголосовал за это. - person Chrispix; 04.11.2010
comment
голос за, я бы не стал переделывать это, потому что люди действительно должны знать, где была ошибка. спасибо за решение. - person mad; 13.12.2010
comment
upvote, но EXTRA_TEXT не работает в случае facebook, только изображение появляется на моей стене после сообщения. Любая идея, как мне решить эту проблему. - person varun bhardwaj; 23.01.2012
comment
Не следует использовать жестко заданные пути, поскольку они могут меняться в зависимости от устройства. Поэтому я предлагаю вам небольшое изменение в вашем коде: File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename); Затем определите: Uri path = Uri.fromFile(filelocation); и поместите его в свое намерение: emailIntent .putExtra(Intent.EXTRA_STREAM, path); - person Carlos Borau; 24.11.2015

Небольшое замечание с моей стороны. У меня были те же проблемы с GMail, но почему-то это работает, когда я сначала сохраняю рассматриваемый файл на SD-карте и извлекаю его оттуда, а не из активов. Итак, мой код следующий:

Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_SUBJECT, "Title");
i.putExtra(Intent.EXTRA_TEXT, "Content");
i.putExtra(Intent.EXTRA_STREAM, uri);
i.setType("text/plain");
startActivity(Intent.createChooser(i, "Send mail"));

и тут,

uri = Uri.fromFile(new File(context.getFilesDir(), FILENAME));

не работает, тогда как

uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), FILENAME));

делает.

С уважением, Майкл

person Michael F    schedule 20.07.2010
comment
Я нашел то же самое. Интересно, это проблема с разрешениями на чтение файла Gmail (или другой почтовой программой)? Одна вещь, которая мне помогла, это то, что когда я использовал встроенную программу Mail (не Gmail), она показала, что вложение было 0 байт. Было приятно узнать, что проблема существует, без необходимости отправлять и проверять мою электронную почту. :-) - person Tyler Collier; 24.11.2010
comment
Я бы предложил заменить startActivity() на startActivityForResult() и удалить файл из корня SD-карты в onActivityResult(). - person Paul Lammertsma; 21.11.2011
comment
Я думаю, что это не проблема разрешения. Это проблема с Android, которая была исправлена ​​где-то между 2.3 и 4.2. В версии 2.3, если я сделаю файл во внутренней памяти доступным для чтения, другие приложения смогут его открыть, но gmail по-прежнему не сможет его прикрепить. Должен быть на внешнем хранилище. На 4.2 такой проблемы нет. - person Tom; 31.05.2013

вместо "Uri.parse" используйте "Uri.fromFile(новый файл(Environment.getExternalStorageDirectory(),"имя файла"))"

Environment.getExternalStorageDirectory() — путь к SD-карте или любому другому внешнему хранилищу

person Snigdha    schedule 07.07.2010

Похоже, это на самом деле правильно, не уверен, что происходит, но после перезагрузки он заработал :/

person Chrispix    schedule 25.02.2009
comment
В коде OP есть опечатка: путь должен быть file:///sdcard (обратите внимание на три косые черты, а не на две). - person Paul Lammertsma; 21.11.2011

У меня была такая же проблема, и я везде искал решение. В конце концов я решил эту проблему, найдя приложение с открытым исходным кодом, которое работало из коробки, и посмотрел, как они это сделали. Код довольно длинный, поэтому я не буду цитировать его здесь, а дам ссылку. Посмотрите на функцию sendEmail в строке 449.

http://rehearsalassist.svn.sourceforge.net/viewvc/rehearsalassist/android/trunk/src/urbanstew/RehearsalAssistant/SessionPlayback.java?revision=94&view=markup

Я реорганизовал свой код, чтобы он был похож, и теперь он работает. Я надеюсь, что это поможет другим в той же ситуации.

person Railsdev    schedule 26.11.2010

Из RFC 1738, раздел 3.10:

URL-адрес файла имеет вид:

   file://<host>/<path>

где хост — это полное доменное имя системы, в которой доступен путь, а путь — это иерархический путь к каталогу в форме каталог/каталог/. ../имя.

Таким образом, это файл:///путь/из/корня, точно так же, как http://host/path/from/root потому что между второй и третьей косой чертой есть неявный «localhost». Но, как упоминалось выше, используйте Uri.FromFile() для его создания.

person android.weasel    schedule 17.01.2012
comment
Часть о 3 косой черте - это то, что я хочу. Спасибо. - person Hoang Tran; 17.08.2012

У меня были такие же симптомы. В моем случае это произошло потому, что я изначально сохранял вложение с разрешениями MODE_PRIVATE. Как только я изменил его на MODE_WORLD_READABLE, кажется, GMail смог получить доступ к файлу и правильно отправить вложение.

Подробнее

person CasualCoder    schedule 02.03.2013

Для меня это работает отлично: в этом решении Николя создает одну копию внутри папки Cache, и здесь у намерения gmail есть доступ! http://stephendnicholas.com/archives/974

person lucasddaniel    schedule 01.06.2013

Также попробуйте добавить Intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Это помогло с моей проблемой.

person James Jones    schedule 01.01.2015

У меня есть решение по этому поводу через 4 дня. Обратите внимание на следующие моменты, указывая путь к классу File в Android (Java):

1) Использовать путь для внутреннего хранилища String path="/storage/sdcard0/myfile.txt";

2) путь="/storage/sdcard1/myfile.txt";

3) указать разрешения в файле манифеста.

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

4) Сначала проверьте длину файла для подтверждения.

5) Проверьте пути в ES File Explorer относительно sdcard0 и sdcard1, это то же самое или другое ......

e.g.

File file=new File(path); 
long=file.length();//in Bytes
person Mahadev Mane    schedule 12.09.2016

Отправить электронное письмо с вложением: (по документам)

Намерение emailIntent = новое намерение (Intent.ACTION_SEND); emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);

emailIntent.putExtra (Intent.EXTRA_EMAIL, новая строка [] {[email protected]});

emailIntent.putExtra(Intent.EXTRA_SUBJECT, Тема письма); emailIntent.putExtra(Intent.EXTRA_TEXT, Текст сообщения электронной почты); emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(content://path/to/email/attachment));

// Вы также можете присоединить несколько элементов, передав ArrayList Uris

person shaiban    schedule 07.11.2016