14

最终目标将很快明确。

我想创建一个文件对象,而不是从真实的物理文件中获取数据,我想自己提供缓冲区。

然后,我想使用这个文件,它实际上并不存在于 sdcard 或我的应用程序之外的任何地方,给它一个名称并通过电子邮件作为附件发送(使用 EXTRA_STREAM)。

我找到了 Adriaan Koster (@adriaankoster) 的以下代码,在 Java 中将字节 [] 写入文件

// convert byte[] to File
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
File fileFromBytes = (File) ois.readObject();
bis.close();
ois.close();

System.out.println(fileFromBytes);

我用它来创建这个功能

private File fileFromBytes(byte[] buf) {
    File f = null;
    try {
        ByteArrayInputStream bis = new ByteArrayInputStream(buf);
        ObjectInputStream ois = new ObjectInputStream(bis);
        f = (File) ois.readObject();
        bis.close();
        ois.close();
    }
    catch (Exception e) {}
    return f;
}

这就是我卡住的地方,因为当我使用它时:

// When sent as body the mail is sent OK
// emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, dump());

// When I try to attach the mail is empty
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, fileFromBytes(dump().getBytes()));

我从示例中知道第二个参数应该是一个 URI,但是:如何创建一个虚拟URI 来适应我的文件?

编辑: 直接从应用程序中附加数据的选项对于某些类型的应用程序很重要。即,不想过多移动敏感数据的安全和银行应用程序。当然,如果数据没有到达 SD 卡并直接进入邮件附件,则比在应用程序内存中更难嗅探。
这不是我的具体情况,但我想指出,拥有这种能力很重要。

4

4 回答 4

6

我想,您要做的第一件事就是创建一个 ContentProvider。您可以在此处查看示例实现

https://github.com/dskinner/AndroidWeb/blob/master/src/org/tsg/web/WebContentProvider.java

在上述链接的情况下,您可以将其添加到您的 AndroidManifest.xml

<provider
    android:name="org.tsg.web.WebContentProvider"
    android:authorities="your.package.name" />

现在,您将拥有一个可供使用的内容 uri content://your.package.name/,.

我想,您对上述 ContentProvider 感兴趣的部分是openFile方法。在跨应用程序按意图共享数据时,某些事情是预期的。在您的情况下,您希望共享一些要附加到电子邮件的字节数据。

因此,如果您将内容 uri 传递给电子邮件应用程序,例如content://your.package.name/foo带有适当的意图标志,那么openFile您的 ContentProvider 将被调用。在这种情况下,您可以检查 uri 段的末尾以查看foo是否被请求,并适当地返回。

您提出的下一个问题是实际上没有文件在磁盘上。虽然我不能保证您在上面使用的方法(尽管它看起来很干净),但您需要返回的是ParcelFileDescriptor来自 ContentProvider 的 a。如果您查看我提供的链接,您可能会尝试将其用作示例以从您的对象中获取文件描述符File(我的知识在这里放弃),但我想,此时数据根本不可用。

不过,您提出的是安全性。请务必注意,您可以私下将数据写入磁盘,因此只有应用程序可以访问数据。我相信,但是您可能需要仔细检查一下,如果该数据对应用程序是私有的,您可以通过 ContentProvider 公开它,并可能锁定谁以及如何使用该提供程序,谁可以调用它等。您可以想深入了解该部分的 android 文档或查看其他一些 SO 问题。

无论如何,祝你好运。

于 2012-06-02T05:52:55.377 回答
1

在应用程序的缓存目录中创建文件。它将在内部文件系统中创建。使用 'getCacheDir()' API 获取缓存目录的路径。将数据写入此目录,然后使用“Uri.fromFile (File file)”从 File 对象中获取 URI。完成文件后,将其删除。

您的应用程序的缓存仅对您的应用程序可用,因此可以安全地用于您的目的。

如果数据太关键,您可以进行一些加密。

于 2012-05-29T18:30:31.367 回答
1

我认为为了做到这一点,你将不得不公开一个 ContentProvider,这将允许你处理一个 URI。然后,电子邮件应用程序应在您的 URI 上打开InputStream,此时您在内存数据上返回一个 InputStream。

我没有尝试过,但理论上这应该可行。

于 2012-06-01T12:56:28.947 回答
0

我正忙于为邮件添加附件,我可以发送带有附件的邮件。如果你想看看:不能在Android中发送带附件的邮件

于 2012-05-09T18:08:18.587 回答