最终目标很快就会明确。
我想创建一个文件对象,而不是从真实的物理文件中获取数据,我想自己提供缓冲区。
然后,我想使用这个文件,它不是真正存在于SD卡中或我应用程序之外的任何地方,给它起一个名字并通过电子邮件作为附件发送(使用EXTRA_STREAM)。
我发现以下一点代码,由Adriaan Koster(@adriaankoster),帖子Write byte[] to File in 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卡并直接进入邮件附件,则比应用程序内存中的数据更难嗅。 这不是我的具体情况,但我想指出这种能力很重要。
答案 0 :(得分: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
),则会在您的ContentProvider上调用openFile
。在这种情况下,您可以检查uri段的结尾以查看请求foo
,并正确返回。
您提出的下一个问题是文件实际上没有在磁盘上。虽然我不能保证你上面使用的方法(虽然它看起来像犹太洁食),但你需要返回的是来自ContentProvider的ParcelFileDescriptor
。如果你查看我提供的链接,你可能会尝试使用它作为样本从File
对象获取文件描述符(我的知识在这里放弃),但我想,数据根本不可用于那一点。
你所提出的是安全性。请务必注意,您可以私下将数据写入磁盘,这样只有应用才能访问数据。我相信,但您可能需要仔细检查,如果该数据是应用程序的私有数据,您可以通过ContentProvider公开它,并可能锁定提供商的使用者和方式,谁可以调用它等等。想深入研究该部分的Android文档,或者查看其他一些SO问题。
无论如何,祝你好运。
答案 1 :(得分:1)
在应用程序的缓存目录中创建文件。它将在内部文件系统中创建。使用'getCacheDir()'API获取缓存目录的路径。将数据写入此目录,然后使用'Uri.fromFile(File file)'从File对象获取URI。完成文件后,将其删除。
您的应用程序的缓存仅适用于您的应用程序,因此可以安全地用于您的目的。
如果数据过于严重,您可以进行一些加密。
答案 2 :(得分:1)
我认为为了做到这一点,你将不得不公开一个ContentProvider,它允许你处理一个URI。然后,电子邮件应用程序应该在您的URI上打开openInputStream,此时您将在内存数据中返回一个InputStream。
我没有尝试过,但理论上这应该可行。
答案 3 :(得分:0)
我正忙着为邮件添加附件,我可以发送带附件的邮件。 如果你想看看:can not send mail with attachment in Android