I need to send an e-mail with attachments automatically without user input. I previously read these 2 answers.
Sending Email in Android using JavaMail API without using the default/built-in app
Android: Send e-mail with attachment automatically in the background.
But now I don't receive any e-mail and I already enabled the less secure apps in gmail. Here's my code :
public class Mail {
private String mailhost;
private String user;
private String password;
private Session session;
private String serverport;
public void main(String user, String password, String subject, String body){
sendFromGMail(user, password, subject,body);
}
private void sendFromGMail(String from, String pass, String subject, String body){
Properties props = System.getProperties();
String host = "smtp.gmail.com";
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "465");
props.put("mail.smtp.auth", "true");
Session session = Session.getInstance(props);
MimeMessage message = new MimeMessage(session);
try {
InternetAddress adressTo = new InternetAddress(from);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, adressTo);
message.setSubject(subject);
message.setText(body);
Transport transport = session.getTransport("smtp");
transport.connect(host, from, pass);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
catch(MessagingException e){
Log.e("Not Sent", e.getMessage(), e);
}
}
}
And this is how I use it :
try {
Mail mail = new Mail();
mail.main(gmailusername, gmailpassword, "Test", "Test2");
this.publishProgress("Email Sent");
}catch(Exception e){
Log.e("SendMail", e.getMessage(), e);
this.publishProgress("Email not sent");
}
Edit : I don't want to use the built-in app as the title suggested. Just wanted to make it clear.
Java debug :
08-12 15:08:41.152 24062-24340/com.documax.cardreader I/System.out﹕ DEBUG: setDebug: JavaMail version 1.4.1
08-12 15:08:41.162 24062-24340/com.documax.cardreader I/System.out﹕ DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc.,1.4.1]
08-12 15:08:41.162 24062-24340/com.documax.cardreader I/System.out﹕ DEBUG SMTP: useEhlo true, useAuth true
08-12 15:08:41.162 24062-24340/com.documax.cardreader I/System.out﹕ DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL false
Fix all these common mistakes, including getting rid of the Authenticator.
Get rid of the call to super() in your constructor, you don't need it.
Also, get rid of the ByteArrayDataSource class. You don't need your own since it comes with JavaMail. Plus, your program isn't even using it.
If it still doesn't work, update your post with your new code and new failure details.
Related
I am developing an android app. In my android app I am having feed back form. and I take a email id from user as input. and i want when a user clicks on submit button the email should send.
I dont want that user should add his/her password for that.
I have checked the default method by Intent and the second method in the below link ..
Second Method
If you want the email to be sent from the account of the user of the app, a proper authentication would be required.
As a result, either you could send an intent to email app (as you mentioned) or you could do it yourself (as in second method mentioned by you).
But the second method obviously requires password since you are sending an email on behalf of the user (from their account). Gmail (or any mail service provider as a matter of fact) won't allow that without a password.
So to answer your question in a nutshell, no. You can not do it without a password.
In stead, you could use a work around. You can send all emails sent through your apps from a single mail id (which is created by you so you know the password). Now in the content of the email, you can store the email id of the user from whom you are asking for the feedback.
This way, you just have to ask for the mail id (no password) and you also get their contact information if you want to contact them back.
Hope this helps.
Good luck.
I had the same question and found a solution that I modified to work for me. You can do a search in stack overflow but solution I used was from sending email without using defaut my token was being retrieved after the email was sent out. Anyway here is snippet of a working sample I created.
I imported the following jars:
compile files('libs/activation.jar')
compile files('libs/additionnal.jar')
compile files('libs/mail.jar')
I had the following permission requests
<uses-permission android:name="android.permission.GET_ACCOUNTS">
</uses-permission>
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"> </uses-permission>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Also for my scenario I asked the user for their user account. If you know it then you can skip this step. the snippet I have for this can be done another way using helper methods provided by studio libs however I just did it via a dialog.
public Account[] getGoogleAccounts(){
return accounts = acctManager.getAccountsByType("com.google"); }
public void getGoogleAccountsDialog(){
if( getGoogleAccounts().length>1) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("Select Google Account:")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.setItems(convertAccountTo(getGoogleAccounts()), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setSelectedAcct(accounts[which]);
initToken(activity);
dialog.dismiss();
}
});
builder.create();
builder.show();
}
else if(getGoogleAccounts().length==1){
setSelectedAcct(getGoogleAccounts()[0]);
}
else{
Toast.makeText(context,"No google account(s) exists on this device.",Toast.LENGTH_LONG);
}
}'
because this is a working sample i just have dummy text setup to fire the email immediately after the name is selected. However you will modify this code for you suiting.
Was the token is obtained I send the email request which is the getAndUseAuthTokenInAsynTask()
public void initToken(Activity ctx) {
acctManager.getAuthToken(getSelectedAcct(), "oauth2:https://mail.google.com/", null, activity, new AccountManagerCallback<Bundle>(){
#Override
public void run(AccountManagerFuture<Bundle> result){
try{
Bundle bundle = result.getResult();
token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
getAndUseAuthTokenInAsyncTask();
Log.d("initToken callback", "token="+token);
} catch (Exception e){
Log.d("test", e.getMessage());
}
}
}, null);
}
lastly the remainder of the calls
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);
}
}
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;
transport.connect(host, port, userEmail, emptyPassword);
byte[] response = String.format("user=%s\1auth=Bearer %s\1\1",
userEmail, token).getBytes();
response = BASE64EncoderStream.encode(response);
transport.issueCommand("AUTH XOAUTH2 " + new String(response), 235);
return transport;
}
Hope this helps someone else. Keep in mind that the sending of the mail should not be done on the main thread.
Not sure if useful to you, but have you considered also using the built-in email functionality? This wouldn't even require the user to enter their user id nor password, but of course they'll leave your app to the email client to send the email.
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
String[] recipients = new String[]{"recipient#email.com", "",};
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, recipients);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Sample mail");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "This is a sample mail..");
emailIntent.setType("text/plain");
startActivity(Intent.createChooser(emailIntent, "Send mail client :"));
(Btw: This would show many other apps along the email clients. If you're interested in such a solution, I can post some code to filter out all apps but email clients)
I want to create app on android and make it config E-mail setting on android device programmatically when it get setting data from server.
I have search around for android code example but I can't find any good example and I don't know where to start looking.
Can any one suggest where should I start looking?
Thank you
Update Sorry for an unclear question.
I used this method to send email programmatically . you can use this. it will help you.
//send email
boolean sendMail(String from,String to)
{
boolean isSend=false;
Properties props = System.getProperties();
String host = "smtp.gmail.com";
props.put("mail.smtp.starttls.enable", "true"); //enable for gmail
props.put("mail.smtp.user", "abc#gmail.com");
props.put("mail.smtp.password", "abc");
props.put("mail.smtp.port", "587"); //gmail port address
props.put("mail.smtp.auth", "true");
Log.d("tag","props set");
Session session = Session.getDefaultInstance(props,null);
Log.d("tag","session set");
MimeMessage message = new MimeMessage(session);
Log.d("tag","message set");
try {
message.setFrom(new InternetAddress(from));
InternetAddress add = new InternetAddress(to);
message.addRecipient(Message.RecipientType.TO, add);
message.setSubject("hello");
message.setText("hello world");
Transport transport = session.getTransport("smtp");
transport.connect(host,from, "hello world");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
isSend=true;
}
catch (AddressException ae) {
ae.printStackTrace();
isSend=false;
}
catch (MessagingException me) {
me.printStackTrace();
isSend=false;
}
return isSend;
}
Hello Friends i wan to make editable false in all edittext when i send mail by my application
programmatically
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto","test#mymail.com, null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "My Subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, Message);
startActivity(Intent.createChooser(emailIntent, "Send email..."));
finish();
friends my question is i want Text Subject Feild and Text/Body feild Read Only user can not edited it's value so how can i make it any idae?
your passing a intent to android device to handle mailing function specifying to handle it once intent is passed it will be handle by gmail or any other email client installed in your phone once they handle and get your data that is subject and message your application will be in paused state i mean to say you don't have control over other applications that handles your data.
create your mail handling and sending mail instead of passing it as intent
set editable false works only when you have those edit fields inside your application not in other activities that are started by your intent
You can create you own email sending activity without passing intent to any native email client app.There you can easily disable the editText for message and subject. The code for sending email is:
public class SendMail{
public static void main(String[] args) {
final String username = "username#gmail.com";
final String password = "password";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("from-email#gmail.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("to-email#gmail.com"));
message.setSubject("Testing Subject");
message.setText("Dear Mail Crawler,"
+ "\n\n No spam to my email, please!");
Transport.send(message);
System.out.println("Done");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
taken from here
Basically if you choose email chooser of android to send an email you lost all the control over this intent. So overriding these behaviour is very hard and might be not possible. So overcoming on this issue you can follow this link Sending Email in Android using JavaMail API without using the default/built-in app.
You can find how to use the javamail Api as in the above link.
Now you can make your own layout for mail activity. And you can use
youreditetxtWhichyouwanttodisable.setEditable(false);
This might be useful.
I used javamail api in my android project and parse String in "mail subject" and "mail content". In my gmail there are many mail boxes such as travel, job, photo.... I need go through all mail boxes and search mails in my conditions. But I found when call getData() it will login gmail and make connection again.
My question are
1.How can it Keep connection in android?
2.How can I search all the mail boxes in the same time?
Thanks for help.
private String downloadUrl () throws IOException {
receiveMail("username", "password");
return null;
}
receiveMail part
private static List<Message> receiveMail(String username, String Password) {
try {
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", IMAPS_PROTOCOL);
Session session = Session.getDefaultInstance(props, null );
session.setDebug(false);
final Store store = session.getStore(IMAPS_PROTOCOL);
store.connect(IMAPS_MAIL_HOTS , username, Password);
getData(store, "travel");
getData(store, "job");
getData(store, "photo");
} catch(Exception ex) {
ex.printStackTrace();
}
return null;
}
If you want to reuse a single connection for each folder, you need to be sure to close the folder before opening the next folder.
I successfully done validation of mail address but I want some suggestions for verifying an email address. The main point is when user enter an email id it should b checked that it is real or just a fake id.
Any suggestion?
No, this facility is not available. You can verify only when you have your own mail server the you are authorized to check the mail id is valid or not. Or when you own other server then you are permitted to get the mirror image of all others mail server only then you can verify, So if you are just a user of mail id then you can verify that the mail id is valid or not.
You can only verify the correct format of mail id by pattern checking.
Have fun
You can only check whether entered E-mail id is validate or not using regular expression, its not possible to check whether id is exists or not? as per my knowledge.
check out this link its already well answered
public static void main(String[] args) throws Exception {
String email = null;
String dns = null;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter email address to validate: ");
email = reader.readLine();
System.out.print("Enter DNS hostname to perform domain validation (e.g. ns.myhost.com): ");
dns = reader.readLine();
// create EmailInspector instance
EmailInspector inspector = new EmailInspector();
// enable debugging
inspector.setDebug(true);
// set DNS server
inspector.setNameserver(dns);
// set validation level
inspector.setEmailInspectionLevel(inspector.DOMAIN_VALIDATION);
// validate email
inspector.validate(email);
}
}
. Create new EmailInspector instance.
. Enable debugging.
. Set DNS server to be used for looking up domains.
. Set validation level.
. Validate email address.
Properties props = System.getProperties();
props.put("mail.smtp.user", senderEmail);
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "465");
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", "465");
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
// Required to avoid security exception.
email.MyAuthenticator authentication =
new email.MyAuthenticator(senderEmail,senderMailPassword);
Session session =
Session.getDefaultInstance(props,authentication);
session.setDebug(true);