¿Cómo puedo enviar correos electrónicos desde mi aplicación Android?

Estoy escribiendo una aplicación para Android. ¿Cómo puedo enviar un correo electrónico desde allí?

La mejor (y más fácil) forma es usar un Intent :

 Intent i = new Intent(Intent.ACTION_SEND); i.setType("message/rfc822"); i.putExtra(Intent.EXTRA_EMAIL , new String[]{"recipient@example.com"}); i.putExtra(Intent.EXTRA_SUBJECT, "subject of email"); i.putExtra(Intent.EXTRA_TEXT , "body of email"); try { startActivity(Intent.createChooser(i, "Send mail...")); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(MyActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show(); } 

De lo contrario, tendrás que escribir tu propio cliente.

Use .setType("message/rfc822") o el selector le mostrará todas las (muchas) aplicaciones que admiten el bash de envío.

He estado usando esto desde hace mucho tiempo y me parece bien, no aparecen aplicaciones que no sean de correo electrónico. Simplemente otra forma de enviar un bash de enviar un correo electrónico:

 Intent intent = new Intent(Intent.ACTION_SENDTO); // it's not ACTION_SEND intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_SUBJECT, "Subject of email"); intent.putExtra(Intent.EXTRA_TEXT, "Body of email"); intent.setData(Uri.parse("mailto:default@recipient.com")); // or just "mailto:" for blank intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // this will make such that when user returns to your app, your app is displayed, instead of the email app. startActivity(intent); 

Estaba usando algo similar a la respuesta actualmente aceptada para enviar correos electrónicos con un archivo de registro de errores binarios adjunto. GMail y K-9 lo envían bien y también llega bien a mi servidor de correo. El único problema fue mi cliente de correo de elección Thunderbird que tuvo problemas para abrir / guardar el archivo de registro adjunto. De hecho, simplemente no guardó el archivo en absoluto sin quejarse.

Eché un vistazo a uno de los códigos fuente de este correo y me di cuenta de que el archivo adjunto tenía (comprensiblemente) el message/rfc822 tipo mime message/rfc822 . Por supuesto, ese archivo adjunto no es un correo electrónico adjunto. Pero Thunderbird no puede lidiar con ese pequeño error con gracia. Así que eso fue un poco fastidioso.

Después de un poco de investigación y experimentación, se me ocurrió la siguiente solución:

  public Intent createEmailOnlyChooserIntent(Intent source, CharSequence chooserTitle) { Stack intents = new Stack(); Intent i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", "info@domain.com", null)); List activities = getPackageManager() .queryIntentActivities(i, 0); for(ResolveInfo ri : activities) { Intent target = new Intent(source); target.setPackage(ri.activityInfo.packageName); intents.add(target); } if(!intents.isEmpty()) { Intent chooserIntent = Intent.createChooser(intents.remove(0), chooserTitle); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[intents.size()])); return chooserIntent; } else { return Intent.createChooser(source, chooserTitle); } } 

Se puede usar de la siguiente manera:

  Intent i = new Intent(Intent.ACTION_SEND); i.setType("*/*"); i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(crashLogFile)); i.putExtra(Intent.EXTRA_EMAIL, new String[] { ANDROID_SUPPORT_EMAIL }); i.putExtra(Intent.EXTRA_SUBJECT, "Crash report"); i.putExtra(Intent.EXTRA_TEXT, "Some crash report details"); startActivity(createEmailOnlyChooserIntent(i, "Send via email")); 

Como puede ver, el método createEmailOnlyChooserIntent puede alimentarse fácilmente con la intención correcta y el tipo de mime correcto.

Luego pasa por la lista de actividades disponibles que responden a un ACTION_SENDTO bash de protocolo mailto (que son solo aplicaciones de correo electrónico) y crea un selector basado en esa lista de actividades y el bash original ACTION_SEND con el tipo de mime correcto.

Otra ventaja es que Skype ya no se encuentra en la lista (que responde al tipo de mime rfc822).

Para SOLO DEJAR APLICACIONES DE CORREO ELECTRÓNICO para resolver su bash, debe especificar ACTION_SENDTO como Acción y mailto como Datos.

 private void sendEmail(){ Intent emailIntent = new Intent(Intent.ACTION_SENDTO); emailIntent.setData(Uri.parse("mailto:" + "recipient@example.com")); emailIntent.putExtra(Intent.EXTRA_SUBJECT, "My email's subject"); emailIntent.putExtra(Intent.EXTRA_TEXT, "My email's body"); try { startActivity(Intent.createChooser(emailIntent, "Send email using...")); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(Activity.this, "No email clients installed.", Toast.LENGTH_SHORT).show(); } } 

La estrategia de usar .setType("message/rfc822") o ACTION_SEND parece coincidir con aplicaciones que no son clientes de correo electrónico, como Android Beam y Bluetooth .

El uso de ACTION_SENDTO y un mailto: URI parece funcionar perfectamente, y se recomienda en la documentación del desarrollador . Sin embargo, si haces esto en los emuladores oficiales y no hay cuentas de correo electrónico configuradas (o no hay clientes de correo), obtienes el siguiente error:

Acción no respaldada

Esa acción no es actualmente compatible.

Como se muestra abajo:

Acción no admitida: esa acción actualmente no es compatible.

Resulta que los emuladores resuelven la intención de una actividad llamada com.android.fallback.Fallback , que muestra el mensaje anterior. Aparentemente esto es por diseño.

Si desea que su aplicación evite esto para que también funcione correctamente en los emuladores oficiales, puede verificarlo antes de intentar enviar el correo electrónico:

 private void sendEmail() { Intent intent = new Intent(Intent.ACTION_SENDTO) .setData(new Uri.Builder().scheme("mailto").build()) .putExtra(Intent.EXTRA_EMAIL, new String[]{ "John Smith " }) .putExtra(Intent.EXTRA_SUBJECT, "Email subject") .putExtra(Intent.EXTRA_TEXT, "Email body") ; ComponentName emailApp = intent.resolveActivity(getPackageManager()); ComponentName unsupportedAction = ComponentName.unflattenFromString("com.android.fallback/.Fallback"); if (emailApp != null && !emailApp.equals(unsupportedAction)) try { // Needed to customise the chooser dialog title since it might default to "Share with" // Note that the chooser will still be skipped if only one app is matched Intent chooser = Intent.createChooser(intent, "Send email with"); startActivity(chooser); return; } catch (ActivityNotFoundException ignored) { } Toast .makeText(this, "Couldn't find an email app and account", Toast.LENGTH_LONG) .show(); } 

Encuentra más información en la documentación del desarrollador .

Resolví este problema con simples líneas de código según lo explica la documentación de Android.

( https://developer.android.com/guide/components/intents-common.html#Email )

La más importante es la bandera: es ACTION_SENDTO , y no ACTION_SEND

La otra línea importante es

 intent.setData(Uri.parse("mailto:")); ***// only email apps should handle this*** 

Por cierto, si envía un Extra vacío, el if() al final no funcionará y la aplicación no abrirá el cliente de correo electrónico.

De acuerdo con la documentación de Android Si desea asegurarse de que su intención sea manejada solo por una aplicación de correo electrónico (y no por otros mensajes de texto o aplicaciones sociales), utilice la acción ACTION_SENDTO e incluya el esquema de datos ” mailto: “. Por ejemplo:

 public void composeEmail(String[] addresses, String subject) { Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setData(Uri.parse("mailto:")); // only email apps should handle this intent.putExtra(Intent.EXTRA_EMAIL, addresses); intent.putExtra(Intent.EXTRA_SUBJECT, subject); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } } 

El envío de correo electrónico se puede hacer con Intents que no requieren configuración. Pero luego requerirá la interacción del usuario y el diseño será un poco restringido.

Crear y enviar un correo electrónico más complejo sin la interacción del usuario implica construir su propio cliente. Lo primero es que la API de Sun Java para correo electrónico no está disponible. He tenido éxito aprovechando la biblioteca Apache Mime4j para crear correo electrónico. Todo basado en los documentos de nilvec .

simple prueba este

  public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); buttonSend = (Button) findViewById(R.id.buttonSend); textTo = (EditText) findViewById(R.id.editTextTo); textSubject = (EditText) findViewById(R.id.editTextSubject); textMessage = (EditText) findViewById(R.id.editTextMessage); buttonSend.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String to = textTo.getText().toString(); String subject = textSubject.getText().toString(); String message = textMessage.getText().toString(); Intent email = new Intent(Intent.ACTION_SEND); email.putExtra(Intent.EXTRA_EMAIL, new String[] { to }); // email.putExtra(Intent.EXTRA_CC, new String[]{ to}); // email.putExtra(Intent.EXTRA_BCC, new String[]{to}); email.putExtra(Intent.EXTRA_SUBJECT, subject); email.putExtra(Intent.EXTRA_TEXT, message); // need this to prompts email client only email.setType("message/rfc822"); startActivity(Intent.createChooser(email, "Choose an Email client :")); } }); } 

Utilizo el siguiente código en mis aplicaciones. Esto muestra exactamente las aplicaciones cliente de correo electrónico, como Gmail.

  Intent contactIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", getString(R.string.email_to), null)); contactIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.email_subject)); startActivity(Intent.createChooser(contactIntent, getString(R.string.email_chooser))); 

Aquí está el código de trabajo de muestra que abre la aplicación de correo en el dispositivo Android y se llena automáticamente con la dirección Para y el Asunto en el correo que se está redactando.

 protected void sendEmail() { Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setData(Uri.parse("mailto:feedback@gmail.com")); intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback"); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } } 

Otra solución puede ser

 Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); emailIntent.setType("plain/text"); emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail"); emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"someone@gmail.com"}); emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Yo"); emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Hi"); startActivity(emailIntent); 

Suponiendo que la mayoría del dispositivo Android tiene la aplicación GMail ya instalada.

Use esto para enviar correos electrónicos …

 boolean success = EmailIntentBuilder.from(activity) .to("support@example.org") .cc("developer@example.org") .subject("Error report") .body(buildErrorReport()) .start(); 

usar build gradle:

 compile 'de.cketti.mailto:email-intent-builder:1.0.0' 

Esta función es la primera intención directa de Gmail para enviar correos electrónicos, si no se encuentra gmail, entonces promueve el selector de intenciones. Utilicé esta función en muchas aplicaciones comerciales y funciona bien. Espero que te ayude:

 public static void sentEmail(Context mContext, String[] addresses, String subject, String body) { try { Intent sendIntentGmail = new Intent(Intent.ACTION_VIEW); sendIntentGmail.setType("plain/text"); sendIntentGmail.setData(Uri.parse(TextUtils.join(",", addresses))); sendIntentGmail.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail"); sendIntentGmail.putExtra(Intent.EXTRA_EMAIL, addresses); if (subject != null) sendIntentGmail.putExtra(Intent.EXTRA_SUBJECT, subject); if (body != null) sendIntentGmail.putExtra(Intent.EXTRA_TEXT, body); mContext.startActivity(sendIntentGmail); } catch (Exception e) { //When Gmail App is not installed or disable Intent sendIntentIfGmailFail = new Intent(Intent.ACTION_SEND); sendIntentIfGmailFail.setType("*/*"); sendIntentIfGmailFail.putExtra(Intent.EXTRA_EMAIL, addresses); if (subject != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_SUBJECT, subject); if (body != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_TEXT, body); if (sendIntentIfGmailFail.resolveActivity(mContext.getPackageManager()) != null) { mContext.startActivity(sendIntentIfGmailFail); } } } 

Esto le mostrará solo los clientes de correo electrónico (y también PayPal por algún motivo desconocido)

  public void composeEmail() { Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setData(Uri.parse("mailto:")); intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hi@example.com"}); intent.putExtra(Intent.EXTRA_SUBJECT, "Subject"); intent.putExtra(Intent.EXTRA_TEXT, "Body"); try { startActivity(Intent.createChooser(intent, "Send mail...")); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(MainActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show(); } } 

Así es como lo hice. Agradable y simple.

 String emailUrl = "mailto:email@example.com?subject=Subject Text&body=Body Text"; Intent request = new Intent(Intent.ACTION_VIEW); request.setData(Uri.parse(emailUrl)); startActivity(request); 

Este método funciona para mí. Abre la aplicación Gmail (si está instalada) y configura mailto.

 public void openGmail(Activity activity) { Intent emailIntent = new Intent(Intent.ACTION_VIEW); emailIntent.setType("text/plain"); emailIntent.setType("message/rfc822"); emailIntent.setData(Uri.parse("mailto:"+activity.getString(R.string.mail_to))); emailIntent.putExtra(Intent.EXTRA_SUBJECT, activity.getString(R.string.app_name) + " - info "); final PackageManager pm = activity.getPackageManager(); final List matches = pm.queryIntentActivities(emailIntent, 0); ResolveInfo best = null; for (final ResolveInfo info : matches) if (info.activityInfo.packageName.endsWith(".gm") || info.activityInfo.name.toLowerCase().contains("gmail")) best = info; if (best != null) emailIntent.setClassName(best.activityInfo.packageName, best.activityInfo.name); activity.startActivity(emailIntent); } 

Usé este código para enviar correo iniciando directamente la sección de redacción de la aplicación de correo predeterminada.

  Intent i = new Intent(Intent.ACTION_SENDTO); i.setType("message/rfc822"); i.setData(Uri.parse("mailto:")); i.putExtra(Intent.EXTRA_EMAIL , new String[]{"test@gmail.com"}); i.putExtra(Intent.EXTRA_SUBJECT, "Subject"); i.putExtra(Intent.EXTRA_TEXT , "body of email"); try { startActivity(Intent.createChooser(i, "Send mail...")); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show(); }