【问题标题】:Android: How do I attach a temporary, generated image to an email?Android:如何将生成的临时图像附加到电子邮件中?
【发布时间】:2011-04-04 00:14:29
【问题描述】:

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

但是我该怎么做呢?

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

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

我什至尝试过将我的图像完全编码为 data:image/png;base64,ABCD... 样式的 URI。这也显示在 Gmail 预览中(附件图标,但没有文件名),但没有导致收件人端附件。

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

【问题讨论】:

    标签: android image email attachment dynamically-generated


    【解决方案1】:

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

    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 卡不可用,我会在电子邮件中附加一个友好的说明,解释为什么无法附加图像以及如何纠正这种情况。

    【讨论】:

    • 这可以通过自定义ContentProvider 来完成。它不需要额外的权限,也消除了对 SD 卡的依赖。
    • @HRJ 您能否详细说明这种可能性并提供答案?我很想看到更多关于如何做到这一点的细节......
    • 这个解决方案不适合我。最奇怪的是,图像文件是在 sd 卡上创建的!
    • @Paschalis 你的目标是什么版本的安卓?我已经有一段时间没有使用这个解决方案了......
    • 目标是 4.1 @devfuel 。最小 SDK 2.0,最大 4.1,目标 4.1
    【解决方案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 可以附加这些文件。我刚刚写了一个blog post 来告诉你怎么做。

    希望对你有所帮助:)

    【讨论】:

    • ContentProvider 是我采用的解决方案。我不希望每个人都能从 SD 卡中读取我的文件。
    【解决方案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..."));
    

    【讨论】:

      猜你喜欢
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      相关资源
      最近更新 更多