http://pastie.org/4185959
I've used this code to make a mailing app that takes in authenticating parameters within the code. Sending the plain mail alone works fine, but adding the attachment is an issue, commenting out the line m.addAttachment() makes the mail send successfully even though I pass the path of a file correctly. Here's the code I use:
class MailSender extends AsyncTask<Void, Integer, Integer>
{
ProgressDialog pd = null;
/* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd = new ProgressDialog(MailSenderActivity.this);
pd.setTitle("Uploading...");
pd.setMessage("Uploading logs. Please wait...");
pd.setCancelable(false);
pd.show();
}
/* (non-Javadoc)
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected Integer doInBackground(Void... params) {
Mail m = new Mail("from_mail#gmail.com", "password");
String toAddresses = "to_mail#gmail.com";
m.setToAddresses(toAddresses);
m.setFromAddress("from_mail#gmail.com");
m.setMailSubject("This is an email sent using my Mail JavaMail wrapper from an Android device.");
m.setMailBody("Email body.");
/*try {
ZipUtility.zipDirectory(new File("/mnt/sdcard/logs/"), new File("/mnt/sdcard/logs.zip"));
} catch (IOException e1) {
Log.e("MailApp", "Could not zip folder", e1);
}*/
try {
m.addAttachment("/mnt/sdcard/Pictures/test.jpg");
if (m.send()) {
System.out.println("Message sent");
return 1;
} else {
return 2;
}
} catch (Exception e) {
Log.e("MailApp", "Could not send email", e);
}
return 3;
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pd.dismiss();
if(result==1)
Toast.makeText(MailSenderActivity.this,
"Email was sent successfully.", Toast.LENGTH_LONG)
.show();
else if(result==2)
Toast.makeText(MailSenderActivity.this,
"Email was not sent.", Toast.LENGTH_LONG).show();
else if(result==3)
Toast.makeText(MailSenderActivity.this,
"There was a problem sending the email.",
Toast.LENGTH_LONG).show();
}
And the Mail.java class
public class Mail extends javax.mail.Authenticator {
private Multipart attachements;
private String fromAddress = "";
private String accountEmail = "";
private String accountPassword = "";
private String smtpHost = "smtp.gmail.com";
private String smtpPort = "465"; // 465,587
private String toAddresses = "";
private String mailSubject = "";
private String mailBody = "";
public Mail() {
attachements = new MimeMultipart();
}
public Mail(String user, String pass) {
this();
accountEmail = user;
accountPassword = pass;
}
public boolean send() throws Exception {
Properties props = new Properties();
//props.put("mail.smtp.user", d_email);
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", smtpPort);
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
try {
Session session = Session.getInstance(props, this);
session.setDebug(true);
MimeMessage msg = new MimeMessage(session);
// create the message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
//fill message
messageBodyPart.setText(mailBody);
// add to multipart
attachements.addBodyPart(messageBodyPart);
//msg.setText(mailBody);
msg.setSubject(mailSubject);
msg.setFrom(new InternetAddress(fromAddress));
msg.addRecipients(Message.RecipientType.TO,
InternetAddress.parse(toAddresses));
msg.setContent(attachements);
Transport transport = session.getTransport("smtps");
transport.connect(smtpHost, 465, accountEmail, accountPassword);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
return true;
} catch (Exception e) {
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);
attachements.addBodyPart(messageBodyPart);
}
private String getFormattedDate(Date date)
{
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd-MMM-yyyy hh:mm:ss a");
return sdf.format(date);
}
#Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(accountEmail, accountPassword);
}
/**
* Gets the fromAddress.
*
* #return <tt> the fromAddress.</tt>
*/
public String getFromAddress() {
return fromAddress;
}
/**
* Sets the fromAddress.
*
* #param fromAddress <tt> the fromAddress to set.</tt>
*/
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
/**
* Gets the toAddresses.
*
* #return <tt> the toAddresses.</tt>
*/
public String getToAddresses() {
return toAddresses;
}
/**
* Sets the toAddresses.
*
* #param toAddresses <tt> the toAddresses to set.</tt>
*/
public void setToAddresses(String toAddresses) {
this.toAddresses = toAddresses;
}
/**
* Gets the mailSubject.
*
* #return <tt> the mailSubject.</tt>
*/
public String getMailSubject() {
return mailSubject;
}
/**
* Sets the mailSubject.
*
* #param mailSubject <tt> the mailSubject to set.</tt>
*/
public void setMailSubject(String mailSubject) {
this.mailSubject = mailSubject;
}
/**
* Gets the mailBody.
*
* #return <tt> the mailBody.</tt>
*/
public String getMailBody() {
return mailBody;
}
/**
* Sets the mailBody.
*
* #param mailBody <tt> the mailBody to set.</tt>
*/
public void setMailBody(String mailBody) {
this.mailBody = mailBody;
}
}
As you can see, the addAttachment method only takes in a string, specifically the file path. I've passed the file path directly, as I have a file named 'test.jpg' in my Pictures folder, but I'm still getting this message:
java.io.FileNotFoundException: /mnt/sdcard/Pictures/test.jpg: open failed: EACCES (Permission denied)
I've added permissions for both the INTERNET and EXTERNAL_DATA_STORAGE, so that's not the issue. It seems as though for some reason I cannot access this file within the Pictures folder.
Here's the location of the file within Amaze:
http://i.imgur.com/nbsWzsb.png
Related
so I searched a lot to send an email throught my app, but without the user having to log in in an email app and send it himself. I would like to just let him write it in an editText and then just press a button and send it to me. So that's what I did: 2 classes for the mail thing, my activity which calls it, add the 3 libraries and the internet permission. What did I do wrong?
Here is where I call the email process :
private View.OnClickListener btnMode1Listener = new
View.OnClickListener() {
#Override
public void onClick(View v) {
suggestionText = entre_suggestion.getText().toString();
Log.i("SendMailActivity", "Send Button Clicked.");
String fromEmail = "fromEmail#gmail.com";
String fromPassword = "frompassword";
String toEmails = "toEmail#gmail.com";
List toEmailList = Arrays.asList(toEmails
.split("\\s*,\\s*"));
Log.i("SendMailActivity", "To List: " + toEmailList);
String emailSubject = "Suggestion";
String emailBody = suggestionText;
new SendMailTask(suggestions.this).execute(fromEmail,
fromPassword, toEmailList, emailSubject, emailBody);
}
};
This is the first class "GMail":
public class GMail {
final String emailPort = "587";// gmail's smtp port
final String smtpAuth = "true";
final String starttls = "true";
final String emailHost = "smtp.gmail.com";
String fromEmail;
String fromPassword;
List toEmailList;
String emailSubject;
String emailBody;
Properties emailProperties;
Session mailSession;
MimeMessage emailMessage;
public GMail() {
}
public GMail(String fromEmail, String fromPassword,
List toEmailList, String emailSubject, String emailBody) {
this.fromEmail = fromEmail;
this.fromPassword = fromPassword;
this.toEmailList = toEmailList;
this.emailSubject = emailSubject;
this.emailBody = emailBody;
emailProperties = System.getProperties();
emailProperties.put("mail.smtp.port", emailPort);
emailProperties.put("mail.smtp.auth", smtpAuth);
emailProperties.put("mail.smtp.starttls.enable", starttls);
Log.i("GMail", "Mail server properties set.");
}
public MimeMessage createEmailMessage() throws AddressException,
MessagingException, UnsupportedEncodingException {
mailSession = Session.getDefaultInstance(emailProperties, null);
emailMessage = new MimeMessage(mailSession);
emailMessage.setFrom(new InternetAddress(fromEmail, fromEmail));
for (Object toEmail : toEmailList) {
Log.i("GMail","toEmail: "+toEmail);
emailMessage.addRecipient(Message.RecipientType.TO,
new InternetAddress((String) toEmail));
}
emailMessage.setSubject(emailSubject);
emailMessage.setContent(emailBody, "text/html");// for a html email
// emailMessage.setText(emailBody);// for a text email
Log.i("GMail", "Email Message created.");
return emailMessage;
}
public void sendEmail() throws AddressException, MessagingException {
Transport transport = mailSession.getTransport("smtp");
transport.connect(emailHost, fromEmail, fromPassword);
Log.i("GMail","allrecipients: "+emailMessage.getAllRecipients());
transport.sendMessage(emailMessage, emailMessage.getAllRecipients());
transport.close();
Log.i("GMail", "Email sent successfully.");
}
}
And this is the second class "SendMailtask":
public class SendMailTask extends AsyncTask {
private ProgressDialog statusDialog;
private Activity sendMailActivity;
public SendMailTask(Activity activity) {
sendMailActivity = activity;
}
protected void onPreExecute() {
statusDialog = new ProgressDialog(sendMailActivity);
statusDialog.setMessage("Getting ready...");
statusDialog.setIndeterminate(false);
statusDialog.setCancelable(false);
statusDialog.show();
}
#Override
protected Object doInBackground(Object... args) {
try {
Log.i("SendMailTask", "About to instantiate GMail...");
publishProgress("Processing input....");
GMail androidEmail = new GMail(args[0].toString(),
args[1].toString(), (List) args[2], args[3].toString(),
args[4].toString());
publishProgress("Preparing mail message....");
androidEmail.createEmailMessage();
publishProgress("Sending email....");
androidEmail.sendEmail();
publishProgress("Email Sent.");
Log.i("SendMailTask", "Mail Sent.");
} catch (Exception e) {
publishProgress(e.getMessage());
Log.e("SendMailTask", e.getMessage(), e);
}
return null;
}
#Override
public void onProgressUpdate(Object... values) {
statusDialog.setMessage(values[0].toString());
}
#Override
public void onPostExecute(Object result) {
statusDialog.dismiss();
}
}
And finally, the 3 librairies I added:
compile files('libs/activation.jar')
compile files('libs/additionnal.jar')
compile files('libs/mail.jar')
So yeah, I searched a lot and didn't find how to debug it. I tried a lot of different ways but it never sent the email. I just want to be clear that I don't want to open the mail app, I want the email to be sent without the user having to do something.
package com.auto.smartautomates.smartautomates.Helpers;
import com.crashlytics.android.Crashlytics;
import java.util.Calendar;
import java.util.Properties;
import javax.mail.Authenticator;
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;
/**
* Created by sardar.khan on 6/8/2017.
*/
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 = "smtp.gmail.com";
private String from;
private String txtBody;
private String htmlBody;
private String replyToList;
private boolean authenticationRequired = false;
public MailService(String from, String toList, String subject, String txtBody, String htmlBody) {
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;
}
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 587 default gmail
/*Authenticator auth = new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("mobile#mydomain.com", "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) {
Crashlytics.logException(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");
bodyMsg.setContent(htmlBody, "text/html");
mp.addBodyPart(bodyMsg);
msg.setContent(mp);
// send it
try {
javax.mail.Transport.send(msg);
} catch (Exception e) {
Crashlytics.logException(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 = "someEmail#gmail.com";
String password ="yourPassword";
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;
}
}
In your account settings, allow smtp, and allow unsafe apps
I am using following code. But in the mail, I am getting the palin html tags only not output in table format. Please help me to get the output as table format in the mail
StringBuilder content = new StringBuilder();
content.append("<HTML>")
.append("<HEAD>")
.append("<TITLE>Welcome</TITLE>")
.append("</HEAD>")
// Start on the body
.append("<BODY>")
.append("<CENTER>")
.append("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 WIDTH=70%>")
.append("<TR>")
.append("<TH style=\"padding:5px\">Subject</TH>")
.append("<TH style=\"padding:5px\">Grade</TH>")
.append("</TR>")
.append("<TR>")
.append("<TD>Mathmatics</TD>")
.append("<TD>A</TD>")
.append("</TR>")
.append("<TR>")
.append("<TD>SCEINECE</TD>")
.append("<TD>B</TD>")
.append("</TR>")
.append("</TABLE>")
.append("</CENTER>")
.append("</BODY></HTML>");
String resultMessage = "";
try {
EmailUtility.sendEmail(host, port, user, pass, recipient, subject, content.toString());
}
i have used javax mail. this will work
public class Main {
public static void main(String[] arg) {
StringBuilder MessageContent = new StringBuilder();
MessageContent.append("<HTML>")
.append("<HEAD>")
.append("<TITLE>Welcome</TITLE>")
.append("</HEAD>")
// Start on the body
.append("<BODY>")
.append("<CENTER>")
.append("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 WIDTH=70%>")
.append("<TR>")
.append("<TH style=\"padding:5px\">Subject</TH>")
.append("<TH style=\"padding:5px\">Grade</TH>")
.append("</TR>")
.append("<TR>")
.append("<TD>Mathmatics</TD>")
.append("<TD>A</TD>")
.append("</TR>")
.append("<TR>")
.append("<TD>SCEINECE</TD>")
.append("<TD>B</TD>")
.append("</TR>")
.append("</TABLE>")
.append("</CENTER>")
.append("</BODY></HTML>");
MailParam mp = new MailParam();
mp.setUsername("....");
.....
Properties props = new Properties();
props.put("mail.smtp.auth", mailParam.getAuth());
props.put("mail.smtp.starttls.enable", mailParam.getStartls());
props.put("mail.smtp.host", mailParam.getHost());
props.put("mail.smtp.port", mailParam.getPort());
BodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
try {
messageBodyPart.setContent(MessageContent, "text/html; charset=utf-8");
//messageBodyPart.setText(MessageContent);
multipart.addBodyPart(messageBodyPart);
} catch (MessagingException e) {
e.printStackTrace();
}
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(mailParam.getUsername(), mailParam.getPwd());
}
});
// Sender's email ID needs to be mentioned
try {
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
message.addHeader("Content-type", "text/HTML; charset=UTF-8");
message.addHeader("Content-Transfer-Encoding", "quoted-printable");
// Set From: header field of the header.
message.setFrom(new InternetAddress("your_mail#yourdomain");
//message.setRecipients(Message.RecipientType.TO,recipientAddress);
message.setRecipients(Message.RecipientType.TO, "npsantost#libero.it");
// Set Subject: header field
message.setSubject("my subject");
// Send the actual HTML message, as big as you like
//message.setContent("<h1>This is actual message</h1>", "text/html");
message.setContent(multipart);
// Send message
Transport.send(message);
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
MailParam class
public class MailParam {
private String username;
String pwd;
String auth;
String startls;
String host;
String port;
String from;
String replyto;
String logopath;
public String getAuth() {
return auth;
}
public String getHost() {
return host;
}
public String getPort() {
return port;
}
public String getPwd() {
return pwd;
}
public String getStartls() {
return startls;
}
public String getUsername() {
return username;
}
public String getFrom() {
return from;
}
public String getReplyto() {
return replyto;
}
public String getLogopath() {
return logopath;
}
public void setAuth(String val) {
auth = val;
}
public void setHost(String val) {
host = val;
}
public void setPort(String val) {
port = val;
}
public void setPwd(String val) {
pwd = val;
}
public void setStartls(String val) {
startls = val;
}
public void setUsername(String val) {
username = val;
}
public void setFrom(String val) {
from = val;
}
public void setReplyto(String val) {
replyto = val;
}
public void setLogoPath(String val) {
logopath = val;
}
}
Here is my Utility class code:
public class EmailUtility {
public static void sendEmail(String host, String port,
final String userName, final String password, String toAddress,
String subject, String message) throws AddressException,
MessagingException {
// sets SMTP server properties
Properties properties = new Properties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
// creates a new session with an authenticator
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
};
Session session = Session.getInstance(properties, auth);
// creates a new e-mail message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(userName));
InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
msg.setRecipients(Message.RecipientType.TO, toAddresses);
msg.setSubject(subject);
msg.setSentDate(new Date());
msg.setText(message);
// sends the e-mail
Transport.send(msg);
}
}
add this block in your Class EmailUtility
BodyPart messageBodyPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart();
try {
messageBodyPart.setContent(message, "text/html; charset=utf-8");
//messageBodyPart.setText(MessageContent);
multipart.addBodyPart(messageBodyPart);
} catch (MessagingException e) {
e.printStackTrace();
}
then replace
msg.setText(message);
with
// creates a new e-mail message
Message msg = new MimeMessage(session);
msg.setContent(multipart);
I downloaded the code from the below link for android which has option to send echo, broadcast as well as user notification message.
Link for Android
Then I tried to use many codes for server side without any success so I studied and wrote the below code for the server side which I have hosted on Tomcat Server and there is a servlet which activates the client.
public class CcsServlet extends HttpServlet
{
private static Logger logger = Logger.getLogger(CcsServlet.class.getName());
private static final String USERNAME = "855350893195" + "#gcm.googleapis.com";
private static final String PASSWORD = "AIzaSyA9DQTcggUtABVC9lnV_Xb5VEQ8iKBEaP4";//AIzaSyAxDKiYUkU8EvtOgaCeZMypVJpzcYgyjhw-server
public void init(ServletConfig config) throws ServletException
{
SmackCcsClient ccsManager = SmackCcsClient.getInstance();
try
{
ccsManager.connect(USERNAME,PASSWORD);
}
catch (Exception e)
{
logger.warning("Cannot connect to CCS server.");
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{
}
}
Code for the SmackCcsClient
public class SmackCcsClient {
private static Logger log = LoggerFactory.getLogger(SmackCcsClient.class);
private static SmackCcsClient sInstance = null;
XMPPConnection connection;
ConnectionConfiguration config;
public SmackCcsClient() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(
GCMConstants.GCM_ELEMENT_NAME,
GCMConstants.GCM_NAMESPACE,
new PacketExtensionProvider() {
#Override
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Returns a random message id to uniquely identify a message.
*
*/
public String getRandomMessageId() {
return UUID.randomUUID().toString();
}
/**
* Sends a downstream GCM message.
*/
public void send(String jsonRequest) {
Packet request = new GcmPacketExtension(jsonRequest).toPacket();
connection.sendPacket(request);
}
public static SmackCcsClient getInstance()
{
if (sInstance == null)
sInstance = new SmackCcsClient();
return sInstance;
}
/**
* Handles an upstream data message from a device application.
*
* <p>
* This sample echo server sends an echo message back to the device.
* Subclasses should override this method to process an upstream message.
*/
public void handleIncomingDataMessage(Map<String, Object> jsonObject) {
String from = jsonObject.get("from").toString();
// PackageName of the application that sent this message.
String category = jsonObject.get("category").toString();
// Use the packageName as the collapseKey in the echo packet
String collapseKey = "echo:CollapseKey";
#SuppressWarnings("unchecked")
Map<String, String> payload = (Map<String, String>) jsonObject.get("data");
payload.put("ECHO", "Application: " + category);
// Send an ECHO response back
String echo = createJsonMessage(from, getRandomMessageId(), payload, collapseKey, null, false);
send(echo);
}
/**
* Handles an ACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle ACKS.
*/
public void handleAckReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
log.debug("handleAckReceipt from: {}, messageId: {}", from, messageId);
}
/**
* Handles a NACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle NACKS.
*/
public void handleNackReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
log.debug("handleNackReceipt() from: {}, messageId: {}",from, messageId);
}
/**
* Creates a JSON encoded GCM message.
*
* #param to
* RegistrationId of the target device (Required).
* #param messageId
* Unique messageId for which CCS will send an "ack/nack"
* (Required).
* #param payload
* Message content intended for the application. (Optional).
* #param collapseKey
* GCM collapse_key parameter (Optional).
* #param timeToLive
* GCM time_to_live parameter (Optional).
* #param delayWhileIdle
* GCM delay_while_idle parameter (Optional).
* #return JSON encoded GCM message.
*/
public static String createJsonMessage(String to, String messageId,
Map<String, String> payload, String collapseKey, Long timeToLive,
Boolean delayWhileIdle) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("to", to);
if (collapseKey != null) {
message.put("collapse_key", collapseKey);
}
if (timeToLive != null) {
message.put("time_to_live", timeToLive);
}
if (delayWhileIdle != null && delayWhileIdle) {
message.put("delay_while_idle", true);
}
message.put("message_id", messageId);
message.put("data", payload);
return JSONValue.toJSONString(message);
}
/**
* Creates a JSON encoded ACK message for an upstream message received from
* an application.
*
* #param to
* RegistrationId of the device who sent the upstream message.
* #param messageId
* messageId of the upstream message to be acknowledged to CCS.
* #return JSON encoded ack.
*/
public static String createJsonAck(String to, String messageId) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("message_type", "ack");
message.put("to", to);
message.put("message_id", messageId);
return JSONValue.toJSONString(message);
}
/**
* Connects to GCM Cloud Connection Server using the supplied credentials.
*
* #param username
* GCM_SENDER_ID#gcm.googleapis.com
* #param password
* API Key
* #throws XMPPException
*/
public void connect(String username, String password) throws XMPPException {
config = new ConnectionConfiguration(GCMConstants.GCM_SERVER, GCMConstants.GCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());
// NOTE: Set to true to launch a window with information about packets
// sent and received
config.setDebuggerEnabled(true);
// -Dsmack.debugEnabled=true
XMPPConnection.DEBUG_ENABLED = true;
connection = new XMPPConnection(config);
connection.connect();
//**code used to send downstream message**
String toRegId = "APA91bECAx_1rzceJbPwas5FyRGPmpYFvWSJ0hfUlT30DSsrsXmBC5W-VmYTI0p8Gg9VZh598iNBcVki-H1dloBnaETfvZlJUZskTxHKE7DoDAgapH_X_DJE3toyZwXS4SHIdt5lYLty6OU_tmAOTZN4n88jlmSaR2_MrNmY1HuAMlddMfqAr10";
String messageId = sInstance.getRandomMessageId();
Map<String, String> payload = new HashMap<String, String>();
payload.put("Hello", "World");
payload.put("CCS", "Dummy Message");
payload.put("EmbeddedMessageId", messageId);
String collapseKey = "sample";
Long timeToLive = 10000L;
Boolean delayWhileIdle = true;
sInstance.send(createJsonMessage(toRegId, messageId, payload,
collapseKey, timeToLive, delayWhileIdle));
connection.addConnectionListener(new ConnectionListener() {
#Override
public void reconnectionSuccessful() {
log.info("Reconnecting..");
}
#Override
public void reconnectionFailed(Exception e) {
log.info( "Reconnection failed.. ", e);
}
#Override
public void reconnectingIn(int seconds) {
log.info( "Reconnecting in %d secs", seconds);
}
#Override
public void connectionClosedOnError(Exception e) {
log.info( "Connection closed on error.");
}
#Override
public void connectionClosed() {
log.info("Connection closed.");
}
});
// Handle incoming packets
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
log.info( "Received: " + packet.toXML());
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage.getExtension(GCMConstants.GCM_NAMESPACE);
String json = gcmPacket.getJson();
try {
#SuppressWarnings("unchecked")
Map<String, Object> jsonObject = (Map<String, Object>) JSONValue
.parseWithException(json);
// present for "ack"/"nack", null otherwise
Object messageType = jsonObject.get("message_type");
if (messageType == null) {
// Normal upstream data message
handleIncomingDataMessage(jsonObject);
// Send ACK to CCS
String messageId = jsonObject.get("message_id")
.toString();
String from = jsonObject.get("from").toString();
String ack = createJsonAck(from, messageId);
send(ack);
} else if ("ack".equals(messageType.toString())) {
// Process Ack
handleAckReceipt(jsonObject);
} else if ("nack".equals(messageType.toString())) {
// Process Nack
handleNackReceipt(jsonObject);
} else {
// logger.log(Level.WARNING,
// "Unrecognized message type (%s)",
messageType.toString();
}
} catch (Exception e) {
// logger.log(Level.SEVERE, "Couldn't send echo.", e);
}
}
}, new PacketTypeFilter(Message.class));
// Log all outgoing packets
connection.addPacketWriterInterceptor(new PacketInterceptor() {
#Override
public void interceptPacket(Packet packet) {
log.info( "Sent: {0}", packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(username, password);
}
}
Code for GcmPacketExtension
class GcmPacketExtension extends DefaultPacketExtension {
String json;
public GcmPacketExtension(String json) {
super(GCMConstants.GCM_ELEMENT_NAME, GCMConstants.GCM_NAMESPACE);
this.json = json;
}
public String getJson() {
return json;
}
#Override
public String toXML() {
return String.format("<%s xmlns=\"%s\">%s</%s>", GCMConstants.GCM_ELEMENT_NAME,
GCMConstants.GCM_NAMESPACE, json, GCMConstants.GCM_ELEMENT_NAME);
}
#SuppressWarnings("unused")
public Packet toPacket() {
return new Message() {
// Must override toXML() because it includes a <body>
#Override
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<message");
if (getXmlns() != null) {
buf.append(" xmlns=\"").append(getXmlns()).append("\"");
}
if (getDefaultLanguage() != null) {
buf.append(" xml:lang=\"").append(getDefaultLanguage())
.append("\"");
}
if (getPacketID() != null) {
buf.append(" id=\"").append(getPacketID()).append("\"");
}
if (getTo() != null) {
buf.append(" to=\"")
.append(StringUtils.escapeForXML(getTo()))
.append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"")
.append(StringUtils.escapeForXML(getFrom()))
.append("\"");
}
buf.append(">");
buf.append(GcmPacketExtension.this.toXML());
buf.append("</message>");
return buf.toString();
}
};
}
}
Code for GcmConstants
public class GCMConstants {
public static final String GCM_SERVER = "gcm.googleapis.com";
public static final int GCM_PORT = 5235;
public static final String GCM_ELEMENT_NAME = "gcm";
public static final String GCM_NAMESPACE = "google:mobile:data";
}
Now when I try to send a downstream message using the code in connect that does not reach the device which device id I have given or Echo message from device also does not echoed by server.
Is it required to sign up thing for CCS required because I have already signed up, however did not get any response.
Second question is why neither of the communication is working.
Now I have cleared up all the issues and now my servlet is running and making a connection however it is returning "No Response from the server", which I am getting as exception while connecting.
I know this issue is old, but I didn't find any solution for SimpleMailMessage with properties added in the class and not in the xml. There is no exeption after my app starts, its simply not sending mail. The method CustomMailDeliveryImpl.sendMail() is trigered from Controlller. I cant find a mistake.
#Component("CustomMailDelivery")
public class CustomMailDeliveryImpl implements CustomMailDelivery {
protected static Logger logger = Logger.getLogger(CustomMailDeliveryImpl.class);
private EmployeeService employeeService;
private String username = "* * *#gmail.com";
private String password = "* * *";
private JavaMailSenderImpl sender = new JavaMailSenderImpl();
#Autowired
public void setSender(JavaMailSenderImpl sender) {
this.sender = sender;
}
#Autowired
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
/**
* #param from - must contain address of sender,
* #param to - must contain address of target,
* #param subject - must be included with short description,
* #param body - main message of mail.
* #throws RuntimeException if any param is empty.
*/
public void sendMail(String from, String to, String subject, String body) {
// selecting settings from DB
SystemSettingsModel settingsModel = employeeService.getSettingsByName("default");
// defining settings
sender.setHost(settingsModel.getSmtpServerAddress());
sender.setPort(settingsModel.getSmtpServerPort());
sender.setUsername(username);
sender.setPassword(password);
// defining SMTP properties
Properties properties = new Properties();
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.debug", "1");
Session session = Session.getDefaultInstance(properties, null);
sender.setSession(session);
// initiating mail
SimpleMailMessage simpleMessage = new SimpleMailMessage();
try {
if (from != null && to != null) {
if (subject != null && body != null) {
simpleMessage.setFrom(from);
simpleMessage.setTo(to);
simpleMessage.setSubject(subject);
simpleMessage.setText(body);
sender.send(simpleMessage);
logger.debug("Mail has been sent successfully");
} else {
throw new MessagingException("Subject and message of mail is empty!");
}
} else {
throw new MessagingException("Address of object and target is empty!");
}
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
Any help appreciated !!!!
I finally managed to overcome this issue and I did found the solution! With this way? you can pass properties from page configuration or DAO Service!
#Component("CustomMailDeliveryImpl")
public class CustomMailDeliveryImpl implements CustomMailDelivery {
private EmployeeService employeeService;
private Transport transport;
private String username = "***#gmail.com";
private String password = "***";
private SystemSettingsModel settingsModel;
private Session session;
private MimeMessage message;
private InternetAddress fromAddress, toAddress;
private Properties properties;
#Autowired
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
public void sendMail(String from, String to, String subject, String body) throws SendFailedException {
settingsModel = employeeService.getSettingsByName("default");
// defining properties
properties = new Properties();
properties.put("mail.smtp.host", settingsModel.getSmtpServerAddress());
properties.put("mail.smtp.port", settingsModel.getSmtpServerPort());
properties.put("mail.smtp.user", username);
properties.put("mail.smtp.password", password);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
// InternetAddress initialisation
try {
fromAddress = new InternetAddress(from);
toAddress = new InternetAddress(to);
// new Authenticator session
session = (javax.mail.Session) Session.getDefaultInstance(properties, null);
} catch (AddressException e) {
throw new RuntimeException();
}
// executing mail sending
try {
if (from != null && to != null) {
if (subject != null && body != null) {
// defining message
message = new MimeMessage(session);
message.setFrom(fromAddress);
message.addRecipient(Message.RecipientType.TO, toAddress);
message.setSubject(subject);
message.setText(body);
message.setSentDate(new Date());
message.setHeader("MIME-Version" , "1.0" );
message.setHeader("Content-Type" , "text/html" );
// Transport initialisation
if (transport == null) {
transport = session.getTransport("smtp");
if (!transport.isConnected())
transport.connect(settingsModel.getSmtpServerAddress(),
settingsModel.getSmtpServerPort(), username, password);
}
transport.sendMessage(message, message.getAllRecipients());
} else {
throw new MessagingException("Subject and message of mail is empty!");
}
} else {
throw new MessagingException("Address and target of mail is empty!");
}
} catch (MessagingException e) {
e.printStackTrace();
throw new RuntimeException();
} finally {
if (transport != null) try {
transport.close();
} catch (MessagingException ignore) {
}
}
}
}
It's working just perfect!!
I work with log4j.properties through WSO2 products. I needed implement a appender to work with SMTPAppender and send emails notifications using gmail smtp server. So, when I config log4j and start ESB WSO2 Server, the manage console print: log4j:ERROR Could not instantiate class [com.notification.GmailSMTPAppender].
My implementation was:
package com.notification;
public class GmailSMTPAppender extends SMTPAppender {
protected Session session;
public GmailSMTPAppender() {
super();
}
/**
* Create mail session.
*
* #return mail session, may not be null.
*/
protected Session createSession() {
Properties props = new Properties();
props.put("mail.smtps.host", getSMTPHost());
props.put("mail.smtps.auth", "true");
Authenticator auth = null;
if (getSMTPPassword() != null && getSMTPUsername() != null) {
auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getSMTPUsername(),
getSMTPPassword());
}
};
}
session = Session.getInstance(props, auth);
if (getSMTPProtocol() != null) {
session.setProtocolForAddress("rfc822", getSMTPProtocol());
}
if (getSMTPDebug()) {
session.setDebug(getSMTPDebug());
}
return session;
}
/**
* Send the contents of the cyclic buffer as an e-mail message.
*/
protected void sendBuffer() {
try {
MimeBodyPart part = new MimeBodyPart();
StringBuffer sbuf = new StringBuffer();
String t = layout.getHeader();
if (t != null)
sbuf.append(t);
int len = cb.length();
for (int i = 0; i < len; i++) {
LoggingEvent event = cb.get();
sbuf.append(layout.format(event));
if (layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
for (int j = 0; j < s.length; j++) {
sbuf.append(s[j]);
sbuf.append(Layout.LINE_SEP);
}
}
}
}
t = layout.getFooter();
if (t != null)
sbuf.append(t);
part.setContent(sbuf.toString(), layout.getContentType());
Multipart mp = new MimeMultipart();
mp.addBodyPart(part);
msg.setContent(mp);
msg.setSentDate(new Date());
send(msg);
} catch (Exception e) {
LogLog.error("Error occured while sending e-mail notification.", e);
}
}
/**
* Pulled email send stuff i.e. Transport.send()/Transport.sendMessage(). So
* that on required this logic can be enhanced.
*
* #param msg
* Email Message
* #throws MessagingException
*/
protected void send(Message msg) throws MessagingException {
SMTPTransport t = (SMTPTransport) session.getTransport("smtps");
try {
t.connect(getSMTPHost(), getSMTPUsername(), getSMTPPassword());
t.sendMessage(msg, msg.getAllRecipients());
} finally {
System.out.println("Response: " + t.getLastServerResponse());
t.close();
}
}
}
How I can instantiate of this appender on my log4j.properties configuration ??
Do you need to programatically add the Appender?
Check the following post