Thursday 7 June 2012

Send e-mail using the JavaMail API using Gmail authentication in Android




First you have to download three jar files.
    1. mail.jar
    2. activation.jar
    3. additionnal.jar
  • Then Right Click on your project,Select Build Path. From that select Configure Build Path.
  • Then in Libraries Tab select Add External Jars and then select the path where you downloaded jar files. 
  • Add all the three jar files and click ok.
AutomaticMailActivity.class

package com.mail;

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

public class AutomaticMailActivity extends Activity {

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

                try {   
                    GMailSender sender = new GMailSender("xxxxxxxxxxxx@gmail.com", "xxxxxxxx");
                    sender.sendMail("This is Subject",   
                            "This is Body",     
                            " xxxxxxxxxxxx@gmail.com "," xxxxxxxxxxxx@gmail.com ");   
                } catch (Exception e) {   
                    Log.e("SendMail", e.getMessage(), e);   
                }
    }
}


GMailSender.class


package com.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 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 {   
        try{
        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);   
        }catch(Exception e){


        }
    }   


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


JSSEProvider.class

package com.provider;

import java.security.AccessController;
import java.security.Provider;

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

main.xml

No need to add anything here .leave the default one.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mail"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".AutomaticMailActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
<uses-permission android:name="android.permission.INTERNET"/>"
</manifest>

30 comments:

  1. Hello hope you will be fine.
    I try this code but i can not received any mail in Gmail and Yahoo account. Also include 3 files in my project. whats a problem.
    plz rply me urgently.

    ReplyDelete
    Replies
    1. Did you enter your Gmail id and password correctly

      Delete
    2. Yes sir i enter gmail id and password

      Delete
  2. Are you getting any error while running the code

    ReplyDelete
  3. NO, logcat is running without error.

    ReplyDelete
    Replies
    1. Is your internet 2G or 3G. This works better with 3G and wifi.
      (In 2G both calls and data use same frequency.)

      Delete
    2. its works for me thank u so much bro

      Delete
    3. Hi Naveed, I'm facing the same problem as you are. I do not get any error in Logcat but no emails are sent from my account. Can you tell me how you solved the problem??

      Delete
    4. This application works beeter with 3G and wifi network. It may not work properly with 2G as both call and data use same frequency in 2G

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Are you trying with emulator or device? What is the network you are using? Works better with 3G and wifi.

    ReplyDelete
  6. Hi,
    this is my logcat:
    03-21 11:41:12.128: E/MailApp(2134): Could not send email
    03-21 11:41:12.128: E/MailApp(2134): android.os.NetworkOnMainThreadException
    03-21 11:41:12.128: E/MailApp(2134): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
    03-21 11:41:12.128: E/MailApp(2134): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
    03-21 11:41:12.128: E/MailApp(2134): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
    03-21 11:41:12.128: E/MailApp(2134): at java.net.InetAddress.getByName(InetAddress.java:289)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.URLName.getHostAddress(URLName.java:487)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.URLName.hashCode(URLName.java:463)
    03-21 11:41:12.128: E/MailApp(2134): at java.util.Hashtable.get(Hashtable.java:263)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.Session.getPasswordAuthentication(Session.java:823)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.Service.connect(Service.java:271)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.Service.connect(Service.java:169)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.Service.connect(Service.java:118)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.Transport.send0(Transport.java:188)
    03-21 11:41:12.128: E/MailApp(2134): at javax.mail.Transport.send(Transport.java:118)
    03-21 11:41:12.128: E/MailApp(2134): at cz.vutbr.phonexia.Mail.send(Mail.java:109)
    03-21 11:41:12.128: E/MailApp(2134): at cz.vutbr.phonexia.SecuritySettings.SendEmail(SecuritySettings.java:71)
    03-21 11:41:12.128: E/MailApp(2134): at java.lang.reflect.Method.invokeNative(Native Method)
    03-21 11:41:12.128: E/MailApp(2134): at java.lang.reflect.Method.invoke(Method.java:511)
    03-21 11:41:12.128: E/MailApp(2134): at android.view.View$1.onClick(View.java:3586)
    03-21 11:41:12.128: E/MailApp(2134): at android.view.View.performClick(View.java:4084)
    03-21 11:41:12.128: E/MailApp(2134): at android.view.View$PerformClick.run(View.java:16966)
    03-21 11:41:12.128: E/MailApp(2134): at android.os.Handler.handleCallback(Handler.java:615)
    03-21 11:41:12.128: E/MailApp(2134): at android.os.Handler.dispatchMessage(Handler.java:92)
    03-21 11:41:12.128: E/MailApp(2134): at android.os.Looper.loop(Looper.java:137)
    03-21 11:41:12.128: E/MailApp(2134): at android.app.ActivityThread.main(ActivityThread.java:4745)
    03-21 11:41:12.128: E/MailApp(2134): at java.lang.reflect.Method.invokeNative(Native Method)
    03-21 11:41:12.128: E/MailApp(2134): at java.lang.reflect.Method.invoke(Method.java:511)
    03-21 11:41:12.128: E/MailApp(2134): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    03-21 11:41:12.128: E/MailApp(2134): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    03-21 11:41:12.128: E/MailApp(2134): at dalvik.system.NativeStart.main(Native Method)
    Where can be problem?
    I try with device and Wifi.
    Thanks a lot!

    ReplyDelete
  7. i want to use all service in android can u help me which api i should use to send email from android to hotmail ,gmail ,yahoo etc thanks

    ReplyDelete
    Replies
    1. In this application you can send mails from gmail to any other mails like yahoo etc.

      Delete
  8. Naveed please tell me how u solved it, i have no log errors ...

    ReplyDelete
  9. Very informative, Thank you very much. Just heard about a new android email API by the name of Aspose.Email for Android. Here is the link: http://www.aspose.com/android/email-component.aspx It provides tools to create, read & convert Outlook MSG, PST, EML, EMLX, OST & MHT file formats. Did anybody have some experience with this API?

    ReplyDelete
  10. Naveed Ur Rehman como resolvio este problema, yo lo estoy usando pero no funciona
    Sale algo como could not connect to smtp host: smtp.gmail.com, port: 465, alguna idea

    ReplyDelete
  11. Please help me, I run the gmail api example. But It have a error here, please let me know the reason why? T.T
    session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("id", "pass"); }});
    P/S: I allready inputed my user and pass...

    ReplyDelete
  12. Thank you for the post. I was looking for tips on services, found your blog and its really informative
    A wonderful blog ever seen. I appreciate your way of expressing..

    Gmail Account Support

    ReplyDelete
  13. I am getting

    10-26 18:19:14.400: I/dalvikvm(20753): Failed resolving Ljavax/activation/DataHandler; interface 1171 'Ljava/awt/datatransfer/Transferable;'
    10-26 18:19:14.400: W/dalvikvm(20753): Link of class 'Ljavax/activation/DataHandler;' failed
    10-26 18:19:14.400: E/dalvikvm(20753): Could not find class 'javax.activation.DataHandler', referenced from method com.melio.neogen.GMailSender.sendMail

    ReplyDelete
  14. I am getting

    javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465;
    nested exception is:
    java.net.SocketException: failed to connect to smtp.gmail.com/2404:6800:4003:c00::6c (port 465) after 90000ms: isConnected failed: EHOSTUNREACH (No route to host)

    ReplyDelete
  15. Security.addProvider(new com.provider.JSSEProvider());, Im getting this mistake, cant resolve provider!! any ideas? Thank you by the way, great blog!!

    ReplyDelete
  16. is it need to on sign in with less security tab from Gmail sender account

    ReplyDelete
    Replies
    1. Yes you need to sign in with your gmail account

      Delete
    2. Yes you need to sign in with your gmail account

      Delete
  17. how to add BCC and CC????

    ReplyDelete
  18. NO, logcat is running without error.and not sent mail ......nothing happen ???? what's the problem

    ReplyDelete