Android Gmail应用 - 邮件附件URI问题

时间:2011-06-30 10:49:47

标签: android gmail

我必须通过我的应用程序从gmail应用程序打开附件文件。

我在内容中获得了链接://gmail-ls/messages/mailid%40gmail.com/4/attachments/0.1/BEST/false

我的问题是邮件客户端中的每个文件的链接都不是唯一的.. 一个或多个文件具有相同的 Uri

有没有办法获取文件名或电子邮件发送日期,以便我可以解决这个问题。

提前致谢。

4 个答案:

答案 0 :(得分:7)

如下所示,您可以制作相同附件的本地副本并处理该文件。直接你无法访问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>

答案 1 :(得分:2)

我以间接的方式解决了这个问题。

我使用文件大小确定了唯一性。

如果您需要此处的代码,则为

InputStream is = getContentResolver().openInputStream(uri);
FILE_SIZE=is.available();

答案 2 :(得分:0)

我最近遇到了同样的问题,并找到了获取文件名的方法:

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());

问候。

答案 3 :(得分:0)

谢谢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();