Android - get email attachment name in my application
Asked Answered
V

4

7

I'm trying to load an email attachment in my application. I can get the content, but I cannot get the file name.

Here's how my intent filter looks like:

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

Here is what I get:

INFO/ActivityManager(97): Starting: Intent { act=android.intent.action.VIEW dat=content://gmail-ls/messages/john.doe%40gmail.com/42/attachments/0.1/SIMPLE/false typ=image/jpeg flg=0x3880001 cmp=com.myapp/.ui.email.EmailDocumentActivityJpeg } from pid 97

In my activity I get the Uri and use it to get the input stream for the file content:

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

Where can I find the file name in this scenario?

Vannesavanness answered 17/5, 2011 at 18:38 Comment(1)
Have you tried adding <data android:host="gmail-ls"?Spleenwort
B
9

I had the same problem to solve today and ended up finding the solution in another post : Android get attached filename from gmail app The main idea is that the URI you get can be used both for retrieving the file content and for querying to get more info. I made a quick utility function to retrieve the name :

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;
    }
}

You can use it this way in your activity :

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

That worked for me (retrieving the name of PDF files).

Broderic answered 15/6, 2011 at 20:10 Comment(1)
This will work with the Gmail app, but not for K-9 mail and perhaps others. To make it work with Gmail and K-9, you just need to add a projection to the resolver.query(), like some of the other answers: final String[] projection = { MediaStore.MediaColumns.DISPLAY_NAME };Choreodrama
S
4

The constant MediaStore.MediaColumns.DISPLAY_NAME resolves to the string "_display_name". The array you put in with this string is used to select the columns you want to get with the query. The behavior of null for this parameter might be different for the various phones? Returning all columns (as it should according to the javadoc) by HTC phones and none for others? The javadoc states you should retrieve specific columns for performance reasons. By returning nothing on the null argument, the manufacturers might want to enforce this performance 'optimization'.

This should therefore work on all phones:

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;    
}

I cannot test this, because I only have a HTC phone :).

Samira answered 22/2, 2012 at 8:16 Comment(3)
Just a quick FYI: just because you use DISPLAY_NAME in your query doesnt mean it's going to be one of the column names in the results. At the very least, some Motorola devices return "title" instead, so it could make more sense to use cursor.getColumnIndex(cursor.getColumnNames()[0]) instead if you want a more universal solution.Wallas
@Wallas That doesn't sound very robust. Might be safer to test for TITLE specifically if DISPLAY_NAME doesn't exist.Aggy
In theory if you only query for the display name then there should only be 1 column in the results containing the info you want...of course in theory the column name in the results should also match the column passed into the query...Wallas
A
3

Thank you everyone, i solved the problem. But i want to point out an error above. I guess the mobile phone you test is HTC. I use the code above run correctly on my HTC mobile phone, but when i run it on Lenovo mobile phone or M9(A mobile phone from China) i can not get the name of the email file. When id debug the code the variable "nameIndex" return "-1" not the correct number "0", so i can not get the name of the email file. Looking for an afternoon, and finally solve the problem.

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;
}

}

Aldoaldol answered 23/12, 2011 at 14:38 Comment(0)
C
2

Here's a "combo solution". Note the final fallback using the mimeType. You will need to define the toExtension() method...

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 ""; }
}
Crook answered 16/10, 2014 at 14:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.