├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── brandonjenniges │ │ └── javamailapidemo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── brandonjenniges │ │ │ └── javamailapidemo │ │ │ ├── Mail.java │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ ├── activity_main.xml │ │ └── content_main.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── brandonjenniges │ └── javamailapidemo │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/android,intellij,java,gradle 3 | 4 | ### Android ### 5 | # Built application files 6 | *.apk 7 | *.ap_ 8 | 9 | # Files for the Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | gen/ 18 | 19 | # Gradle files 20 | .gradle/ 21 | build/ 22 | 23 | # Local configuration file (sdk path, etc) 24 | local.properties 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Log Files 30 | *.log 31 | 32 | # Android Studio Navigation editor temp files 33 | .navigation/ 34 | 35 | # Android Studio captures folder 36 | captures/ 37 | 38 | ### Android Patch ### 39 | gen-external-apklibs 40 | 41 | 42 | ### Intellij ### 43 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 44 | 45 | *.iml 46 | 47 | ## Directory-based project format: 48 | .idea/ 49 | # if you remove the above rule, at least ignore the following: 50 | 51 | # User-specific stuff: 52 | # .idea/workspace.xml 53 | # .idea/tasks.xml 54 | # .idea/dictionaries 55 | # .idea/shelf 56 | 57 | # Sensitive or high-churn files: 58 | # .idea/dataSources.ids 59 | # .idea/dataSources.xml 60 | # .idea/sqlDataSources.xml 61 | # .idea/dynamic.xml 62 | # .idea/uiDesigner.xml 63 | 64 | # Gradle: 65 | # .idea/gradle.xml 66 | # .idea/libraries 67 | 68 | # Mongo Explorer plugin: 69 | # .idea/mongoSettings.xml 70 | 71 | ## File-based project format: 72 | *.ipr 73 | *.iws 74 | 75 | ## Plugin-specific files: 76 | 77 | # IntelliJ 78 | /out/ 79 | 80 | # mpeltonen/sbt-idea plugin 81 | .idea_modules/ 82 | 83 | # JIRA plugin 84 | atlassian-ide-plugin.xml 85 | 86 | # Crashlytics plugin (for Android Studio and IntelliJ) 87 | com_crashlytics_export_strings.xml 88 | crashlytics.properties 89 | crashlytics-build.properties 90 | fabric.properties 91 | 92 | 93 | ### Java ### 94 | *.class 95 | 96 | # Mobile Tools for Java (J2ME) 97 | .mtj.tmp/ 98 | 99 | # Package Files # 100 | *.jar 101 | *.war 102 | *.ear 103 | 104 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 105 | hs_err_pid* 106 | 107 | 108 | ### Gradle ### 109 | .gradle 110 | build/ 111 | 112 | # Ignore Gradle GUI config 113 | gradle-app.setting 114 | 115 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 116 | !gradle-wrapper.jar 117 | 118 | # Cache of project 119 | .gradletasknamecache 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaMail API for Android 2 | 3 | Example using JavaMailAPI to send emails with gmail account in Android 4 | 5 | JavaMail API Documentation 6 | -------------- 7 | 8 | https://java.net/projects/javamail/pages/Android 9 | 10 | Pre-requisites 11 | -------------- 12 | - Android SDK v10 13 | 14 | Getting Started 15 | --------------- 16 | 17 | This project uses the Gradle build system. To build this project, use the 18 | "gradlew build" command or use "Import Project" in Android Studio. 19 | 20 | Adding JavaMail API to your project 21 | -------------- 22 | Add to build.gradle file 23 | 24 | ``` 25 | android { 26 | packagingOptions { 27 | pickFirst 'META-INF/LICENSE.txt' // picks the JavaMail license file 28 | } 29 | } 30 | 31 | repositories { 32 | jcenter() 33 | maven { 34 | url "https://maven.java.net/content/groups/public/" 35 | } 36 | } 37 | 38 | dependencies { 39 | compile 'com.sun.mail:android-mail:1.5.5' 40 | compile 'com.sun.mail:android-activation:1.5.5' 41 | } 42 | ``` 43 | Add Internet permission to AndroidManifest.xml 44 | ``` 45 | 46 | ``` 47 | Add Mail.java to project 48 | 49 | Known issues 50 | -------------- 51 | - Doesn't work with Gmail accounts that use Two-factor authentication 52 | 53 | License 54 | -------------- 55 | https://java.net/projects/javamail/pages/License 56 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.brandonjenniges.javamailapidemo" 9 | minSdkVersion 10 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | packagingOptions { 22 | pickFirst 'META-INF/LICENSE.txt' // picks the JavaMail license file 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: ['*.jar']) 28 | testCompile 'junit:junit:4.12' 29 | compile 'com.android.support:appcompat-v7:23.1.1' 30 | compile 'com.android.support:design:23.1.1' 31 | compile 'com.sun.mail:android-mail:1.5.5' 32 | compile 'com.sun.mail:android-activation:1.5.5' 33 | } 34 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/brandonjenniges/javamailapidemo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.brandonjenniges.javamailapidemo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/brandonjenniges/javamailapidemo/Mail.java: -------------------------------------------------------------------------------- 1 | package com.brandonjenniges.javamailapidemo; 2 | 3 | import java.util.Date; 4 | import java.util.Properties; 5 | 6 | import javax.activation.CommandMap; 7 | import javax.activation.DataHandler; 8 | import javax.activation.DataSource; 9 | import javax.activation.FileDataSource; 10 | import javax.activation.MailcapCommandMap; 11 | import javax.mail.BodyPart; 12 | import javax.mail.Multipart; 13 | import javax.mail.PasswordAuthentication; 14 | import javax.mail.Session; 15 | import javax.mail.Transport; 16 | import javax.mail.internet.InternetAddress; 17 | import javax.mail.internet.MimeBodyPart; 18 | import javax.mail.internet.MimeMessage; 19 | import javax.mail.internet.MimeMultipart; 20 | 21 | /** 22 | * Created by brandonjenniges on 11/6/15. 23 | */ 24 | public class Mail extends javax.mail.Authenticator { 25 | private String _user; 26 | private String _pass; 27 | 28 | private String[] _to; 29 | private String _from; 30 | 31 | private String _port; 32 | private String _sport; 33 | 34 | private String _host; 35 | 36 | private String _subject; 37 | private String _body; 38 | 39 | private boolean _auth; 40 | 41 | private boolean _debuggable; 42 | 43 | private Multipart _multipart; 44 | 45 | public Mail() { 46 | _host = "smtp.gmail.com"; // default smtp server 47 | _port = "465"; // default smtp port 48 | _sport = "465"; // default socketfactory port 49 | 50 | _user = ""; // username 51 | _pass = ""; // password 52 | _from = ""; // email sent from 53 | _subject = ""; // email subject 54 | _body = ""; // email body 55 | 56 | _debuggable = false; // debug mode on or off - default off 57 | _auth = true; // smtp authentication - default on 58 | 59 | _multipart = new MimeMultipart(); 60 | 61 | // There is something wrong with MailCap, javamail can not find a 62 | // handler for the multipart/mixed part, so this bit needs to be added. 63 | MailcapCommandMap mc = (MailcapCommandMap) CommandMap 64 | .getDefaultCommandMap(); 65 | mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); 66 | mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 67 | mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); 68 | mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 69 | mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); 70 | CommandMap.setDefaultCommandMap(mc); 71 | } 72 | 73 | public Mail(String user, String pass) { 74 | this(); 75 | 76 | _user = user; 77 | _pass = pass; 78 | } 79 | 80 | public boolean send() throws Exception { 81 | Properties props = _setProperties(); 82 | 83 | if (!_user.equals("") && !_pass.equals("") && _to.length > 0 84 | && !_from.equals("") && !_subject.equals("") 85 | && !_body.equals("")) { 86 | Session session = Session.getInstance(props, this); 87 | 88 | MimeMessage msg = new MimeMessage(session); 89 | 90 | msg.setFrom(new InternetAddress(_from)); 91 | 92 | InternetAddress[] addressTo = new InternetAddress[_to.length]; 93 | for (int i = 0; i < _to.length; i++) { 94 | addressTo[i] = new InternetAddress(_to[i]); 95 | } 96 | msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 97 | 98 | msg.setSubject(_subject); 99 | msg.setSentDate(new Date()); 100 | 101 | // setup message body 102 | BodyPart messageBodyPart = new MimeBodyPart(); 103 | messageBodyPart.setText(_body); 104 | _multipart.addBodyPart(messageBodyPart); 105 | 106 | msg.setHeader("X-Priority", "1"); 107 | // Put parts in message 108 | msg.setContent(_multipart); 109 | 110 | // send email 111 | Transport.send(msg); 112 | 113 | return true; 114 | } else { 115 | return false; 116 | } 117 | } 118 | 119 | public void addAttachment(String filename) throws Exception { 120 | BodyPart messageBodyPart = new MimeBodyPart(); 121 | DataSource source = new FileDataSource(filename); 122 | messageBodyPart.setDataHandler(new DataHandler(source)); 123 | messageBodyPart.setFileName(filename); 124 | 125 | _multipart.addBodyPart(messageBodyPart); 126 | } 127 | 128 | @Override 129 | public PasswordAuthentication getPasswordAuthentication() { 130 | return new PasswordAuthentication(_user, _pass); 131 | } 132 | 133 | private Properties _setProperties() { 134 | Properties props = new Properties(); 135 | 136 | props.put("mail.smtp.host", _host); 137 | 138 | if (_debuggable) { 139 | props.put("mail.debug", "true"); 140 | } 141 | 142 | if (_auth) { 143 | props.put("mail.smtp.auth", "true"); 144 | } 145 | 146 | props.put("mail.smtp.port", _port); 147 | props.put("mail.smtp.socketFactory.port", _sport); 148 | props.put("mail.smtp.socketFactory.class", 149 | "javax.net.ssl.SSLSocketFactory"); 150 | props.put("mail.smtp.socketFactory.fallback", "false"); 151 | 152 | return props; 153 | } 154 | 155 | // the getters and setters 156 | public String getBody() { 157 | return _body; 158 | } 159 | 160 | public void setBody(String _body) { 161 | this._body = _body; 162 | } 163 | 164 | public String get_user() { 165 | return _user; 166 | } 167 | 168 | public void set_user(String _user) { 169 | this._user = _user; 170 | } 171 | 172 | public String get_pass() { 173 | return _pass; 174 | } 175 | 176 | public void set_pass(String _pass) { 177 | this._pass = _pass; 178 | } 179 | 180 | public String[] get_to() { 181 | return _to; 182 | } 183 | 184 | public void set_to(String[] _to) { 185 | this._to = _to; 186 | } 187 | 188 | public String get_from() { 189 | return _from; 190 | } 191 | 192 | public void set_from(String _from) { 193 | this._from = _from; 194 | } 195 | 196 | public String get_port() { 197 | return _port; 198 | } 199 | 200 | public void set_port(String _port) { 201 | this._port = _port; 202 | } 203 | 204 | public String get_sport() { 205 | return _sport; 206 | } 207 | 208 | public void set_sport(String _sport) { 209 | this._sport = _sport; 210 | } 211 | 212 | public String get_host() { 213 | return _host; 214 | } 215 | 216 | public void set_host(String _host) { 217 | this._host = _host; 218 | } 219 | 220 | public String get_subject() { 221 | return _subject; 222 | } 223 | 224 | public void set_subject(String _subject) { 225 | this._subject = _subject; 226 | } 227 | 228 | public boolean is_auth() { 229 | return _auth; 230 | } 231 | 232 | public void set_auth(boolean _auth) { 233 | this._auth = _auth; 234 | } 235 | 236 | public boolean is_debuggable() { 237 | return _debuggable; 238 | } 239 | 240 | public void set_debuggable(boolean _debuggable) { 241 | this._debuggable = _debuggable; 242 | } 243 | 244 | public Multipart get_multipart() { 245 | return _multipart; 246 | } 247 | 248 | public void set_multipart(Multipart _multipart) { 249 | this._multipart = _multipart; 250 | } 251 | } -------------------------------------------------------------------------------- /app/src/main/java/com/brandonjenniges/javamailapidemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.brandonjenniges.javamailapidemo; 2 | 3 | import android.os.AsyncTask; 4 | import android.os.Bundle; 5 | import android.support.design.widget.FloatingActionButton; 6 | import android.support.design.widget.Snackbar; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.Toolbar; 9 | import android.util.Log; 10 | import android.view.View; 11 | import android.widget.EditText; 12 | 13 | import javax.mail.AuthenticationFailedException; 14 | import javax.mail.MessagingException; 15 | 16 | public class MainActivity extends AppCompatActivity { 17 | 18 | private EditText user; 19 | private EditText pass; 20 | private EditText subject; 21 | private EditText body; 22 | private EditText recipient; 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_main); 28 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 29 | setSupportActionBar(toolbar); 30 | 31 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 32 | fab.setOnClickListener(new View.OnClickListener() { 33 | @Override 34 | public void onClick(View view) { 35 | sendMessage(); 36 | } 37 | }); 38 | 39 | user = (EditText) findViewById(R.id.username); 40 | pass = (EditText) findViewById(R.id.password); 41 | subject = (EditText) findViewById(R.id.subject); 42 | body = (EditText) findViewById(R.id.body); 43 | recipient = (EditText) findViewById(R.id.recipient); 44 | } 45 | 46 | private void sendMessage() { 47 | String[] recipients = { recipient.getText().toString() }; 48 | SendEmailAsyncTask email = new SendEmailAsyncTask(); 49 | email.activity = this; 50 | email.m = new Mail(user.getText().toString(), pass.getText() 51 | .toString()); 52 | email.m.set_from(user.getText().toString()); 53 | email.m.setBody(body.getText().toString()); 54 | email.m.set_to(recipients); 55 | email.m.set_subject(subject.getText().toString()); 56 | email.execute(); 57 | } 58 | 59 | public void displayMessage(String message) { 60 | Snackbar.make(findViewById(R.id.fab), message, Snackbar.LENGTH_LONG) 61 | .setAction("Action", null).show(); 62 | } 63 | } 64 | 65 | class SendEmailAsyncTask extends AsyncTask { 66 | Mail m; 67 | MainActivity activity; 68 | 69 | public SendEmailAsyncTask() {} 70 | 71 | @Override 72 | protected Boolean doInBackground(Void... params) { 73 | try { 74 | if (m.send()) { 75 | activity.displayMessage("Email sent."); 76 | } else { 77 | activity.displayMessage("Email failed to send."); 78 | } 79 | 80 | return true; 81 | } catch (AuthenticationFailedException e) { 82 | Log.e(SendEmailAsyncTask.class.getName(), "Bad account details"); 83 | e.printStackTrace(); 84 | activity.displayMessage("Authentication failed."); 85 | return false; 86 | } catch (MessagingException e) { 87 | Log.e(SendEmailAsyncTask.class.getName(), "Email failed"); 88 | e.printStackTrace(); 89 | activity.displayMessage("Email failed to send."); 90 | return false; 91 | } catch (Exception e) { 92 | e.printStackTrace(); 93 | activity.displayMessage("Unexpected error occured."); 94 | return false; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 20 | 21 | 25 | 26 | 31 | 32 | 33 | 37 | 38 | 42 | 43 | 48 | 49 | 50 | 54 | 55 | 59 | 60 | 65 | 66 | 67 | 71 | 72 | 76 | 77 | 82 | 83 | 84 | 88 | 89 | 93 | 94 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brandonjenniges/JavaMail-API-Android/b85612226118ab2a4afdf5dcb95c28b384279a32/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brandonjenniges/JavaMail-API-Android/b85612226118ab2a4afdf5dcb95c28b384279a32/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brandonjenniges/JavaMail-API-Android/b85612226118ab2a4afdf5dcb95c28b384279a32/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brandonjenniges/JavaMail-API-Android/b85612226118ab2a4afdf5dcb95c28b384279a32/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brandonjenniges/JavaMail-API-Android/b85612226118ab2a4afdf5dcb95c28b384279a32/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | > 2 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | JavaMail API Demo 3 | Settings 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 14 |