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

时间:2010-08-25 23:08:26

标签: android image email attachment dynamically-generated

我有一个以编程方式生成的图片,我希望通过ACTION_SENDEXTRA_STREAM方法将其作为附件发送。

但我该怎么做?

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

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

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

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

3 个答案:

答案 0 :(得分:18)

我的问题实际上由两部分组成:

  1. context.getCacheDir()对您的应用是私有的。你不能把东西放在那里,并期望另一个应用程序能够访问它。
  2. 我误解了我应该使用的MIME类型。即使我发送电子邮件文本,我还是需要为了附件而指定image/png
  3. 此外,研究表明,将(可能很大的)图像放在主存储器上并不是一个好主意,即使你要立即清理它。

    一旦我做了这些事情并将生成的图像写入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卡不可用,我会在电子邮件中附上一封友好的说明,解释无法附加图片的原因以及如何纠正这种情况。

答案 1 :(得分:4)

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

希望这有点帮助:)

答案 2 :(得分:-1)

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