¿Por qué no se envía mi email? (Javamail)

publicado por: Anonymous

Estoy utilizando Javamail para enviar email en un principio creo que lo tengo todo bien, pero no conseguido enviar los email, no recibo ningún error en el Logcat, parece que todo sale bien pero no es así, no se envía el email

Este es mi código, MainActivity:

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    private Mail m;

    Button send_email;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        m = new Mail("[email protected]", "clave");

        send_email = (Button) findViewById(R.id.send_email);

        send_email.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new SendMail().execute("");
            }
        });

    }

        private class SendMail extends AsyncTask<String, Integer, Void> {
            protected void doInBackground() {
                    String[] toArr = {"[email protected]"};
                    m.setTo(toArr);
                    m.setFrom("[email protected]");
                    m.setSubject("Es una prueba");
                    m.setBody("Prueba");

                    try {
                        //m.addAttachment("/sdcard/abc.jpg");
                        if (m.send()) {
                            // success
                            Toast.makeText(MainActivity.this, "Emil enviado.", Toast.LENGTH_LONG).show();
                        } else {
                            // failure
                            Toast.makeText(MainActivity.this, "Email no enviado.", Toast.LENGTH_LONG).show();
                        }
                    } catch (Exception e) {
                        // some other problem
                        Toast.makeText(MainActivity.this, "" + e + "", Toast.LENGTH_LONG).show();
                        Log.e("SendMail", e.getMessage(), e);
                    }
            }

            protected void onProgressUpdate() {
                //called when the background task makes any progress
            }

            @Override
            protected Void doInBackground(String... params) {
                return null;
            }

            protected void onPreExecute() {
                //called before doInBackground() is started
            }

            protected void onPostExecute() {
                //called after doInBackground() has finished
            }
        }
    }

Y esta la clase Mail:

import java.util.Date;
import java.util.Properties;
import javax.activation.CommandMap;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.MailcapCommandMap;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class Mail extends javax.mail.Authenticator {
    private String _user;
    private String _pass;

    private String[] _to;
    private String _from;

    private String _port;
    private String _sport;

    private String _host;

    private String _subject;
    private String _body;

    private boolean _auth;

    private boolean _debuggable;

    private Multipart _multipart;


    public Mail() {
        _host = "smtp.gmail.com"; // default smtp server
        _port = "465"; // default smtp port
        _sport = "465"; // default socketfactory port

        _user = ""; // username
        _pass = ""; // password
        _from = ""; // email sent from
        _subject = ""; // email subject
        _body = ""; // email body

        _debuggable = false; // debug mode on or off - default off
        _auth = true; // smtp authentication - default on

        _multipart = new MimeMultipart();

        // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added.
        MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
        mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
        mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
        mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
        mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
        mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
        CommandMap.setDefaultCommandMap(mc);
    }

    public Mail(String user, String pass) {
        this();

        _user = user;
        _pass = pass;
    }

    public boolean send() throws Exception {
        Properties props = _setProperties();

        if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) {
            Session session = Session.getInstance(props, this);

            MimeMessage msg = new MimeMessage(session);

            msg.setFrom(new InternetAddress(_from));

            InternetAddress[] addressTo = new InternetAddress[_to.length];
            for (int i = 0; i < _to.length; i++) {
                addressTo[i] = new InternetAddress(_to[i]);
            }
            msg.setRecipients(MimeMessage.RecipientType.TO, addressTo);

            msg.setSubject(_subject);
            msg.setSentDate(new Date());

            // setup message body
            BodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText(_body);
            _multipart.addBodyPart(messageBodyPart);

            // Put parts in message
            msg.setContent(_multipart);

            // send email
            Transport.send(msg);

            return true;
        } else {
            return false;
        }
    }

    public void addAttachment(String filename) throws Exception {
        BodyPart messageBodyPart = new MimeBodyPart();
        DataSource source = new FileDataSource(filename);
        messageBodyPart.setDataHandler(new DataHandler(source));
        messageBodyPart.setFileName(filename);

        _multipart.addBodyPart(messageBodyPart);
    }

    @Override
    public PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(_user, _pass);
    }

    private Properties _setProperties() {
        Properties props = new Properties();

        props.put("mail.smtp.host", _host);

        if(_debuggable) {
            props.put("mail.debug", "true");
        }

        if(_auth) {
            props.put("mail.smtp.auth", "true");
        }

        props.put("mail.smtp.port", _port);
        props.put("mail.smtp.socketFactory.port", _sport);
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");

        return props;
    }

    // the getters and setters
    public String getBody() {
        return _body;
    }

    public void setBody(String _body) {
        this._body = _body;
    }

    public void setTo(String[] toArr) {
        this._to = toArr;
    }

    public void setFrom(String string) {
        this._from = string;
    }

    public void setSubject(String string) {
        this._subject = string;
    }
}

Tengo las tres librerías mail, additionnal y activation importadas, y en AndroidManifest:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

¿Alguien me puede ayudar? Gracias!

EDITO1: Utilizando la librería GmailBackground que me comenta @Webserveis funciona perfectamente, pero, cuando intento enviar el email desde otro móvil no se envía, mirando la cuenta que tengo escrita en el código para enviar email me doy cuenta que Gmail bloquea el envío porque se ha conectado desde otro dispositivo, que puedo hacer para que se pueda enviar desde cualquier móvil pero con la misma cuenta de Gmail? Se puede hacer algo? Tengo activado que se puedan conectar aplicaciones menos seguras.

solución

Prueba con algunos de estos tutoriales acerca de JavaMail, yo nunca lo he usado.

Pero ten en cuenta que para enviar emails se debe usar un servidor de email lo cual debes tener un login activado en el, por ejemplo si quieres usar el servidor de Gmail de google, debes tener una cuenta Gmail.

Java email con servidor google en este tutorial ya te dice que debes proporcionar tu usuario sin @Gmail.com

Otro tutorial más completo aquí veo que para que puedas usar el servidor de Gmail, des de un origen distinto debes activar el Enlace Aplicaciones menos seguras

Esta configuración no está disponible para las cuentas que tienen
habilitada la verificación en dos pasos. Dichas cuentas requieren una
contraseña específica de la aplicación para acceder a las aplicaciones
menos seguras

introducir la descripción de la imagen aquí

Ejemplo básico

la configuración de la cuenta está en sendEmail()

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MainActivity extends AppCompatActivity {

    private Properties emailProperties;
    private Session mailSession;
    private MimeMessage emailMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setMailServerProperties();
        createEmailMessage();
        sendEmail();

    }

   public void setMailServerProperties() {

        String emailPort = "587";//gmail's smtp port

        emailProperties = System.getProperties();
        emailProperties.put("mail.smtp.port", emailPort);
        emailProperties.put("mail.smtp.auth", "true");
        emailProperties.put("mail.smtp.starttls.enable", "true");

    }

    public void createEmailMessage() throws AddressException,
            MessagingException {
        String[] toEmails = { "[email protected]" };
        String emailSubject = "Java Email";
        String emailBody = "This is an email sent by JavaMail api.";

        mailSession = Session.getDefaultInstance(emailProperties, null);
        emailMessage = new MimeMessage(mailSession);

        for (int i = 0; i < toEmails.length; i++) {
            emailMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmails[i]));
        }

        emailMessage.setSubject(emailSubject);
        emailMessage.setContent(emailBody, "text/html");//for a html email
        //emailMessage.setText(emailBody);// for a text email

    }

    public void sendEmail() throws AddressException, MessagingException {

        String emailHost = "smtp.gmail.com";
        String fromUser = "your emailid here";//just the id alone without @gmail.com
        String fromUserEmailPassword = "your email password here";

        Transport transport = mailSession.getTransport("smtp");

        transport.connect(emailHost, fromUser, fromUserEmailPassword);
        transport.sendMessage(emailMessage, emailMessage.getAllRecipients());
        transport.close();
        System.out.println("Email sent successfully.");
    }

} 

Librerias para Gmail

GmailBackground es una librería que simplifica el proceso de enviar el email

BackgroundMail.newBuilder(this)
        .withUsername("[email protected]")
        .withPassword("password12345")
        .withMailto("[email protected]")
        .withType(BackgroundMail.TYPE_PLAIN)
        .withSubject("this is the subject")
        .withBody("this is the body")
        .withOnSuccessCallback(new BackgroundMail.OnSuccessCallback() {
            @Override
            public void onSuccess() {
                //do some magic
            }
        })
        .withOnFailCallback(new BackgroundMail.OnFailCallback() {
            @Override
            public void onFail() {
                //do some magic
            }
        })
        .send();
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *