Show me the code! – By Davanum Srinivas

Web Services, Apache, Websphere, IBM, etc.

Android – Send email via GMail (actually via SMTP)

with 44 comments

Here is a screen shot.

1

The main activity is pretty simple


package org.apache.android.mail;

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

public class SendMail extends Activity {
    /**
     * Called with the activity is first created.
     */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.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);
                }
            }
        });
    }
}

The GMail Sender code is from here


package org.apache.android.mail;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Security;
import java.util.Properties;

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 org.apache.harmony.xnet.provider.jsse.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");
        }
    }
}

Notes



  • We use activation-1.1.jar and mail-1.4.jar from SUN

  • Picked up a few classes in java.awt.datatransfer package from Apache Harmony SVN (and stripped them down)

  • Picked up the ByteArrayDataSource class from Apache Axis

  • build.xml adds the 2 jars and the additional harmony/axis classes into the classes.dex as well

Download Source and APK from here – SendMail.zip

Written by Davanum Srinivas

December 22, 2007 at 11:10 pm

Posted in Uncategorized

44 Responses

Subscribe to comments with RSS.

  1. Thanks so much!

    shiyansucks

    December 23, 2007 at 12:09 am

  2. [...] Envoyer un message GMail avec Android. Davanum a encore frappé ! [...]

    Android en vrac de Noël !

    December 23, 2007 at 6:03 pm

  3. Cool app.

    Android App

    December 24, 2007 at 4:32 pm

  4. Thank you so much!!!

    You have a prosperous new year 2008!!!

    Peter

    January 6, 2008 at 11:17 pm

  5. Awesome!!!

    Russian Translit

    January 10, 2008 at 8:51 pm

  6. i am getting the following error:

    E/AndroidRuntime(685): … 19 more
    E/AndroidRuntime(956): Uncaught handler: thread Main exiting due to uncaught exception
    E/AndroidRuntime(956): java.lang.NoClassDefFoundError: javax/activation/DataHandler
    E/AndroidRuntime(956): at org.apache.android.mail.GMailSender.sendMail(GMailSender.java:52)
    E/AndroidRuntime(956): at org.apache.android.mail.SendMail$1.onClick(SendMail.java:29)
    E/AndroidRuntime(956): at android.view.View.performClick(View.java:1515)
    E/AndroidRuntime(956): at android.widget.Button.performClick(Button.java:148)
    E/AndroidRuntime(956): at android.widget.TextView.onKeyDown(TextView.java:1533)
    E/AndroidRuntime(956): at android.view.KeyEvent.dispatch(KeyEvent.java:401)
    E/AndroidRuntime(956): at android.view.View.dispatchKeyEvent(View.java:2206)
    E/AndroidRuntime(956): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:360)
    E/AndroidRuntime(956): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:360)
    E/AndroidRuntime(956): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:360)
    E/AndroidRuntime(956): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:360)
    E/AndroidRuntime(956): at android.policy.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1071)
    E/AndroidRuntime(956): at android.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:884)
    E/AndroidRuntime(956): at android.app.Activity.dispatchKeyEvent(Activity.java:1377)
    E/AndroidRuntime(956): at android.policy.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1058)
    E/AndroidRuntime(956): at android.view.ViewRoot.handleMessage(ViewRoot.java:564)
    E/AndroidRuntime(956): at android.os.Handler.dispatchMessage(Handler.java:80)
    E/AndroidRuntime(956): at android.os.Looper.loop(Looper.java:71)
    E/AndroidRuntime(956): at android.app.ActivityThread.main(ActivityThread.java:2506)
    E/AndroidRuntime(956): at java.lang.reflect.Method.invokeNative(Native Method)
    E/AndroidRuntime(956): at java.lang.reflect.Method.invoke(Method.java:380)
    E/AndroidRuntime(956): at android.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1170)
    E/AndroidRuntime(956): at android.os.ZygoteInit.main(ZygoteInit.java:1121)
    E/AndroidRuntime(956): at android.dalvik.NativeStart.main(Native Method)
    E/AndroidRuntime(956): Caused by: java.lang.ClassNotFoundException: javax.activation.DataHandler in loader android.app.ApplicationLoaders$PathClassLoader@4008a2c8
    E/AndroidRuntime(956): at android.app.ApplicationLoaders$PathClassLoader.findClass(ApplicationLoaders.java:188)
    E/AndroidRuntime(956): at java.lang.ClassLoader.loadClass(ClassLoader.java:438)
    E/AndroidRuntime(956): at java.lang.ClassLoader.loadClass(ClassLoader.java:406)
    E/AndroidRuntime(956): … 24 more
    ,i added the jars you provided in the zip….

    csagar

    January 26, 2008 at 4:12 am

  7. when i downloaded the zip i got /java/awt/datatransfer package also… i am not using your build file…so ,is it required ??? i get no error on comiplation.I checked your build.xml. You have mentioned in the notes that build.xml adds two jars.and some harmony/axis class .i could found the jars.but not these classes. Whats going wrong in my case??please reply

    csagar

    January 26, 2008 at 4:39 am

  8. thanks , it was a great help for me, i am trying to make a mail client including sending and receiving mails

    shimul

    January 28, 2008 at 2:56 am

  9. how to connect the smtp server

    kmk

    February 6, 2008 at 6:03 am

  10. Very useful program. I am programming aplication, where i need to send email with attachement. Does enybody know haow to do that? I tried this with multipart and bod part stuff like you can do that in java, but it doesn’t work here in android. I get no errors but I get either no email to may inbox which I had sent with android.

    Does somebody have any suggestions? Where is the problem?

    Please help me…

    Thanks

    marko

    February 6, 2008 at 7:07 am

  11. Great post, that helped me to get started with imap on Android:
    http://eppleton.com/blog/?p=176

    Toni Epple

    February 10, 2008 at 11:34 am

  12. This is suporting html email
    How can i enable html email in Amdorid

    hari

    February 11, 2008 at 12:52 pm

  13. And I should add: Awesome! Thanks :)

    Joseph Dung

    February 12, 2008 at 8:03 am

  14. Great work… but has anyone gotten attachments to work with this? It sends the email fine but no attachments get through.

    :)

    George

    February 20, 2008 at 10:43 am

  15. Hi,

    I copied the code above into my android program using Eclipse, and the code didn’t have any compilation problem. However, when I run it, I get the following error message:

    java.lang.NoClassDefFoundError: javax/activation/DataHandler

    I have both the activation-1.1.jar and mail-1.4.jar in my build path. Can someone help me out? I have been trying to solve this for one week already. Thanks!

    mcluucy

    March 15, 2008 at 12:16 am

  16. i am getting java.lang.NoClassDefFoundError execption… Can anyone help me out…

    nithin

    April 1, 2008 at 6:02 am

  17. hello sir
    I would to ask how to run this application under eclipse environment
    thanks

    miladi

    April 8, 2008 at 6:40 am

  18. I can run its on eclipse.
    I build new project and copy all source file to project.
    after that you can not run it. Because name of activity(start activity) does not match. So I change Activity class name to match with name of start activity in open dialog.

    RoSippA

    May 6, 2008 at 1:19 am

  19. mcluucy (and others):

    The NoClassDefFoundError results from android’s lack of java.awt.datatransfer classes. In order to gain access to message contents in javamail (sending or receiving) you need to have the DataHandler class that is in activation.jar; however, this class will fail to link if specific classes from java.awt.datatransfer are not present. Hence, the error messages indicate that DataHandler cannot be loaded, even though it is in the classpath.

    The provided .zip contains (as indicated in the notes after the above source code) a few files from the Apache Harmony implementation of java (presumably cut to remove compilation errors), which can be copied into a project. However, note that if you indend to use these files to gain read access to a MimeMessage (e.g., IMAP client), I’ve found that they only provide an InputStream, and do not allow you to cast .getContent as a String or Multipart. I imagine the relevant awt classes required for these DataHandlers can be similarly acquired.

    Will

    May 8, 2008 at 3:59 am

  20. Also, note that an implementation of ByteArrayDataSource was taken from Apache Axis to define the DataHandler required to send the mail (as shown in the above source code). A similar technique may be useful in retrieving a String or Mailpart with .getContent()

    Will

    May 8, 2008 at 4:21 am

  21. i am getting a number format exception when i set my mail.smtp.port to the ip as below.
    ERROR/GmailSender SendMail()(849): java.lang.NumberFormatException: 192.168.151.26

    farah

    May 15, 2008 at 9:01 am

  22. I discovered (a while ago, but forgot to post a comment here) the cause to the .getContent() error described above. When the activation.jar and mail.jar archives are imported into Android, the META-INF directories containing the mailcap entries are stripped. When the classes look at the MIME type on the content, it doesn’t find a known handler because one is never defined.

    Will

    June 1, 2008 at 7:13 pm

  23. Hi,
    The sendmail.zip is not downloadable. I too had the same problem java.lang.NoClassDefFoundError: javax/activation/DataHandler. Please help.

    Thanks.

    Sathiya

    August 22, 2008 at 11:49 am

  24. Get nothing from the download link.
    I would love to know the extra classes I need…

    elvis

    August 26, 2008 at 5:33 am

  25. sir where we get this import android.app.Activity; packet

    Ruby

    September 16, 2008 at 4:55 am

  26. Tried downloading the code, but it was unavailable.

    Mirko

    October 1, 2008 at 12:36 am

  27. The Zip is no longer on your server… Is it on purpose ?
    Please put it back.

    Majax

    October 10, 2008 at 7:48 pm

  28. hi
    very nice code but it is uncomplete
    i mean many qustion are unanswered
    you not told
    how to add two jar file?
    how i create or download these two package java.awt.datatransfer package and
    ByteArrayDataSource
    and
    what is this?
    build.xml adds the 2 jars and the additional harmony/axis classes into the classes.dex as well

    plz tel me how to do all these setting
    Thank You

    RAHUL

    January 6, 2009 at 6:29 am

  29. Hi,

    I would also like the zip file. I’ve been trying to compile myself but with no joy. It would be a great help if you could reupload.

    Thank you,

    Chiggsy

    February 8, 2009 at 8:22 am

  30. Hello webmaster
    I would like to share with you a link to your site
    write me here preonrelt@mail.ru

    Alexwebmaster

    March 3, 2009 at 3:19 am

  31. can any1 send me the zip file please. i cant download the zip project.this is my email ch1ttagong@yahoo.com

    saifuctg

    April 2, 2009 at 4:14 pm

  32. I can’t see how this code works, when I run, both on the device or emulator it fails with a java.lang.VerifyError This is because javax.mail depends on javax.activation package. The DataHandler class in activation uses an interface from awt which is obviously not included in the dalvik system.

    Before the exception is thrown I see

    Failed resolving Ljavax/activation/DataHandler; interface 178 ‘Ljava/awt/datatransfer/Transferable;’

    So, how do you get javax.mail to run without this dependency?

    John Hunsley

    April 6, 2009 at 4:59 am

  33. Hello everyone,
    I am looking for a way to download the zip file.
    If any of you have it, please email me at noam.habot@gmail.com

    Thanks,
    Noam.

    Noam

    April 7, 2009 at 11:39 am

  34. download sendMail.zip from here

    http://banglasoft.info/tmpFiles/SendMail.rar

    if u got any question. don’t send me private email plz.

    saifuctg

    April 9, 2009 at 6:25 pm

  35. I have download the code. And compile it without error. But when I run it, it crash down. I doubt if the imported lib can run on android platform.

    cyber

    April 20, 2009 at 3:22 am

  36. There is obviously a lot to know about this. I think you made some good points in Features also.

    Lilian Waldridge

    April 27, 2009 at 10:30 am

  37. 1 more good solution is coming guys….wait few days let me finish my exams.

    saifuctg

    May 6, 2009 at 5:41 pm

  38. [...] another attempt at putting together bits and pieces with more details how to go about this yourself but it’s really lots of hacking which most people might like to avoid. Someone else has also [...]

  39. Hey saifuctg thanks for the SendMail rar, it doesnt seem to be complete though…its missing the extra harmony/axis classes that are supposed to be added to the dex file….dont suppose anyone still has a copy of them lying around anywhere?

    -James (james@jamesgrafton.com)

    james grafton

    May 28, 2009 at 12:56 pm

    • Hey guys managed to get this working on 1.5 and 1.1 firmware. unfortunately it ended up not being very useful for me (I wanted to use gmail as a mail relay – unfortunately Google overwrites the From header whenever you send a mail from an authenticated account)…

      Anyways you guys might still find a use for it. I have created two jar files, additional.jar contains the missing datatransfer classes and custom_activation.jar is a customized set of activation classes which reference the local data transfer classes rather than the system default ones.

      You can find both of these jar files at:

      http://jamesgrafton.com/Android/

      -James

      james grafton

      June 2, 2009 at 4:27 am

  40. Hello, I have this error
    java.lang.VerifyError: javax.mail.internet.MimeMessage
    Any idea to fix it?
    Thanks anyway!

    markuz

    June 2, 2009 at 11:59 am

    • Hi,

      “Ljavax/activation/DataHandler” problem is still observed. can anybody give any suggesion to solve this problem. whether the new .jar files (custom_activation, additional.jar) will solve this issue.

      can you attach those .jar files again. only

      Nayan

      June 3, 2009 at 1:59 am

  41. Hi Mark, how exactly are you trying to use the libraries? could you post the code snippet thats actually throwing that exception?

    My initial thoughts are that your using a corrupt version of mail.jar…try using the one on my site (http://jamesgrafton.com/Android/mail.jar)

    james grafton

    June 3, 2009 at 4:21 am


Leave a Reply