I'm trying to create a messaging application in Android.
If I use:
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
This will launch the built-in Android App; I tried to send mail without using this app by clicking the button directly.
#1 building
This is an alternative version, which is also useful for me, with attachments (it has been published above, but different from the source link, it is the full version, and people cannot make it work properly due to lack of data after publishing)
import java.util.Date; import java.util.Properties; import javax.activation.CommandMap; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.activation.MailcapCommandMap; import javax.mail.BodyPart; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; public class Mail extends javax.mail.Authenticator { private String _user; private String _pass; private String[] _to; private String _from; private String _port; private String _sport; private String _host; private String _subject; private String _body; private boolean _auth; private boolean _debuggable; private Multipart _multipart; public Mail() { _host = "smtp.gmail.com"; // default smtp server _port = "465"; // default smtp port _sport = "465"; // default socketfactory port _user = ""; // username _pass = ""; // password _from = ""; // email sent from _subject = ""; // email subject _body = ""; // email body _debuggable = false; // debug mode on or off - default off _auth = true; // smtp authentication - default on _multipart = new MimeMultipart(); // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added. MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); CommandMap.setDefaultCommandMap(mc); } public Mail(String user, String pass) { this(); _user = user; _pass = pass; } public boolean send() throws Exception { Properties props = _setProperties(); if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) { Session session = Session.getInstance(props, this); MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(_from)); InternetAddress[] addressTo = new InternetAddress[_to.length]; for (int i = 0; i < _to.length; i++) { addressTo[i] = new InternetAddress(_to[i]); } msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); msg.setSubject(_subject); msg.setSentDate(new Date()); // setup message body BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText(_body); _multipart.addBodyPart(messageBodyPart); // Put parts in message msg.setContent(_multipart); // send email Transport.send(msg); return true; } else { return false; } } public void addAttachment(String filename) throws Exception { BodyPart messageBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(filename); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(filename); _multipart.addBodyPart(messageBodyPart); } @Override public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(_user, _pass); } private Properties _setProperties() { Properties props = new Properties(); props.put("mail.smtp.host", _host); if(_debuggable) { props.put("mail.debug", "true"); } if(_auth) { props.put("mail.smtp.auth", "true"); } props.put("mail.smtp.port", _port); props.put("mail.smtp.socketFactory.port", _sport); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.socketFactory.fallback", "false"); return props; } // the getters and setters public String getBody() { return _body; } public void setBody(String _body) { this._body = _body; } public void setTo(String[] toArr) { // TODO Auto-generated method stub this._to=toArr; } public void setFrom(String string) { // TODO Auto-generated method stub this._from=string; } public void setSubject(String string) { // TODO Auto-generated method stub this._subject=string; } // more of the getters and setters ..... }
And call it in the activity
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); Button addImage = (Button) findViewById(R.id.send_email); addImage.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Mail m = new Mail("gmailusername@gmail.com", "password"); String[] toArr = {"bla@bla.com", "lala@lala.com"}; m.setTo(toArr); m.setFrom("wooo@wooo.com"); m.setSubject("This is an email sent using my Mail JavaMail wrapper from an Android device."); m.setBody("Email body."); try { m.addAttachment("/sdcard/filelocation"); if(m.send()) { Toast.makeText(MailApp.this, "Email was sent successfully.", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MailApp.this, "Email was not sent.", Toast.LENGTH_LONG).show(); } } catch(Exception e) { //Toast.makeText(MailApp.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show(); Log.e("MailApp", "Could not send email", e); } } }); }
#2 building
To help those using SDK target > 9 get the main thread network exception. This uses dropie's code above, but works similarly for any code.
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); android.os.NetworkOnMainThreadException
You can use AsyncTask as follows
public void onClickMail(View view) { new SendEmailAsyncTask().execute(); } class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> { Mail m = new Mail("from@gmail.com", "my password"); public SendEmailAsyncTask() { if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "SendEmailAsyncTask()"); String[] toArr = { "to mail@gmail.com"}; m.setTo(toArr); m.setFrom("from mail@gmail.com"); m.setSubject("Email from Android"); m.setBody("body."); } @Override protected Boolean doInBackground(Void... params) { if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "doInBackground()"); try { m.send(); return true; } catch (AuthenticationFailedException e) { Log.e(SendEmailAsyncTask.class.getName(), "Bad account details"); e.printStackTrace(); return false; } catch (MessagingException e) { Log.e(SendEmailAsyncTask.class.getName(), m.getTo(null) + "failed"); e.printStackTrace(); return false; } catch (Exception e) { e.printStackTrace(); return false; } }
#3 building
Have you considered using Apache Commons Net? Starting from 3.3, just a jar (you can use gradle or maven to rely on it) can be completed: http ://blog.dahanne.net/2013/06/17/sending-a-mail-in-java- And android with Apache commons net/
#4 building
You can use the JavaMail API to handle email tasks. JavaMail API is provided in JavaMail API, and its jar can also be downloaded. Unfortunately, because the AWT component it uses is completely incompatible in Android, it cannot be used directly in Android applications.
You can find the Android port for JavaMail at: http : //code.google.com/p/javamail-android/
Add cans to your application and use the SMTP method
#5 building
SMTP
Using SMTP is a feasible method, other methods have pointed out the implementation method. Just note that when you do this, you will completely avoid the built-in mail application, and you must statically provide the address of the SMTP server, the user name and password of the server, or query it from the user.
HTTP
Another way is to use a simple server-side script, such as PHP, that takes some URL parameters and uses them to send mail. In this way, you only need to issue HTTP requests from the device (which can be easily implemented using the built-in Library), without storing the SMTP login data on the device. This is another indirect way compared to using SMTP directly, but because it's easy to send HTTP requests and mail from PHP, it may even be simpler than using SMTP directly.
Mail application
If the message will be sent from the user's default mail account that he has already registered on the phone, you must do something else. If you have enough time and experience, you may need to check the Android Email application's source code to see if it provides some entry points to send mail without user intervention (I don't know, but maybe there is one).
Maybe you even found a way to query the user account details (so that it can be used for SMTP), although I highly doubt whether it is feasible, because it will bring huge security risks, and Android is quite safe to build.