Android múltiples archivos adjuntos de correo electrónico usando Intent

98

He estado trabajando en un programa de Android para enviar correos electrónicos con un archivo adjunto (archivo de imagen, archivo de audio, etc.) usando Intent con ACTION_SEND. El programa funciona cuando el correo electrónico tiene un solo archivo adjunto. Solía Intent.putExtra(android.content.Intent.EXTRA_STREAM, uri)adjuntar el archivo de imagen designado al correo y está funcionando bien, el correo se puede entregar a través de Gmail. Sin embargo, cuando intenté adjuntar varias imágenes al mismo correo llamando Intent.putExtra(android.content.Intent.EXTRA_STREAM, uri)varias veces, no funcionó. Ninguno de los archivos adjuntos aparece en el correo electrónico.

Busqué en la documentación del SDK y en el grupo de usuarios de programación de Android sobre archivos adjuntos de correo electrónico, pero no puedo encontrar ninguna información relacionada. Sin embargo, descubrí que hay otra constante de intención ACTION_SEND_MULTIPLE(disponible desde el nivel 4 de API) que podría cumplir con mi requisito. Basado en la documentación del SDK, simplemente indica que entrega múltiples datos a otra persona, funciona como ACTION_SEND, excepto que los datos son múltiples. Pero todavía no pude averiguar el uso correcto de este comando. Traté de declarar la intención con ACTION_SEND_MULTIPLE, luego llamé putExtra(EXTRA_STREAM, uri)varias veces para adjuntar varias imágenes, pero obtuve el mismo resultado erróneo como antes, ninguno de los archivos adjuntos aparece en el correo electrónico.

¿Alguien lo ha probado ACTION_SEND_MULTIPLEy lo ha hecho funcionar con varios archivos adjuntos de correo electrónico?

aaaa1234
fuente
Tengo el mismo problema. No es código de trabajo. Existe el mismo problema durante el envío de MMS, existe la posibilidad de agregar solo un archivo. ¿Tienes algunas ideas de otra manera?

Respuestas:

187

Aquí está el código que necesita para crear un emailIntent que contenga múltiples archivos adjuntos.

public static void email(Context context, String emailTo, String emailCC,
    String subject, String emailText, List<String> filePaths)
{
    //need to "send multiple" to get more than one attachment
    final Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
    emailIntent.setType("text/plain");
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, 
        new String[]{emailTo});
    emailIntent.putExtra(android.content.Intent.EXTRA_CC, 
        new String[]{emailCC});
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); 
    emailIntent.putExtra(Intent.EXTRA_TEXT, emailText);
    //has to be an ArrayList
    ArrayList<Uri> uris = new ArrayList<Uri>();
    //convert from paths to Android friendly Parcelable Uri's
    for (String file : filePaths)
    {
        File fileIn = new File(file);
        Uri u = Uri.fromFile(fileIn);
        uris.add(u);
    }
    emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
    context.startActivity(Intent.createChooser(emailIntent, "Send mail..."));
}
Gregm
fuente
2
olvidó poner el asunto y el texto del correo electrónico en la intención. de lo contrario, gracias por el código.
Bahadır Yağan
5
El tipo de datos MIME correcto debe ser "text / plain" y no "simple / texto": emailIntent.setType("text/plain");. Si usa "sin formato / texto", Android forzará a usar GMail como remitente, pero si usa "texto / sin formato", proporcionará un diálogo de selección de aplicaciones con Gmail, Facebook, Bluetooth, etc. Si desea proponer solo programas de correo utilice "texto / xml" en su lugar.
Idolon
4
Y si cambia la última línea a context.startActivity(emailIntent);la casilla de verificación "Usar de forma predeterminada para esta acción" aparecerá en el cuadro de diálogo del selector de aplicaciones, por lo que el usuario podrá seleccionar la aplicación predeterminada para enviar los correos electrónicos con varios archivos adjuntos.
Idolon
2
Este ejemplo me está generando una "AndroidRuntimeException: llamar a startActivity () desde fuera de un contexto de actividad requiere la marca FLAG_ACTIVITY_NEW_TASK. ¿Es esto realmente lo que quieres?" He intentado pasar tanto la aplicación como el contexto base a este método de correo electrónico, y ambos dan como resultado el mismo error.
Ravemir
Esto me resolvió, pero no estoy seguro de si me estoy escapando de un error de una manera extraña, así que dejaré el comentario anterior aquí para cualquiera que tenga alguna idea al respecto.
ravemir
29

ACTION_SEND_MULTIPLE debería ser la acción

y entonces emailIntent.setType("text/plain");

seguido por:

ArrayList<Uri> uris = new ArrayList<Uri>();
String[] filePaths = new String[] {"sdcard/sample.png", "sdcard/sample.png"};
for (String file : filePaths)
{
    File fileIn = new File(file);
    Uri u = Uri.fromFile(fileIn);
    uris.add(u);
}
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(emailIntent);

Esto funciona para mi.

santhana
fuente
19

Aunque este es un hilo antiguo, pero como se muestra en la parte superior de las búsquedas de Google, quiero agregar una pequeña pista para completarlo, por lo que me tropecé con él.

Es necesario hacer que los archivos adjuntos sean legibles para la actividad de correo, de lo contrario no se adjuntarán. Entonces tienes que llamar a alguna parte

fileIn.setReadable(true, false)
Thomas
fuente
Gracias señor, el correo no pudo enviar los archivos adjuntos solo el correo.
Josejulio
¡Gracias hombre! No pude hacer que las fotos se envíen sin esta línea
Konunger
¡GUAUU! esta respuesta me salvó totalmente el día. Si alguien recibe el error "uno o más archivos no adjuntos. Límite de 20 MB" de la aplicación Gmail, esta solución lo resuelve todo. ¡El mejor consejo de todos!
belphegor
2

Para múltiples archivos adjuntos, use PutParcelableArrayListExtra(Intent.ExtraStream, uris)donde la variable uris es List<IParcelable>(). un ejemplo:

var email = new Intent(Intent.ActionSendMultiple);
    email.SetType("text/plain");
    email.PutExtra(Intent.ExtraEmail, new string[]{emailTo});
    email.PutExtra(Intent.ExtraCc, new string[]{emailCC});

    var uris = new List<IParcelable>();
    filePaths.ForEach(file=> {
        var fileIn = new File(file);
        var uri = Android.Net.Uri.FromFile(fileIn);
        uris.Add(uri);
    });

    email.PutParcelableArrayListExtra(Intent.ExtraStream, uris);

    context.StartActivity(Intent.CreateChooser(email, "Send mail..."));

Espero que esto ayude ;)

Michele Caggiano
fuente