使用javax邮件类通过Gmail smtp发送多封电子邮件会偶尔触发连接拒绝错误

时间:2012-04-29 22:22:11

标签: android gmail javax.mail

我使用javax邮件类通过Gmail SMTP发送多封带附件的电子邮件。 电子邮件发送在doInBackground()函数中的AsyncTask内完成。我有一个邮件的arraylist,我一个接一个地发送它们。第一封电子邮件发送成功,但从下一封电子邮件中我收到MessagingException:无法连接到SMTP主机。 我不太清楚为什么会出现这个问题。是否可能未释放所需的资源?有谁知道这个问题的解决方案?

  

04-30 10:10:25.109:W / System.err(619):javax.mail.MessagingException:无法连接到SMTP主机:localhost,port:25;   04-30 10:10:25.109:W / System.err(619):嵌套异常是:   04-30 10:10:25.109:W / System.err(619):java.net.ConnectException:localhost / 127.0.0.1:25 - 连接被拒绝   04-30 10:10:25.109:W / System.err(619):at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1391)   04-30 10:10:25.109:W / System.err(619):at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412)   04-30 10:10:25.109:W / System.err(619):at javax.mail.Service.connect(Service.java:288)   04-30 10:10:25.109:W / System.err(619):at javax.mail.Service.connect(Service.java:169)   04-30 10:10:25.109:W / System.err(619):at javax.mail.Service.connect(Service.java:118)   04-30 10:10:25.109:W / System.err(619):at javax.mail.Transport.send0(Transport.java:188)   04-30 10:10:25.109:W / System.err(619):at javax.mail.Transport.send(Transport.java:118)   04-30 10:10:25.109:W / System.err(619):at com.waratah.app.Mail.send(Mail.java:123)   04-30 10:10:25.109:W / System.err(619):at com.waratah.app.ScheduledService $ SendEmailAsyncTask.doInBackground(ScheduledService.java:1368)   04-30 10:10:25.109:W / System.err(619):at com.waratah.app.ScheduledService $ SendEmailAsyncTask.doInBackground(ScheduledService.java:1)   04-30 10:10:25.109:W / System.err(619):在android.os.AsyncTask $ 2.call(AsyncTask.java:185)   04-30 10:10:25.109:W / System.err(619):at java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:306)   04-30 10:10:25.109:W / System.err(619):at java.util.concurrent.FutureTask.run(FutureTask.java:138)   04-30 10:10:25.109:W / System.err(619):at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)   04-30 10:10:25.109:W / System.err(619):at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:581)   04-30 10:10:25.109:W / System.err(619):at java.lang.Thread.run(Thread.java:1019)   04-30 10:10:25.109:W / System.err(619):引起:java.net.ConnectException:localhost / 127.0.0.1:25 - 连接被拒绝   04-30 10:10:25.113:W / System.err(619):at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:207)   04-30 10:10:25.113:W / System.err(619):at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)   04-30 10:10:25.113:W / System.err(619):at java.net.Socket.connect(Socket.java:983)   04-30 10:10:25.113:W / System.err(619):at java.net.Socket.connect(Socket.java:926)   04-30 10:10:25.113:W / System.err(619):at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:233)   04-30 10:10:25.113:W / System.err(619):at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:189)   04-30 10:10:25.113:W / System.err(619):at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1359)   04-30 10:10:25.113:W / System.err(619):... 15 more

我发送电子邮件asynctask类

class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
    Mail thisMail;

    public SendEmailAsyncTask() {
        if(V) Log.v(SendEmailAsyncTask.class.getName(), "SendEmailAsyncTask()");
        this.thisMail = mailQueue.get(mailCounter);
        sendMessageToClient("Sending " + thisMail.getRecipients());

    }

    @Override
    protected Boolean doInBackground(Void... params) {
        if(V) Log.v(SendEmailAsyncTask.class.getName(), "doInBackground()");
        try {
            thisMail.send();
            return true;
        } catch (AuthenticationFailedException e) {
            Log.e(SendEmailAsyncTask.class.getName(), "Gmail account details are wrong");
            createNotification("Gmail account details are incorrect. Please check them in the settings.");
            setFlag(FLAG_BAD_ACCOUNT);
            e.printStackTrace();
            return false;
        } catch (MessagingException e) {
            Log.e(SendEmailAsyncTask.class.getName(), thisMail.getRecipients() + " sending failed");
            e.printStackTrace();
            return false;
        } 
    }

    @Override
    protected void onPostExecute(Boolean result) {
        if(result) { // email send success
            //sent successfully 
            if(D) Log.d(SendEmailAsyncTask.class.getName(), "email sent successfully");
            sendMessageToClient("Email sent");
        } else {
            //retry? or quit
            if(D) Log.d(SendEmailAsyncTask.class.getName(), "email was not sent");
            sendMessageToClient("Email not sent");
        }       

            mailCounter++;
            // if there are more mails in the queue start another send email task
            if (mailCounter < mailQueue.size()) {
                SendEmailAsyncTask sendTask = new SendEmailAsyncTask();
                sendTask.execute();

            // if there are no more in the mail queue, delete the data set
            } else {
                deleteTask = new DeleteFilesAsyncTask(currentDataSet.getDate(), currentDataSet.getMachine());
                deleteTask.execute();
            }

        sendTask = null;
    }
}

编辑: 通过我的Mail包装器类,我使用的端口是465,而不是25.我想知道这是否意味着什么?

public class Mail extends javax.mail.Authenticator {   
private String mailhost = "smtp.gmail.com";   
private String user;   
private String password;   
private Session session;   
private Multipart multipart;
private String subject;
private String body;
private String sender;
private String recipients;

static {   
    Security.addProvider(new JSSEProvider());   
}  

public Mail(String user, String password) {
    this.user = user;   
    this.password = password;   
    multipart = new MimeMultipart();

    Properties props = new Properties();   
    props.setProperty("mail.transport.protocol", "smtp");   
    props.setProperty("mail.host", mailhost);   
    props.put("mail.smtp.auth", "true");   
    props.put("mail.smtp.port", "465");   
    props.put("mail.smtp.socketFactory.port", "465");   
    props.put("mail.smtp.socketFactory.class",   
            "javax.net.ssl.SSLSocketFactory");   
    props.put("mail.smtp.socketFactory.fallback", "false");   
    props.setProperty("mail.smtp.quitwait", "false");   

    //session = Session.getDefaultInstance(props, this);
    session = Session.getInstance(props, this);
}   

}

1 个答案:

答案 0 :(得分:1)

好的,因为没有人似乎有答案......我会回答我自己的问题。

我通过在创建电子邮件后立即发送电子邮件而不是稍后安排发送来解决问题。

上一个代码: (成功发送后有错误)

class CreateEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        // create emails and add to the queue
    }

    @Override
    protected void onPostExecute(Boolean result) {
        SendEmailAsyncTask sendTask = new SendEmailAsyncTask();
        sendTask.execute();
}

class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        // send emails
    }
}

更改的代码: (适用于所有电子邮件)

class CreateEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        // create emails
        // send emails
    }
}

我认为可能会有超时或某些事情使邮件对象无效,但我不确定。我检查了Java Mail API documentation,但找不到太多信息......