【问题标题】:Android - get email attachment name in my applicationAndroid - 在我的应用程序中获取电子邮件附件名称
【发布时间】:2011-08-27 11:47:16
【问题描述】:

我正在尝试在我的应用程序中加载电子邮件附件。可以获取内容,但无法获取文件名。

这是我的意图过滤器的样子:

        <intent-filter>
            <action
                android:name="android.intent.action.VIEW" />
            <category
                android:name="android.intent.category.DEFAULT" />
            <data
                android:mimeType="image/jpeg" />
        </intent-filter>

这是我得到的:

INFO/ActivityManager(97):开始: 意图{ 行动=android.intent.action.VIEW dat=content://gmail-ls/messages/john.doe%40gmail.com/42/attachments/0.1/SIMPLE/false 类型=图像/jpeg flg=0x3880001 cmp=com.myapp/.ui.email.EmailDocumentActivityJpeg } 从 pid 97

在我的活动中,我获取了 Uri 并使用它来获取文件内容的输入流:

InputStream is = context.getContentResolver().openInputStream(uri);

在这种情况下我在哪里可以找到文件名?

【问题讨论】:

  • 你试过添加吗?

标签: android android-intent android-contentprovider


【解决方案1】:

我今天有同样的问题要解决,最后在另一篇文章中找到了解决方案:Android get attached filename from gmail app 主要思想是您获得的 URI 既可用于检索文件内容,也可用于查询以获取更多信息。 我做了一个快速实用函数来检索名称:

public static String getContentName(ContentResolver resolver, Uri uri){
    Cursor cursor = resolver.query(uri, null, null, null, null);
    cursor.moveToFirst();
    int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
    if (nameIndex >= 0) {
        return cursor.getString(nameIndex);
    } else {
        return null;
    }
}

您可以在活动中以这种方式使用它:

Uri uri = getIntent().getData();
String name = getContentName(getContentResolver(), uri);

这对我有用(检索 PDF 文件的名称)。

【讨论】:

  • 这适用于 Gmail 应用程序,但不适用于 K-9 邮件和其他邮件。要使其与 Gmail 和 K-9 一起使用,您只需向 resolver.query() 添加投影,就像其他一些答案一样:final String[] projection = { MediaStore.MediaColumns.DISPLAY_NAME };
【解决方案2】:

常量MediaStore.MediaColumns.DISPLAY_NAME 解析为字符串"_display_name"。您与此字符串一起放入的数组用于选择您希望通过查询获得的列。 null 对于此参数的行为可能因各种手机而异?返回 HTC 手机的所有列(根据 javadoc 应该如此),而其他人则没有? javadoc 声明您应该出于性能原因检索特定列。通过在 null 参数上不返回任何内容,制造商可能希望强制执行此性能“优化”。

因此这应该适用于所有手机:

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(MediaStore.MediaColumns.DISPLAY_NAME);
    if (nameIndex >= 0) {
        return cursor.getString(nameIndex);
    }

    return null;    
}

我无法对此进行测试,因为我只有一部 HTC 手机:)。

【讨论】:

  • 仅供参考:仅仅因为您在查询中使用 DISPLAY_NAME 并不意味着它将成为结果中的列名之一。至少,某些摩托罗拉设备会返回“title”,因此如果您想要更通用的解决方案,使用 cursor.getColumnIndex(cursor.getColumnNames()[0]) 可能更有意义。
  • @Nick 这听起来不太健壮。如果DISPLAY_NAME 不存在,测试TITLE 可能会更安全。
  • 理论上,如果您只查询显示名称,那么结果中应该只有 1 列包含您想要的信息...当然理论上结果中的列名称也应该与传递到查询中的列...
【解决方案3】:

谢谢大家,我解决了这个问题。但我想指出上面的一个错误。我猜你测试的手机是HTC。我使用上面的代码在我的 HTC 手机上运行正确,但是当我在联想手机或 M9(中国手机)上运行时,我无法获取电子邮件文件的名称。当 id 调试代码时,变量“nameIndex”返回“-1”而不是正确的数字“0”,所以我无法获取电子邮件文件的名称。找了一个下午,终于解决了。

public static String getEmailFileName(ContentResolver resolver, Uri uri){
Cursor cursor = resolver.query(uri, new String[]{"_display_name"}, null, null, null);
cursor.moveToFirst();
int nameIndex = cursor.getColumnIndex("_display_name");
if (nameIndex >= 0) {
    return cursor.getString(nameIndex);
} else {
    return null;
}

}

【讨论】:

    【解决方案4】:

    这是一个“组合解决方案”。请注意使用 mimeType 的最终回退。您将需要定义 toExtension() 方法...

    private static String contentUriFilename( Uri uri ){
        String fileName="";
        if( fileName.isEmpty() )
            fileName = contentUriFilename( uri, android.provider.OpenableColumns.DISPLAY_NAME );
        if( fileName.isEmpty() )
            fileName = contentUriFilename( uri, android.provider.MediaStore.MediaColumns.DISPLAY_NAME );
        if( fileName.isEmpty() )
            fileName = contentUriFilename( uri, "_display_name" );
        if( fileName.isEmpty() ){
            String mimeType;
            try{ mimeType = context_.getContentResolver().getType( uri ); }
            catch( Exception e ){ mimeType=""; }
            fileName = "unknown." + toExtension( mimeType );
        }
        return fileName;
    }
    
    private static String contentUriFilename( Uri uri, String columnName ){
        Cursor cursor = context_.getContentResolver().query( uri,
            new String[]{columnName}, null, null, null);
        cursor.moveToFirst();
        try{
            return cursor.getString(
                        cursor.getColumnIndexOrThrow( columnName ) );
        }
        catch( Exception e ){ return ""; }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      • 2011-11-01
      • 2015-04-12
      • 2011-08-20
      • 1970-01-01
      相关资源
      最近更新 更多