How to Send a Simple Email Programmatically? (Exists a Simple Way to Do It)

How to send a simple email programmatically? (exists a simple way to do it?)

First way.
If you don't want to be linked to the native email program or gmail program (via intent) to send the mail, but have the email sent in the background, see the code below.

You can use this helper class and adjust it to your needs.

package com.myapp.android.model.service;

import android.util.Log;
import com.myapp.android.MyApp;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;

public class MailService {
// public static final String MAIL_SERVER = "localhost";

private String toList;
private String ccList;
private String bccList;
private String subject;
final private static String SMTP_SERVER = DataService
.getSetting(DataService.SETTING_SMTP_SERVER);
private String from;
private String txtBody;
private String htmlBody;
private String replyToList;
private ArrayList<Attachment> attachments;
private boolean authenticationRequired = false;

public MailService(String from, String toList, String subject, String txtBody, String htmlBody,
Attachment attachment) {
this.txtBody = txtBody;
this.htmlBody = htmlBody;
this.subject = subject;
this.from = from;
this.toList = toList;
this.ccList = null;
this.bccList = null;
this.replyToList = null;
this.authenticationRequired = true;

this.attachments = new ArrayList<Attachment>();
if (attachment != null) {
this.attachments.add(attachment);
}
}

public MailService(String from, String toList, String subject, String txtBody, String htmlBody,
ArrayList<Attachment> attachments) {
this.txtBody = txtBody;
this.htmlBody = htmlBody;
this.subject = subject;
this.from = from;
this.toList = toList;
this.ccList = null;
this.bccList = null;
this.replyToList = null;
this.authenticationRequired = true;
this.attachments = attachments == null ? new ArrayList<Attachment>()
: attachments;
}

public void sendAuthenticated() throws AddressException, MessagingException {
authenticationRequired = true;
send();
}

/**
* Send an e-mail
*
* @throws MessagingException
* @throws AddressException
*/
public void send() throws AddressException, MessagingException {
Properties props = new Properties();

// set the host smtp address
props.put("mail.smtp.host", SMTP_SERVER);
props.put("mail.user", from);

props.put("mail.smtp.starttls.enable", "true"); // needed for gmail
props.put("mail.smtp.auth", "true"); // needed for gmail
props.put("mail.smtp.port", "587"); // gmail smtp port

/*Authenticator auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("mobile@mydomain.example", "mypassword");
}
};*/

Session session;

if (authenticationRequired) {
Authenticator auth = new SMTPAuthenticator();
props.put("mail.smtp.auth", "true");
session = Session.getDefaultInstance(props, auth);
} else {
session = Session.getDefaultInstance(props, null);
}

// get the default session
session.setDebug(true);

// create message
Message msg = new javax.mail.internet.MimeMessage(session);

// set from and to address
try {
msg.setFrom(new InternetAddress(from, from));
msg.setReplyTo(new InternetAddress[]{new InternetAddress(from,from)});
} catch (Exception e) {
msg.setFrom(new InternetAddress(from));
msg.setReplyTo(new InternetAddress[]{new InternetAddress(from)});
}

// set send date
msg.setSentDate(Calendar.getInstance().getTime());

// parse the recipients TO address
java.util.StringTokenizer st = new java.util.StringTokenizer(toList, ",");
int numberOfRecipients = st.countTokens();

javax.mail.internet.InternetAddress[] addressTo = new javax.mail.internet.InternetAddress[numberOfRecipients];

int i = 0;
while (st.hasMoreTokens()) {
addressTo[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}
msg.setRecipients(javax.mail.Message.RecipientType.TO, addressTo);

// parse the replyTo addresses
if (replyToList != null && !"".equals(replyToList)) {
st = new java.util.StringTokenizer(replyToList, ",");
int numberOfReplyTos = st.countTokens();
javax.mail.internet.InternetAddress[] addressReplyTo = new javax.mail.internet.InternetAddress[numberOfReplyTos];
i = 0;
while (st.hasMoreTokens()) {
addressReplyTo[i++] = new javax.mail.internet.InternetAddress(
st.nextToken());
}
msg.setReplyTo(addressReplyTo);
}

// parse the recipients CC address
if (ccList != null && !"".equals(ccList)) {
st = new java.util.StringTokenizer(ccList, ",");
int numberOfCCRecipients = st.countTokens();

javax.mail.internet.InternetAddress[] addressCC = new javax.mail.internet.InternetAddress[numberOfCCRecipients];

i = 0;
while (st.hasMoreTokens()) {
addressCC[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}

msg.setRecipients(javax.mail.Message.RecipientType.CC, addressCC);
}

// parse the recipients BCC address
if (bccList != null && !"".equals(bccList)) {
st = new java.util.StringTokenizer(bccList, ",");
int numberOfBCCRecipients = st.countTokens();

javax.mail.internet.InternetAddress[] addressBCC = new javax.mail.internet.InternetAddress[numberOfBCCRecipients];

i = 0;
while (st.hasMoreTokens()) {
addressBCC[i++] = new javax.mail.internet.InternetAddress(st
.nextToken());
}

msg.setRecipients(javax.mail.Message.RecipientType.BCC, addressBCC);
}

// set header
msg.addHeader("X-Mailer", "MyAppMailer");
msg.addHeader("Precedence", "bulk");
// setting the subject and content type
msg.setSubject(subject);

Multipart mp = new MimeMultipart("related");

// set body message
MimeBodyPart bodyMsg = new MimeBodyPart();
bodyMsg.setText(txtBody, "iso-8859-1");
if (attachments.size()>0) htmlBody = htmlBody.replaceAll("#filename#",attachments.get(0).getFilename());
if (htmlBody.indexOf("#header#")>=0) htmlBody = htmlBody.replaceAll("#header#",attachments.get(1).getFilename());
if (htmlBody.indexOf("#footer#")>=0) htmlBody = htmlBody.replaceAll("#footer#",attachments.get(2).getFilename());

bodyMsg.setContent(htmlBody, "text/html");
mp.addBodyPart(bodyMsg);

// set attachements if any
if (attachments != null && attachments.size() > 0) {
for (i = 0; i < attachments.size(); i++) {
Attachment a = attachments.get(i);
BodyPart att = new MimeBodyPart();
att.setDataHandler(new DataHandler(a.getDataSource()));
att.setFileName( a.getFilename() );
att.setHeader("Content-ID", "<" + a.getFilename() + ">");
mp.addBodyPart(att);
}
}
msg.setContent(mp);

// send it
try {
javax.mail.Transport.send(msg);
} catch (Exception e) {
e.printStackTrace();
}

}

/**
* SimpleAuthenticator is used to do simple authentication when the SMTP
* server requires it.
*/
private static class SMTPAuthenticator extends javax.mail.Authenticator {

@Override
protected PasswordAuthentication getPasswordAuthentication() {

String username = DataService
.getSetting(DataService.SETTING_SMTP_USER);
String password = DataService
.getSetting(DataService.SETTING_SMTP_PASSWORD);

return new PasswordAuthentication(username, password);
}
}

public String getToList() {
return toList;
}

public void setToList(String toList) {
this.toList = toList;
}

public String getCcList() {
return ccList;
}

public void setCcList(String ccList) {
this.ccList = ccList;
}

public String getBccList() {
return bccList;
}

public void setBccList(String bccList) {
this.bccList = bccList;
}

public String getSubject() {
return subject;
}

public void setSubject(String subject) {
this.subject = subject;
}

public void setFrom(String from) {
this.from = from;
}

public void setTxtBody(String body) {
this.txtBody = body;
}

public void setHtmlBody(String body) {
this.htmlBody = body;
}

public String getReplyToList() {
return replyToList;
}

public void setReplyToList(String replyToList) {
this.replyToList = replyToList;
}

public boolean isAuthenticationRequired() {
return authenticationRequired;
}

public void setAuthenticationRequired(boolean authenticationRequired) {
this.authenticationRequired = authenticationRequired;
}

}

And use this class:

MailService mailer = new MailService("from@mydomain.example","to@domain.example","Subject","TextBody", "<b>HtmlBody</b>", (Attachment) null);
try {
mailer.sendAuthenticated();
} catch (Exception e) {
Log.e(AskTingTing.APP, "Failed sending email.", e);
}

Second way.
Another option, if you don't mind using the native email client or gmail on Android for sending the mail (but the user actually has to hit the send button finally in the email client), you can do this:

startActivity(new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:to@gmail.com")));

How to send emails from my Android application?

The best (and easiest) way is to use an Intent:

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"recipient@example.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
i.putExtra(Intent.EXTRA_TEXT , "body of email");
try {
startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MyActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}

Otherwise you'll have to write your own client.

Sending email from Android app without using email client

Have your app tell your Web service to request a quote. Have your Web service send the email.

Anything involving sending the email directly from the client will involve either:

  • the user (by means of an email client)
  • a hard-coded password
  • a security flaw (e.g., an email client allowing other apps to send emails without user involvement)

Since none of those are options based on your question (plus, ethics), you need to send the email from somewhere else, and that "somewhere else" is inevitably some form of server. It would not have to be a Web service necessarily, but that would be the typical solution nowadays.

Send Email in Service (without prompting user)

The best solution is using the Gmail account to send the email.

Generally speaking:

  1. download mail.jar and activation.jar for android https://code.google.com/p/javamail-android/
  2. Connect to GMail to get the OAuth token
  3. Send the email

here's the code

import java.util.Properties;

import javax.activation.DataHandler;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;

import com.sun.mail.smtp.SMTPTransport;
import com.sun.mail.util.BASE64EncoderStream;

public class GMailSender {
private Session session;
private String token;

public String getToken() {
return token;
}

public GMailSender(Activity ctx) {
super();
initToken(ctx);
}

public void initToken(Activity ctx) {

AccountManager am = AccountManager.get(ctx);

Account[] accounts = am.getAccountsByType("com.google");
for (Account account : accounts) {
Log.d("getToken", "account="+account);
}

Account me = accounts[0]; //You need to get a google account on the device, it changes if you have more than one

am.getAuthToken(me, "oauth2:https://mail.google.com/", null, ctx, new AccountManagerCallback<Bundle>(){
@Override
public void run(AccountManagerFuture<Bundle> result){
try{
Bundle bundle = result.getResult();
token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
Log.d("initToken callback", "token="+token);

} catch (Exception e){
Log.d("test", e.getMessage());
}
}
}, null);

Log.d("getToken", "token="+token);
}

public SMTPTransport connectToSmtp(String host, int port, String userEmail,
String oauthToken, boolean debug) throws Exception {

Properties props = new Properties();
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
props.put("mail.smtp.sasl.enable", "false");

session = Session.getInstance(props);
session.setDebug(debug);

final URLName unusedUrlName = null;
SMTPTransport transport = new SMTPTransport(session, unusedUrlName);
// If the password is non-null, SMTP tries to do AUTH LOGIN.
final String emptyPassword = null;

/* enable if you use this code on an Activity (just for test) or use the AsyncTask
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
*/

transport.connect(host, port, userEmail, emptyPassword);

byte[] response = String.format("user=%s\1auth=Bearer %s\1\1",
userEmail, oauthToken).getBytes();
response = BASE64EncoderStream.encode(response);

transport.issueCommand("AUTH XOAUTH2 " + new String(response), 235);

return transport;
}

public synchronized void sendMail(String subject, String body, String user,
String oauthToken, String recipients) {
try {

SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com", 587,
user, oauthToken, true);

MimeMessage message = new MimeMessage(session);
DataHandler handler = new DataHandler(new ByteArrayDataSource(
body.getBytes(), "text/plain"));
message.setSender(new InternetAddress(user));
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));
smtpTransport.sendMessage(message, message.getAllRecipients());

} catch (Exception e) {
Log.d("test", e.getMessage(), e);
}
}

}

this code was originally posted here Javamail api in android using XOauth.

Please note to get the OAuth token you need an Activity and you have to ask the user which account to use. The token should be retrieved during the OnCreate phase and saved in the preferences. See also How to get the Android device's primary e-mail address

Alternatively you can use mail.jar but you have to ask the user for their username and password.

Send email through App without opening mail App in Android

In your account settings, allow smtp, and allow unsafe apps

send email from android app issue with subject and bcc

As you can see in the getting the address you got the text by .getText(); then you made it a string for other uses, because it was an editable text from editText. But in the other EditTextss you forgot to add .toString(); so you can use it as a string in email.

try this:

send.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {

final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");

emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{ address.getText().toString()});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject.getText().toString());
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, emailBody.getText().toString());
emailIntent.putExtra(android.content.Intent.EXTRA_BCC, CC.getText().toString());

startActivity(Intent.createChooser(emailIntent, "Send mail..."));
}
});

please ask if you didn't understand

Is it possible to send an email programmatically without using any actual email account

Yes, it is absolutely possible to do that. From a relatively low-level perspective, you need to:

  1. Resolve the MX (mail-exchanger) server for the e-mail account you want to send to.
  2. Open a socket to the MX server.
  3. Send the appropriate SMTP commands to cause the e-mail message to be delivered to your recipient account. You essentially have the freedom to set the "from" address to be any arbitrary thing you want.

SMTP is a very simple/human-friendly protocol, so it's not a massive effort to do all of that by hand. At the same time, there are prebuilt libraries that will handle all of that for you (except possibly the resolution of the recipient's MX server).

Note that emails sent this way are more likely to be filtered out as spam (generally because the sender's IP/hostname is not going to match whatever domain you put on the outgoing e-mail address you decide to use).

Also note that since you can set the "from" address to anything, you have the option of asking the user if they want to provide their actual contact address, and if they do you can make that the "from" address so that you can actually get back in touch with them if necessary.



Related Topics



Leave a reply



Submit