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

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

但是我该怎么做?

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

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

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

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

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

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

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

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

因此,概述:

在清单中请求SD卡访问

  

确保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卡才能使图像附件function可用,但这对我的用例完全可以接受。 你的旅费可能会改变。 如果SD卡不可用,我会在电子邮件中附上友好的说明,解释无法附加图像的原因以及如何纠正这种情况。

我遇到了完全相同的问题(想要在我的情况下附加一个文本文件)。 如果你查看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可以附加它们。 我刚刚写了一篇关于如何做的博客文章 。

希望这有点帮助:)

 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..."));