Android:如何将临时生成的图像附加到电子邮件中?

el2*_*ot2 16 email android image attachment dynamically-generated

我有一个以编程方式生成的图像,我想通过ACTION_SENDEXTRA_STREAM方法作为附件发送.

但是我该怎么做?

我的第一次尝试(写入我的context.getCacheDir()基础文件路径)似乎在Gmail预览中有效(没有图像预览,但附件文件名和图标可见),但附件从未到达收件人端.我想这与生成的文件的权限有关,但如何避免这种情况?我是否需要在这些生成的文件上设置更宽松的设置(以便Gmail活动可以访问)?应用程序的缓存文件夹甚至可以吗?

是否有另一个文件位置更适合写我的文件?我考虑了下载文件夹,但认为这对于只有在通过电子邮件发送之前才需要存在的东西才是一个尴尬的位置.

我甚至尝试过纯粹在data:image/png;base64,ABCD...样式URI中编码我的图像.这也出现在Gmail预览中(附件图标,但没有文件名),但未导致收件人端附件.

有没有人能够通过任何方式将一次性生成的图像附加到电子邮件意图?我可能忽略了哪些选择?

el2*_*ot2 18

我的问题实际上包括两部分:

  1. context.getCacheDir()是您的应用程序的私有.你不能把东西放在那里,并希望另一个应用程序能够访问它.
  2. 我误解了我应该使用的MIME类型.即使我发送电子邮件文本,我还是需要image/png为了附件而指定.

此外,研究表明,将(可能很大的)图像放在主存储器上并不是一个好主意,即使你要立即清理它.

一旦我做了这些事情并将我生成的图像写入SD卡上的公共位置,它就可以正常工作.

因此,概述:

在清单中请求SD卡访问

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)

确保SD卡可用

if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) 
{
    //Bail gracefully
}
Run Code Online (Sandbox Code Playgroud)

在SD卡上创建目录

File pngDir = new File(
    Environment.getExternalStorageDirectory(),   
    //Loose convention inferred from app examples
    "Android/data/com.somedomain.someapp/flotsam");

if (!pngDir.exists())
    pngDir.mkdirs();
Run Code Online (Sandbox Code Playgroud)

将您的文件写入该目录并捕获Uri

File pngFile = new File(pngDir, "jetsam.png");
//Save file encoded as PNG
Uri pngUri = Uri.fromFile(pngFile);
Run Code Online (Sandbox Code Playgroud)

建立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);
Run Code Online (Sandbox Code Playgroud)

然后开始活动

context.startActivity(Intent.createChooser(intent, "Something Pithy"));
Run Code Online (Sandbox Code Playgroud)

然后确保你清理一切......

警告1

似乎有更多支持特定于应用程序的SD卡目录,但唉,不是我所需的SDK版本.

警告2

这是最终对我有用的解决方案的概述.它不一定是"最佳实践"方法.

警告3

这意味着应用程序必须安装SD卡才能使图像附件功能可用,但这对我的用例完全可以接受.你的旅费可能会改变.如果SD卡不可用,我会在电子邮件中附上友好的说明,解释无法附加图像的原因以及如何纠正这种情况.