【发布时间】:2011-06-30 10:49:47
【问题描述】:
我必须通过我的应用从 gmail 应用打开附件文件。
我得到类似 content://gmail-ls/messages/mailid%40gmail.com/4/attachments/0.1/BEST/false 的模式的链接
我的问题是邮件客户端中每个文件的链接不是唯一的.. 一个或多个文件具有相同的 Uri。
有什么方法可以获取文件名或电子邮件发送日期,以便我解决这个问题。
提前致谢。
【问题讨论】:
我必须通过我的应用从 gmail 应用打开附件文件。
我得到类似 content://gmail-ls/messages/mailid%40gmail.com/4/attachments/0.1/BEST/false 的模式的链接
我的问题是邮件客户端中每个文件的链接不是唯一的.. 一个或多个文件具有相同的 Uri。
有什么方法可以获取文件名或电子邮件发送日期,以便我解决这个问题。
提前致谢。
【问题讨论】:
如下所示,您可以制作同一附件的本地副本并处理该文件。您将无法直接访问 gmail 服务器上的该文件。
Uri uri = getIntent().getData();
if (uri != null) {
try {
InputStream attachment = getContentResolver().openInputStream(uri);
if (attachment == null)
Log.e("GMAIL ATTACHMENT", "Mail attachment failed to resolve");
else {
FileOutputStream tmp = new FileOutputStream(getCacheDir().getPath() + "/temp.myfile");
byte[] buffer = new byte[1024];
while (attachment.read(buffer) > 0)
tmp.write(buffer);
tmp.close();
attachment.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return getCacheDir().getPath() + "/temp.myfile";
记得将此添加到您的清单中。
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:mimeType="application/octet-stream"
android:pathPattern=".*\\.tsconfig" />
<!-- To handle gmail attachments -->
</intent-filter>
【讨论】:
我以间接的方式解决了这个问题。
我使用文件大小确定了唯一性。
如果你需要这里的代码
InputStream is = getContentResolver().openInputStream(uri);
FILE_SIZE=is.available();
【讨论】:
我最近遇到了同样的问题,并找到了一种获取文件名的方法:
public static String getContentName(ContentResolver resolver, Uri uri){
Cursor cursor = resolver.query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null);
cursor.moveToFirst();
int nameIndex = cursor.getColumnIndex(cursor.getColumnNames()[0]);
if (nameIndex >= 0) {
return cursor.getString(nameIndex);
} else {
return null;
}
}
使用方法:
String fileName = getContentName(getContentResolver(), getIntent().getData());
问候。
【讨论】:
感谢 Lokesh Kumar,您的代码帮了大忙! 不过,我想强调一下您的解决方案存在的问题。
尝试使用您的此代码时:
FileOutputStream tmp = new FileOutputStream(getCacheDir().getPath() + "/temp.myfile");
byte[] buffer = new byte[1024];
while (attachment.read(buffer) > 0)
tmp.write(buffer);
tmp.close();
attachment.close();
它确实复制到了整个文件,但我认为有问题。
在执行attachment.read(buffer) 时,您每次读取 1024 个字节,假设您有一个 2000 个字节的文件。
在第一次读取时,您将获得第一个 1024,然后在下一次和最后一次读取时,您将获得最后 976 个字节,据我所见,在这种情况下,缓冲区不会清除最后一个字节预览读取,文件末尾将是最后一次读取的 976 字节,其余 48 字节来自最后一个之前的读取.. 这将使文件的结尾不正确。
就我而言,附件是我必须复制的 kml 文件(xml 形式的位置数据文件)。通过尝试使用此代码,我总是得到不正确的 kml 结尾。在结束标签之后,我得到了一些文本,这些文本来自最后一个之前的阅读。
类似这样的:
</Document>
</kml>
278
34.81186031,31.96118044
34.81184437,31.96122622
34.81181701,31.96127052
34.81182701,31.9612875
当然,这不是一个有效的 kml,在尝试解析它时会导致错误。
因此,我使用了一些不同的代码从输入流中读取,这些代码做得更好。
这是我复制文件的代码:
InputStream attachment = getContentResolver().openInputStream(container.uri);
FileOutputStream tmp = new FileOutputStream(container.fileName);
BufferedInputStream bis = new BufferedInputStream(attachment);
StringBuffer b = new StringBuffer();
while (bis.available() != 0) {
char c = (char) bis.read();
b.append(c);
}
bis.close();
attachment.close();
tmp.write(String.valueOf(b).getBytes());
tmp.close();
【讨论】: