Search code examples
javaandroidemailbackgroundsend

Send email in background


I have tried an android application that can send email through background. When I click send button email was not send and getting error android.os.NetworkOnMianThreadException. Please help me to resolve this error. My complete code and logcat are given below..

GMailSender.java

public class GMailSender extends javax.mail.Authenticator
{
private String mailhost = "smtp.gmail.com";
private String user;
private String password;
private Session session;

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

public GMailSender(String user, String password) {
    this.user = user;
    this.password = password;

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

protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(user, password);
}

public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception {
    MimeMessage message = new MimeMessage(session);
    DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));
    message.setSender(new InternetAddress(sender));
    message.setSubject(subject);
    message.setDataHandler(handler);
    if (recipients.indexOf(',') > 0)
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));
    else
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));
    Transport.send(message);
}

public class ByteArrayDataSource implements DataSource {
    private byte[] data;
    private String type;

    public ByteArrayDataSource(byte[] data, String type) {
        super();
        this.data = data;
        this.type = type;
    }

    public ByteArrayDataSource(byte[] data) {
        super();
        this.data = data;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getContentType() {
        if (type == null)
            return "application/octet-stream";
        else
            return type;
    }

    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(data);
    }

    public String getName() {
        return "ByteArrayDataSource";
    }

    public OutputStream getOutputStream() throws IOException {
        throw new IOException("Not Supported");
    }
}
}

MainActivity.java

public class MainActivity extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Button send = (Button) this.findViewById(R.id.send);
    final EditText userid = (EditText) this.findViewById(R.id.userid);
    final EditText password = (EditText) this.findViewById(R.id.password);
    final EditText from = (EditText) this.findViewById(R.id.from);
    final EditText to = (EditText) this.findViewById(R.id.to);
    final EditText subject = (EditText) this.findViewById(R.id.subject);
    final EditText body = (EditText) this.findViewById(R.id.body);

    send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                    GMailSender sender = new GMailSender(userid.getText()
                                    .toString(), password.getText().toString());
                    try {
                            sender.sendMail(subject.getText().toString(), body
                                            .getText().toString(), from.getText().toString(),
                                            to.getText().toString());
                    } catch (Exception e) {
                            Log.e("SendMail", e.getMessage(), e);
                    }
            }
    });
}
}

JSSEProvider.java

public class JSSEProvider extends Provider
{
 public JSSEProvider() {
        super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
        AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
            public Void run() {
                put("SSLContext.TLS",
                        "org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
                put("Alg.Alias.SSLContext.TLSv1", "TLS");
                put("KeyManagerFactory.X509",
                        "org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
                put("TrustManagerFactory.X509",
                        "org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
                return null;
            }
        });
    }
 }

Logcat

01-10 20:46:30.868: E/SendMail(23815): null
01-10 20:46:30.868: E/SendMail(23815): android.os.NetworkOnMainThreadException
01-10 20:46:30.868: E/SendMail(23815):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
01-10 20:46:30.868: E/SendMail(23815):  at java.net.InetAddress.lookupHostByName(InetAddress.java:392)
01-10 20:46:30.868: E/SendMail(23815):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:243)
01-10 20:46:30.868: E/SendMail(23815):  at java.net.InetAddress.getByName(InetAddress.java:296)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.URLName.getHostAddress(URLName.java:487)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.URLName.hashCode(URLName.java:463)
01-10 20:46:30.868: E/SendMail(23815):  at java.util.Hashtable.get(Hashtable.java:263)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.Session.getPasswordAuthentication(Session.java:823)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.Service.connect(Service.java:271)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.Service.connect(Service.java:169)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.Service.connect(Service.java:118)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.Transport.send0(Transport.java:188)
01-10 20:46:30.868: E/SendMail(23815):  at javax.mail.Transport.send(Transport.java:118)
01-10 20:46:30.868: E/SendMail(23815):  at com.example.emailtestapp.GMailSender.sendMail(GMailSender.java:70)
01-10 20:46:30.868: E/SendMail(23815):  at com.example.emailtestapp.MainActivity$1.onClick(MainActivity.java:32)
01-10 20:46:30.868: E/SendMail(23815):  at android.view.View.performClick(View.java:3534)
01-10 20:46:30.868: E/SendMail(23815):  at android.view.View$PerformClick.run(View.java:14172)
01-10 20:46:30.868: E/SendMail(23815):  at android.os.Handler.handleCallback(Handler.java:605)
01-10 20:46:30.868: E/SendMail(23815):  at android.os.Handler.dispatchMessage(Handler.java:92)
   01-10 20:46:30.868: E/SendMail(23815):   at android.os.Looper.loop(Looper.java:154)
   01-10 20:46:30.868: E/SendMail(23815):   at android.app.ActivityThread.main(ActivityThread.java:4624)
   01-10 20:46:30.868: E/SendMail(23815):   at java.lang.reflect.Method.invokeNative(Native Method)
   01-10 20:46:30.868: E/SendMail(23815):   at java.lang.reflect.Method.invoke(Method.java:511)
   01-10 20:46:30.868: E/SendMail(23815):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:965)
   01-10 20:46:30.868: E/SendMail(23815):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:732)
   01-10 20:46:30.868: E/SendMail(23815):   at dalvik.system.NativeStart.main(Native Method)

Solution

  • Use AsyncTask does not make sense if you do not update after a request interface

    try explicitly create a new thread

    send.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    Thread thread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            GMailSender sender = new GMailSender(userid.getText()
                                    .toString(), password.getText().toString());
                            try {
                                sender.sendMail(subject.getText().toString(), body
                                                .getText().toString(), from.getText().toString(),
                                        to.getText().toString());
                            } catch (Exception e) {
                                Log.e("SendMail", e.getMessage(), e);
                            }
                        }
                    });
                    thread.start();
                }
            });