Android: Как подключить временное, сгенерированное изображение к электронному письму?
У меня есть программно сгенерированное изображение, которое я хочу отправить в качестве вложения с помощью методов ACTION_SEND
и EXTRA_STREAM
.
Но как мне это сделать?
Моя первая попытка (запись на мой путь к файлу context.getCacheDir()
), похоже, работала в предварительном просмотре Gmail (без предварительного просмотра изображения, но вложенное имя файла и значок были видны), но приложение никогда не появлялось на стороне получателя. Я предполагаю, что это имеет какое-то отношение к разрешениям на сгенерированный файл, но как этого избежать? Нужно ли устанавливать более разрешительные настройки для этих сгенерированных файлов (чтобы доступ к активности Gmail)? Это возможно даже для папки кэша приложений?
Есть ли другое местоположение файла, которое было бы более подходящим для записи моих файлов? Я рассмотрел папку с загрузкой, но думаю, что это будет неудобное место для чего-то, что должно существовать только до тех пор, пока оно не будет отправлено по электронной почте.
Я даже пробовал кодировать свое изображение только в URI стиля data:image/png;base64,ABCD...
. Это тоже появилось в предварительном просмотре Gmail (значок приложения, но не имя файла), но не привел к вложению получателя.
Кто-нибудь мог приложить одноразовое сгенерированное изображение к намерению электронной почты любыми способами? Какие варианты я могу упустить?
Ответы
Ответ 1
Моя проблема действительно состояла из двух частей:
-
context.getCacheDir()
является приватным для вашего приложения. Вы не можете что-то там положить и ожидать, что другое приложение сможет получить к нему доступ.
- Я неправильно понял, какой тип MIME я должен был использовать. Несмотря на то, что я отправлял электронный текст, мне действительно нужно было указать
image/png
ради моего вложения.
Кроме того, исследования показали, что размещение (потенциально больших) изображений в первичной памяти не было хорошей идеей, даже если вы собирались немедленно ее очистить.
Как только я сделал это и написал свои сгенерированные изображения в общедоступном месте на SD-карте, он работал нормально.
Итак, в обзоре:
Запросить доступ к SD-карте в манифесте
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Убедитесь, что SD-карта доступна
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
{
//Bail gracefully
}
Создать каталог на SD-карте
File pngDir = new File(
Environment.getExternalStorageDirectory(),
//Loose convention inferred from app examples
"Android/data/com.somedomain.someapp/flotsam");
if (!pngDir.exists())
pngDir.mkdirs();
Напишите свой файл в этот каталог и захватите Uri
File pngFile = new File(pngDir, "jetsam.png");
//Save file encoded as PNG
Uri pngUri = Uri.fromFile(pngFile);
Создайте ACTION_SEND
намерение
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("image/png"); //
intent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "[email protected]" });
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Portable Network Graphics");
intent.putExtra(android.content.Intent.EXTRA_CC, new String[] { "[email protected]" });
intent.putExtra(Intent.EXTRA_TEXT, "Something textual");
intent.putExtra(Intent.EXTRA_STREAM, pngUri);
И затем запустите действие
context.startActivity(Intent.createChooser(intent, "Something Pithy"));
И затем убедитесь, что вы все очистите...
Предостережение 1
Кажется, что больше подходит для каталогов SD-карт для приложений, но, увы, не в моей требуемой версии SDK.
Caveat 2
Это обзор решения, которое в конечном итоге сработало для меня. Это не обязательно подход "наилучшей практики".
Caveat 3
Это означает, что приложение должно иметь SD-карту, смонтированную для доступности функции вложений изображений, но это было вполне приемлемо для моего варианта использования. Ваш пробег может отличаться. Если SD-карта недоступна, я добавляю дружеское примечание к письму, объясняющее, почему изображения не могут быть прикреплены и как исправить ситуацию.
Ответ 2
Я просто столкнулся с одной и той же проблемой (желая прикрепить текстовый файл в моем случае). Если вы посмотрите в журнале Android, причина этого заключается в следующем:
02-28 21:01:28.434: E/Gmail(19673): file:// attachment paths must point to file:///mnt/sdcard. Ignoring attachment file:///data/data/com.stephendnicholas.gmailattach/cache/Test.txt
В качестве обходного решения (как упоминалось HRJ) вы можете использовать ContentProvider для обеспечения доступа к файлам в вашем внутреннем кеше приложения, чтобы Gmail мог их присоединить. Я только что написал сообщение в блоге о том, как это сделать.
Надеюсь, что с помощью этой помощи:)
Ответ 3
tableLayout.buildDrawingCache();
Bitmap test = Bitmap.createBitmap(tableLayout.getDrawingCache());
tableLayout.destroyDrawingCache();
Log.d("Image", test.toString());
String path = Environment.getExternalStorageDirectory().toString();
Log.d("Path", path);
File file = new File(path,"mail_image.png");
Uri pngUri = Uri.fromFile(file);
Log.d("Real Image Path", pngUri.toString());
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("image/png");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "email to");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "From My App");
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, pngUri );
startActivity(Intent.createChooser(emailIntent, "Send mail..."));