2011-05-17 23 views
7

Estoy intentando cargar un archivo adjunto en mi aplicación. Puedo obtener el contenido, pero no puedo obtener el nombre del archivo.Android: obtenga el nombre del archivo adjunto en mi aplicación

Así es como mi filtro intención parece:

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

Esto es lo que me sale:

INFO/ActivityManager (97): Inicio: Intención { 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.EmailDocumentActivityJpegPid} de 97

En mi actividad me sale el Uri y lo utilizan para obtener el flujo de entrada para el contenido del archivo:

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

¿Dónde puedo encontrar el nombre del archivo en este escenario?

+0

¿Ha intentado agregar **

Respuesta

7

que tenían el mismo problema que resolver hoy y terminamos encontrar la solución en otro post: Android get attached filename from gmail app La idea principal es que el URI se obtiene se puede utilizar tanto para recuperar el contenido del archivo y para consultar para obtener más información. hice una función de utilidad rápida para recuperar el nombre:

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

Usted puede usarlo de esta manera en su actividad:

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

que trabajó para mí (recuperar el nombre de los archivos PDF).

+1

Esto funcionará con la aplicación de Gmail, pero no para correo K-9 y tal vez otros. Para que funcione con Gmail y K-9, solo tiene que agregar una proyección al 'resolver.query()', como algunas de las otras respuestas: 'final String [] projection = {MediaStore.MediaColumns.DISPLAY_NAME}; ' –

3

Gracias a todos, he resuelto el problema. Pero quiero señalar un error anterior. Supongo que el teléfono móvil que prueba es HTC. Utilizo el código anterior para ejecutar correctamente en mi teléfono móvil HTC, pero cuando lo ejecuto en el teléfono móvil Lenovo o M9 (un teléfono móvil de China) no puedo obtener el nombre del archivo de correo electrónico. Cuando id depura el código, la variable "nameIndex" devuelve "-1" y no el número correcto "0", por lo que no puedo obtener el nombre del archivo de correo electrónico. Buscando una tarde, y finalmente resolver el problema.

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

La constante MediaStore.MediaColumns.DISPLAY_NAME resuelve a la cadena "_display_name". La matriz que ingresa con esta cadena se utiliza para seleccionar las columnas que desea obtener con la consulta. El comportamiento de null para este parámetro puede ser diferente para los distintos teléfonos? ¿Devolviendo todas las columnas (como debería según el javadoc) de los teléfonos HTC y ninguna para los demás? El javadoc indica que debe recuperar columnas específicas por motivos de rendimiento. Al no devolver nada en el argumento null, los fabricantes pueden querer aplicar este rendimiento 'optimización'.

Esto se debe, por tanto, trabajar en todos los teléfonos:

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

no puedo probar esto, porque sólo tengo un teléfono HTC :).

+0

Solo un breve mensaje: solo porque use DISPLAY_NAME en su consulta no significa que va a ser uno de los nombres de columna en los resultados. Por lo menos, algunos dispositivos Motorola devuelven "title" en su lugar, por lo que podría tener más sentido utilizar cursor.getColumnIndex (cursor.getColumnNames() [0]) en su lugar si desea una solución más universal. – Nick

+0

@Nick Eso no suena muy robusto. Podría ser más seguro probar 'TITLE' específicamente si' DISPLAY_NAME' no existe. – Rich

+0

En teoría, si solo consulta el nombre para mostrar, solo debe haber 1 columna en los resultados que contengan la información que desea ... por supuesto, en teoría, el nombre de columna en los resultados también debe coincidir con la columna que se pasa a la consulta. . – Nick

2

Aquí hay una "solución combinada".Tenga en cuenta la caída final utilizando mimeType. Deberá definir el método 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 ""; } 
} 
Cuestiones relacionadas