Android: как прикрепить временное сгенерированное изображение к электронному письму? - PullRequest
16 голосов
/ 26 августа 2010

У меня есть изображение, сгенерированное программным способом, которое я хочу отправить в виде вложения с помощью метода ACTION_SEND и EXTRA_STREAM.

Но как мне это сделать?

Моя первая попытка(запись в мой путь к файлу на основе context.getCacheDir()), похоже, работала в предварительном просмотре Gmail (без предварительного просмотра изображения, но имя и значок вложенного файла были видны), но вложение так и не поступило на сторону получателя.Я думаю, это как-то связано с разрешениями для сгенерированного файла, но как этого избежать?Нужно ли устанавливать более разрешающие настройки для этих сгенерированных файлов (чтобы доступ к активности Gmail был доступным)?Возможно ли это даже для папки кэша приложения?

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

Я даже пытался кодировать свое изображение исключительно в URI в стиле data:image/png;base64,ABCD....Это также обнаружилось в предварительном просмотре Gmail (значок вложения, но без имени файла), но не привело к вложению на стороне получателя.

Кто-нибудь смог прикрепить одноразовое изображение кнамерение электронной почты каким-либо образом?Какие варианты я мог пропустить?

Ответы [ 3 ]

18 голосов
/ 27 августа 2010

Моя проблема действительно состояла из двух частей:

  1. context.getCacheDir() является приватной для вашего приложения.Вы не можете поместить что-то туда и ожидать, что другое приложение сможет получить к нему доступ.
  2. Я неправильно понял, какой тип 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[] { "someone@somewhere.com" });
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Portable Network Graphics");
intent.putExtra(android.content.Intent.EXTRA_CC, new String[] { "carbon@somewhere.com" });
intent.putExtra(Intent.EXTRA_TEXT, "Something textual");
intent.putExtra(Intent.EXTRA_STREAM, pngUri);

И затем запустите упражнение

context.startActivity(Intent.createChooser(intent, "Something Pithy"));

И затем убедитесь, что вы все очистите ...

Предостережение 1

Похоже, что в каталогах SD-карт для конкретных приложений появляется больше поддержки, но, увы, не в моей требуемой версии SDK.

Предупреждение 2

Это обзор решения, которое в итоге сработало для меня.Это не обязательно подход «наилучшей практики».

Предостережение 3

Это означает, что для установки образа в приложении должна быть установлена ​​SD-карта.функция вложения доступна, но это было полностью приемлемо для моего варианта использования.Ваш пробег может варьироваться.Если SD-карта недоступна, я добавляю в электронное письмо дружескую заметку, объясняющую, почему изображения не могут быть прикреплены и как исправить ситуацию.

4 голосов
/ 29 февраля 2012

Я только что столкнулся с точно такой же проблемой (желая прикрепить текстовый файл в моем случае). Если вы посмотрите в журнале 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 мог их прикрепить. Я только что написал сообщение в блоге о том, как это сделать.

Надеюсь, это поможет:)

0 голосов
/ 01 мая 2013
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..."));
...