Wednesday, June 19, 2013

How to send email using JAVA Mail and default App from android application

In this article we will learn how to send email in Android app. There are number of possibilities to send email using android app. To list some,

1. SMTP
While using SMTP you need to provide the address of the SMTP server, the username and password for that server, either statically in your code, or query it from the user.
For example:
SMTP Server: GMAIL Server
username: rushabh138@gmail.com
password: rushabh

2. HTTP 
Another way would involve a simple server side scripting, like php, that takes some URL parameters and uses them to send a mail. This way, you only need to make an HTTP request from the device and don't need to store the SMTP login data on the device.
For this you can refer or search for formmail.php and you'll be able to find number of post which you can use. (I am not going to use or explain HTTP concept in this article).

3. Mail Application
Send Mail using user default mail account that he already register with the phone.

Minimum Requirement 
1. Eclipse IDE + ADT plugin
2. Android SDK

You can download complete package from http://developer.android.com/sdk/index.html

Using SMTP Method

Task to complete 


  • Create an android application with UI that contains two edittext and one button.
  • When user enter email address and username in Edittext and click on Button; email is send to particular mail-ID specify in edittext. 

Steps

1. Open Eclipse -> Click on New -> Click on Android Application Project.
2. Enter Application Name : SendMail, Project Name: SendMail and Package Name: com.sendmail.SendMail. Leave Minimum Required SDK, Targer SDK, Compile With and Theme as default.


3. Under your project name you will see list of folder. Expand res folder and then expand layout folder. Double click on activity_main.xml file to open it.
4. In activity_main.xml create two edittext and one button with text property set to "Send".

    <EditText
        android:id="@+id/emailidtext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"    
        />

 <EditText
        android:id="@+id/usernametext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"    
        />

<Button
        android:id="@+id/sendbutton"
        android:layout_width="102dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"      
        android:text="Send"
        android:textAlignment="center"
        android:textSize="20sp" />

The JAVAMail API provides a platform-independent and protocol-independent framework to build mail and messaging applications. Also, Android make use of java classes and interfaces so it quite possible to add previously written java class or interface in android for some task.

Now we'll import JAVA Mail API into our project. Required files are.
1. mail.jar
2. activation.jar
3. additionnal.jar

In order to add JARS file into your project download all three file and copy them into lib folder. Once files are copied write click on each file and select Build Path as Add to Build Path. Refresh your project and you will find all three files under Reference Libraries. This means you have successfully added all three jars file into your project.

In our application we are going to use following things from JAVAMail API:


  • Message class: It allow to device message into multipart so that long message can be sent easily. 
  • Session: It helps to create session between host to send mail.
  • Internet Address: Mail ID i.e. rushabh138@gmail.com 

Next step is to create Send Mail class and will instantiate class on button clicking event.

To add a new class file, right click on src folder of your project and click New and select Class file and name it SendMail.

SendMail.java

package ;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import android.util.Log;

public class SendMail {

private String user;
private String email;

public SendMail(String userName, String emailAddress) {
this.user = userName;
this.email = emailAddress;
}
public void GMailSender(){

try{

Log.d("Check","Check Properties 1");

//Get system properties
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");  
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");

Log.d("Check", "Check Properties 2");

//Get the default session object
Log.d("Check","Check session 1");
Session session = Session.getDefaultInstance(props,new javax.mail.Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication("rushabh138@gmail.com", "rushabh");
}
});

Log.d("Check","Check seesion 2");

//Create message
Log.d("Check","Message 1");
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("rushabh138@gmail.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
message.setSubject("Password Reset");
message.setContent("Hello","text/html; charset=utf-8");

Log.d("Check","Message 2");

Log.d("Check","Transport 1");
Transport.send(message);

Log.d("Check","Transport 2");

}
catch(MessagingException e){
throw new RuntimeException(e);
}
}
//get username
public String getUser() {
return user;
}

//set username
public void setUser(String user) {
this.user = user;
}
//get email address
public String getEmail() {
return email;
}
//set email address
public void setEmail(String email) {
this.email = email;
}
}

Once SendMail.java file has been created open activity_mail.java file, create button onClicklistener and pass email address to SendMail class.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reset_password);

Button button1  = (Button)findViewById(R.id.sendbutton);
this.button1 .setOnClickListener(this);
}

In order to implement onClicklistener create public method onClick and pass Button ID into that. It always good practice to create a public onClick method and using switch case into it. By this, you are eliminating network related error.

@Override
public void onClick(View v){
switch(v.getId()){

case R.id.sendbutton:
try{
Log.d(ResetPassword,"Reset Button Click");

EditText emailaddress = (EditText)findViewById(R.id.emailidtext);
EmailAddress = emailaddress.getText().toString();
EditText username = (EditText)findViewById(R.id.usernametext);
UserName = username.getText().toString();

We need to check whether user had enter valid email address or username field is not left blank. In order to do that we'll create a public method to validate email address.

if((isEmailValid(EmailAddress)==true)&&(UserName.length() > 0)){
final SendMail mail = new SendMail(UserName,EmailAddress);

new AsyncTask<Void, Void, Void>(){
@Override
   protected void onPreExecute()
   {
       Log.d("Check", "onPreExecute()");
   }

   @Override
   protected Void doInBackground(Void... params)
   {
       Log.d("Check", "doInBackground() -- Here is the download");        
       mail.GMailSender();
       return null;
   }

   @Override
   protected void onPostExecute(Void res)
   {
       Log.d("Check", "onPostExecute()");
   }
}.execute();  
Context context = getApplicationContext();
 CharSequence text = finalString;
 int duration = Toast.LENGTH_LONG;

  toast = Toast.makeText(context, text, duration);
  toast.setGravity(Gravity.CENTER_HORIZONTAL, 5, 10);
  toast.show();
}
else{
Context context = getApplicationContext();
CharSequence text = "Enter valid username and email address.";
int duration = Toast.LENGTH_LONG;

toast = Toast.makeText(context, text, duration);
toast.setGravity(Gravity.CENTER_HORIZONTAL, 5, 10);
toast.show();
} 
}
catch(Exception e){
Log.d(ResetPassword,"Within Catch Block");
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
   } 
  }
}

//method to check if user enter valid email address or not
public static boolean isEmailValid(String email){
Log.d(ResetPassword,"Within Email Validation");
boolean isValid = false;

String expression = "^[\\w\\.-]+@([\\w\\-]+\\.)+[A-Z]{2,4}$";
CharSequence inputStr = email;

Pattern pattern = Pattern.compile(expression,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);

if(matcher.matches()){
isValid = true;
}
return isValid;

}

Note: If you don't use AsyncTask<> () you probably will end up getting error message like NetworkOnMainThread. I do have that error and after spending many hours while researching I found this answer which is working for me.

You need to add this line into manifest file:

<uses-permission android:name="android.permission.INTERNET" />

Using Mail Application Method

Follow the steps as explain in method 1 to create new project and add one edittext and one buttons (explain in method 1). Once UI is ready go to src file and open activity_mail.java file under your project and add this code.

EditText emailaddress = (EditText)findViewById(R.id.emailidtext);
EmailAddress = emailaddress.getText().toString();
EditText username = (EditText)findViewById(R.id.usernametext);
UserName = username.getText().toString();

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL  , new String[]{EmailAddress });
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();
}

Useful Link to Use Kindle as emulator 
Link 1
Link 2



3 comments:

  1. hello, thank you for tutorial but I've problem in this step error:
    https://myaccount.dropsend.com/inbox/download?file_ids[]=17540057

    I hope in your help.

    ReplyDelete
  2. this is the right link:
    https://myaccount.dropsend.com/file/cba8db27dc06b8dc

    ReplyDelete