I've been working on feedback form. It consists of name,email and feedback EditTexts.
I'm making the android application for the user to send the feedback using JavaMail API. Now My android is working fine as the user inputs the details in the fore mentioned space and sends the feedback to the mail which is given as Recipients address(i.e., My gmail account).
Problem : I have tried my level best to get the data(the mail id of the user)from the EditText input for email id of the user and to show it on the gmail account account as sent by USER_NAME but after numerous efforts it is giving me same data i.e., The mail is sent by me only no user id is shown
I'm providing you the screen shot of my mail account
My gmail inbox where I received the mail from the user
As you can see there are two mails right now, the one which is unread it doesn't show the email id of the user rather shows me because the mail comes from the username provided in the recipient's address
I've done researches on it:
Used setFrom(new InternetAddress(email)) here email is the edittext input of the email by the sender.
went to many searches but none of the ideas are working here (couldn't provide the links as I don't have much reputations to post more than two links. I've two photos which is also in a link form as stackoverflow is not allowing me to uplaod it directly.)
Did this also setFrom(new InternetAddress("Sender"+"<"+email+">")) result is showing Sender
What I ended up doing is : setFrom(new InternetAddress(Config.EMAIL,email));
and got succeeded somehow in showing the email in the email address in the section. The picture will give you better idea
Mail when opened
but still result is same the inbox is repeatedly showing me the sender's email as mine.
Here's mycode:
1. SendMail.java
public class SendMail extends AsyncTask<Void,Void,Void> {
//Declaring Variables
private Context context;
private Session session;
//Information to send email
private String name;
private String email;
private String subject;
private String feedback;
private ProgressDialog progressDialog;
public SendMail(Context context,String name, String email,String subject, String feedback) {
this.context = context;
this.name = name;
this.email = email;
this.subject = subject;
this.feedback = feedback;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//Showing progress dialog while sending email
progressDialog = ProgressDialog.show(context,"Sending feedback","Please wait...",false,false);
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//Dismissing the progress dialog
progressDialog.dismiss();
//Showing a success message
Toast.makeText(context,"Feedback Sent", Toast.LENGTH_LONG).show();
}
#Override
protected Void doInBackground(Void... voids) {
//creating properties
Properties properties = new Properties();
//Configuring properties for gmail
//If you are not using gmail you may need to change the values
properties.put("mail.smtp.host", "smtp.gmail.com");
properties.put("mail.smtp.socketFactory.port", "465");
properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.port", "465");
//creating new session
session = Session.getDefaultInstance(properties, new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(Config.EMAIL, Config.PASSWORD);
}
});
InternetAddress fromAddress = null;
try {
fromAddress = new InternetAddress(Config.EMAIL,email);
}catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
//Creating MimeMessage object
MimeMessage mimeMessage = new MimeMessage(session);
//Setting sender address
mimeMessage.setFrom(fromAddress);
//Adding receiver
mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(Config.EMAIL));
//Adding subject
mimeMessage.setSubject(subject);
//Adding Message
mimeMessage.setText("Name:"+ " "+ name + "\n" + "Email:" + " " + email + "\n" +
"Feedback" + " " + feedback);
//Sending email
Transport.send(mimeMessage);
} catch (MessagingException e) {
Log.e("SendMail", e.getMessage(), e);
}
return null;
}
}
2.Config.java
public class Config {
public static final String EMAIL = "recipient_email#gmail.com";
public static final String PASSWORD ="password";
}
3. Feedback.java
private void sendEmail() {
//getting content from email
String subject = string.toString();
String email = inputEmail.getText().toString().trim();
String name = inputName.getText().toString().trim();
String feedback = inputFeedback.getText().toString().trim();
//Creating SendMail object
SendMail sendMail = new SendMail(getContext(),name,email,subject,feedback);
//Executing sendmail to send email
sendMail.execute();
}
Please suggest me some way so that I can reach up to my destination. Thanking you in advance.
If your application is using your credentials to login to Gmail, Gmail is not going to let you "fake" the From address to be some other user.
Also, you really don't want to embed your Gmail password in the application.
A much better approach is to create a web application that accepts the input for the feedback form and sends the email. The Android application can post the form data to the web application, which will compose the message and send it, adding the user's email address as another header field or as data in the body of the message. That makes sure your Gmail password is safe on your server, not in the application that users can access.
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 am trying to integrate Facebook API for login functionality in android. I need email Id for respective user. I am getting JSON in response but It has no email Id.How can I achieve to get the email Id.
public void getProfileInformation() {
mAsyncRunner.request("me", new RequestListener() {
#Override
public void onComplete(String response, Object state) {
Log.d("Profile", response);
String json = response;
try {
// Facebook Profile JSON data
JSONObject profile = new JSONObject(json);
// getting name of the user
final String name = profile.getString("name");
// getting email of the user
final String email = profile.getString("email");
runOnUiThread(new Runnable() {
// Dayanand plzz check this log n let me know.
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Name: " + name + "\nEmail: " + email, Toast.LENGTH_LONG).show();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
Here is code, Where I am getting null in Toast. It goes to catch method.Please help
You have to ask for the permission : email from the user.
You need to ask for the email permission to the user, otherwise you can't get it.
Once the user grants you the permission, you'll see it when requesting for me.
See http://developers.facebook.com/docs/reference/login/email-permissions/
When you first time login at that time you are passing one permission array. so, you have to pass this array for email permission..
private String[] permissions = {"publish_stream","email","user_about_me","user_status"};
Hi I am trying to use the Parse Api's database for my project which requires user accounts that Parse provides. While I was reading the tutorial on how to set up user accounts at
https://parse.com/docs/android_guide#users it stated:
"Enabling email verification in an application's settings allows the application to reserve part of its experience for users with confirmed email addresses. Email verification adds the emailVerified key to the ParseUser object. When a ParseUser's email is set or modified, emailVerified is set to false. Parse then emails the user a link which will set emailVerified to true."
How exactly would you add the emailVerification key = true whenever a user tries to register:
ParseUser user = new ParseUser();
user.setUsername(username);
user.setPassword(password);
user.setEmail(email);
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
// sign up succeeded so go to multiplayer screen
// store the username of the current player
currentUser = username;
final String title = "Account Created Successfully!";
final String message = "Please verify your email before playing";
buildAlertDialog(title, message, true);
} else {
// sign up didnt succed. //TODO: figure out how do deal with error
final String title = "Error Account Creation failed";
final String message = "Account could not be created";
buildAlertDialog(title, message, false);
}
}
});
Go to your parse.com dashboard, go to settings, email settings and switch on the Verify user emails.
No code required.
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 have created my android code wherein I fetch all the data from facebook and then displays it in a textView and it works just fine on my account. But after I tried to connect with my dummy account, no details is fetched and I don't know the cause of this problem. Well here's my code to review:
private void getFbName() {
mProgress.setMessage("Finalizing ...");
mProgress.show();
new Thread() {
#Override
public void run() {
String name = "";
int what = 1;
try {
String me = mFacebook.request("me");
JSONObject jsonObj = (JSONObject) new JSONTokener(me).nextValue();
name = jsonObj.getString("first_name") + "|" + jsonObj.getString("last_name") + "|" + jsonObj.getString("email") + "|" + jsonObj.getString("id");
what = 0;
}
catch (Exception ex) {
ex.printStackTrace();
}
mFbHandler.sendMessage(mFbHandler.obtainMessage(what, name));
}
}.start();
}
private Handler mFbHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
mProgress.dismiss();
if (msg.what == 0) {
String username = (String) msg.obj;
username = (username.equals("")) ? "No Name" : username;
//SPLITTER
String tokens[] = username.split("\\|");
TextView fname = (TextView) findViewById(R.id.textView1);
fname.setText(tokens[0]);
TextView lname = (TextView) findViewById(R.id.textView2);
lname.setText(tokens[1]);
TextView eadd = (TextView) findViewById(R.id.textView3);
eadd.setText(tokens[2]);
TextView fbid = (TextView) findViewById(R.id.textView4);
fbid.setText(tokens[3]);
SessionStore.saveName(username, Main.this);
//mFacebookBtn.setText(" Facebook (" + username + ")");
Toast.makeText(Main.this, "Connected to Facebook as " + username, Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(Main.this, "Connected to Facebook", Toast.LENGTH_SHORT).show();
}
}
};
Well I only followed this tutorial for my code with some modification in the design wherein I use 1 button for login and another for logout and then displays the result in 4 textViews.
Edit
Here's my logout code:
private void fbLogout() {
mProgress.setMessage("Disconnecting from Facebook");
mProgress.show();
new Thread() {
#Override public void run() {
SessionStore.clear(Main.this);
int what = 1;
try {
mFacebook.logout(Main.this);
what = 0;
}
catch (Exception ex) {
ex.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage(what));
}
}.start();
}
When using the facebook android SDK, you two have two types of authentication:
Using the SDK auth dialog which will ask the user for his email/password.
Using Single Sign-On (SSO) which will only work if the device has the facebook application (katana) installed. If that's the case, that app will be responsible for the authentication which creates a better user experience since the user is already signed in and does not need to reenter his credentials.
If you are following the tutorial then you are using SSO (if the app is installed of course), and because of that when ever you are using the facebook.authorize method you are asking the fb app to authorize your app for the current logged in user.
If you want another user to use your app you'll need the user to log out of the main facebook app.
You can use the sdk authentication and bypass the SSO as suggested here: How to disable Facebook single sign on for android - Facebook-android-sdk, but as I said before, I think it results in a bad user experience.
Another thing is that you keep implementing things using threads, but the facebook android SDK already gives you a helper class for that, it's the AsyncFacebookRunner which makes api requests asynchronously, read Async API Requests.