0

I have this code, two simple classes: a mail sender and a main Android activity with just one button. This is the activity code:

package com.py.spycam;

import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.internet.AddressException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

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

    public void onClickMail(View v) {
        String[] to = {"toaddress"};
        SMTPMail mail = new SMTPMail("user", "pass");
        try {
            mail.send("sender", to, "prova", "prova bpdy");
            Toast.makeText(this, "Mail sent", Toast.LENGTH_SHORT).show();
        } catch (NoSuchProviderException e) {
            Toast.makeText(this, "Unable to send email (NoSuchProviderException)", Toast.LENGTH_SHORT).show();
        } catch (AddressException e) {
            Toast.makeText(this, "Unable to send email (AddressException)", Toast.LENGTH_SHORT).show();
        } catch (MessagingException e) {
            Toast.makeText(this, "Unable to send email (MessagingException)", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Toast.makeText(this, "Unable to send email (general Exception)", Toast.LENGTH_SHORT).show();
        }

    }

}

And this is the mail sender:

package com.py.spycam;

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
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 SMTPMail {
    private String host;
    private String from;
    private String pass;
    private Properties props;

    public SMTPMail(String _user, String _pass) {
        host = "smtp.gmail.com";
        from = _user;
        pass = _pass;
        props = System.getProperties();

        /* Props settings */
        props.put("mail.smtp.starttls.enable", "true"); // added this line
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.user", from);
        props.put("mail.smtp.password", pass);
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");
    }

    public void send(String from, String[] to, String subject, String body)
            throws AddressException, MessagingException, NoSuchProviderException {
            //throws AddressException, MessagingException {

        Session session = Session.getDefaultInstance(props, null);
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));

        InternetAddress[] toAddress = new InternetAddress[to.length];

        // To get the array of addresses
        for(int i=0; i < to.length; i++ ) { // changed from a while loop
            toAddress[i] = new InternetAddress(to[i]);
        }

        for(int i=0; i < toAddress.length; i++) { // changed from a while loop
            message.addRecipient(Message.RecipientType.TO, toAddress[i]);
        }
        message.setSubject(subject);
        message.setText(body);
        Transport transport = session.getTransport("smtp");
        transport.connect(host, from, pass);
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();
    }


}

I keep getting a general Exception, not caught by any catch statement (how could it be? From where is it thrown?). What's wrong with this code? Note: this code works if executed with plain Java (javac compiled, executed with a simple main).

Mega-edit: here's the output from the LogCat, restricted to System.err warnings (generated from printStackTrace()s.

01-17 01:41:41.550: W/System.err(23420): android.os.NetworkOnMainThreadException
01-17 01:41:41.550: W/System.err(23420):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
01-17 01:41:41.555: W/System.err(23420):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
01-17 01:41:41.555: W/System.err(23420):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
01-17 01:41:41.555: W/System.err(23420):    at java.net.InetAddress.getByName(InetAddress.java:289)
01-17 01:41:41.555: W/System.err(23420):    at java.net.InetSocketAddress.<init>(InetSocketAddress.java:105)
01-17 01:41:41.555: W/System.err(23420):    at java.net.InetSocketAddress.<init>(InetSocketAddress.java:90)
01-17 01:41:41.555: W/System.err(23420):    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:233)
01-17 01:41:41.555: W/System.err(23420):    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:189)
01-17 01:41:41.555: W/System.err(23420):    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1359)
01-17 01:41:41.555: W/System.err(23420):    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412)
01-17 01:41:41.555: W/System.err(23420):    at javax.mail.Service.connect(Service.java:288)
01-17 01:41:41.560: W/System.err(23420):    at javax.mail.Service.connect(Service.java:169)
01-17 01:41:41.560: W/System.err(23420):    at com.py.spycam.SMTPMail.send(SMTPMail.java:55)
01-17 01:41:41.560: W/System.err(23420):    at com.py.spycam.MainActivity.onClickMail(MainActivity.java:29)
01-17 01:41:41.560: W/System.err(23420):    at java.lang.reflect.Method.invokeNative(Native Method)
01-17 01:41:41.560: W/System.err(23420):    at java.lang.reflect.Method.invoke(Method.java:511)
01-17 01:41:41.560: W/System.err(23420):    at android.view.View$1.onClick(View.java:3586)
01-17 01:41:41.560: W/System.err(23420):    at android.view.View.performClick(View.java:4084)
01-17 01:41:41.560: W/System.err(23420):    at android.view.View$PerformClick.run(View.java:16966)
01-17 01:41:41.560: W/System.err(23420):    at android.os.Handler.handleCallback(Handler.java:615)
01-17 01:41:41.560: W/System.err(23420):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-17 01:41:41.565: W/System.err(23420):    at android.os.Looper.loop(Looper.java:137)
01-17 01:41:41.565: W/System.err(23420):    at android.app.ActivityThread.main(ActivityThread.java:4931)
01-17 01:41:41.565: W/System.err(23420):    at java.lang.reflect.Method.invokeNative(Native Method)
01-17 01:41:41.565: W/System.err(23420):    at java.lang.reflect.Method.invoke(Method.java:511)
01-17 01:41:41.565: W/System.err(23420):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
01-17 01:41:41.565: W/System.err(23420):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
01-17 01:41:41.565: W/System.err(23420):    at dalvik.system.NativeStart.main(Native Method)
whatyouhide
  • 15,897
  • 9
  • 57
  • 71
  • Please show the complete error stack trace – Adel Boutros Jan 17 '13 at 00:00
  • That's another problem I'm still trying to figure out... Where is it supposed to be the error stack trace? I know I'm gone full nood now – whatyouhide Jan 17 '13 at 00:02
  • 1
    It is called LogCat and should be a view in Eclipse or accessible via `adb logcat` in your terminal. – WarrenFaith Jan 17 '13 at 00:04
  • You're catching all the exceptions and not logging them. Instead of the Toast (or in addition) use Log to output the exception (or just put e.printStackTrace() for a quick and dirty look). Also here's an example of doing what you're trying to do (though this code has a number if issues too, like it's using the UI thread to send the email): http://stackoverflow.com/questions/2020088/sending-email-in-android-using-javamail-api-without-using-the-default-built-in-a/ – Charlie Collins Jan 17 '13 at 00:08
  • I tried to follow the instructions from the link posted by @CharlieCollins, but I didn't manage to make it through. I'll add a comment with LogCat output in a little while. – whatyouhide Jan 17 '13 at 00:17
  • `01-17 01:19:19.940: E/Trace(22281): error opening trace file: No such file or directory (2)` Is this what you were talking about? I restricted the LogCat to errors, and I didn't change the activity code. If I change it with a `printStackTrace()`, where should I look for this output then? – whatyouhide Jan 17 '13 at 00:20

1 Answers1

3

Pretty basic.

There are two rules to the android threading model.

1) Don't block the main thread. 2) Don't manipulate the main ("UI") thread from another thread

You have violated the first of these by blocking the main thread by making a network call on it. Move the sending mail to a different thread. Consider a simple Thread or an AsyncTask

Also, see the developer docs regarding "Processes and Threads".

Also, note that you seem to currently have StrictMode enabled, which is a good thing. This detects things you "shouldn't be doing", such as making network calls on the main thread and throws exceptions if you do so.

LuxuryMode
  • 33,401
  • 34
  • 117
  • 188