Android - 在我的应用程序中获取电子邮件附件名称

Posted

技术标签:

【中文标题】Android - 在我的应用程序中获取电子邮件附件名称【英文标题】:Android - get email attachment name in my application 【发布时间】: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);

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

【问题讨论】:

你试过添加吗? 【参考方案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 ""; 

【讨论】:

以上是关于Android - 在我的应用程序中获取电子邮件附件名称的主要内容,如果未能解决你的问题,请参考以下文章

获取firebase android中特定值的推送ID

在我的 Android 应用程序中获取“原因:java.lang.RuntimeException”

如何在Spring Security中获取用户名(在我的情况下是电子邮件)[UserDetails / String]

在 Android 中高效处理动态列表视图项

如何获取通知 onesignal 的内容并将其显示在我的 android 应用程序中

如何在我的应用程序中获取以前使用 android 打印服务的打印机列表?