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 - 在我的应用程序中获取电子邮件附件名称的主要内容,如果未能解决你的问题,请参考以下文章
在我的 Android 应用程序中获取“原因:java.lang.RuntimeException”
如何在Spring Security中获取用户名(在我的情况下是电子邮件)[UserDetails / String]