7 votes

Android - obtenir le nom de la pièce jointe d'un courriel dans mon application

J'essaie de charger une pièce jointe de courriel dans mon application. Je peux obtenir le contenu, mais je ne peux pas obtenir le nom du fichier.

Voici à quoi ressemble mon filtre d'intention :

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

Voici ce que j'obtiens :

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 } de pid 97

Dans mon activité, je récupère l'Uri et l'utilise pour obtenir le flux d'entrée du contenu du fichier :

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

Où puis-je trouver le nom du fichier dans ce scénario ?

9voto

Gregory Points 2660

J'ai eu le même problème à résoudre aujourd'hui et j'ai fini par trouver la solution dans un autre post : Android récupère le nom du fichier joint à partir de l'application gmail L'idée principale est que l'URI que vous obtenez peut être utilisé à la fois pour récupérer le contenu du fichier et pour faire des requêtes pour obtenir plus d'informations. J'ai créé une fonction utilitaire rapide pour récupérer le nom :

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

Vous pouvez l'utiliser de cette manière dans votre activité :

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

Cela a fonctionné pour moi (récupération du nom des fichiers PDF).

4voto

Jop van Raaij Points 213

La constante MediaStore.MediaColumns.DISPLAY_NAME se résout en la chaîne de caractères "_display_name" . Le tableau que vous saisissez avec cette chaîne est utilisé pour sélectionner les colonnes que vous souhaitez obtenir avec la requête. Le comportement de null pour ce paramètre pourrait être différente pour les différents téléphones ? Retourner toutes les colonnes (comme cela devrait être le cas selon la javadoc) pour les téléphones HTC et aucune pour les autres ? La javadoc indique que vous devez récupérer des colonnes spécifiques pour des raisons de performance. En ne retournant rien sur le paramètre null les fabricants pourraient vouloir appliquer cette "optimisation" des performances.

Cela devrait donc fonctionner sur tous les télé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;    
}

Je ne peux pas le tester, car je n'ai qu'un téléphone HTC :).

3voto

GaoMatrix Points 31

Merci à tous, j'ai résolu le problème. Mais je veux signaler une erreur ci-dessus. Je suppose que le téléphone mobile que vous testez est HTC. Le code ci-dessus s'exécute correctement sur mon téléphone mobile HTC, mais lorsque je l'exécute sur un téléphone mobile Lenovo ou M9 (un téléphone mobile de Chine), je ne peux pas obtenir le nom du fichier e-mail. Quand je débogue le code, la variable "nameIndex" renvoie "-1" et non le nombre correct "0", donc je ne peux pas obtenir le nom du fichier e-mail. Je cherche un après-midi, et enfin résoudre le problème.

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

}

2voto

BuvinJ Points 21

Voici une "solution combinée". Notez la solution de repli finale utilisant le mimeType. Vous devrez définir la méthode 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 ""; }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X