Friday, February 24, 2017

Send mail in background, Send mail without intent


Send mail in background is a process to send mail by without open default mail composer. By this we can send number of mail in the background. Also if an application owner wants to send mail in the background without knowing to user, then this is also usefull in this case.




Steps to use Send mail in background in your project.
  1. Crate a project in android studio.
  2. Open manifest.xml and add a permission to it.

     
    <uses-permission android:name="android.permission.INTERNET" />
     
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.pankaj.mail_in_background">
    
        <!--permissions-->
        <uses-permission android:name="android.permission.INTERNET" />
    
        <!--application-->
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
    
            <!--activities-->
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

     
  3. Add three jar files(additionnal.jar, mail.jar, activation.jar) download and put in lib folder.
  4. Open build.gradle(app).
  5. Add a dependancy (<project>/<app-module>/build.gradle)-
    compile files('libs/additionnal.jar')
    compile files('libs/mail.jar')
    compile files('libs/activation.jar')

  6. Click on sync project .


    apply plugin: 'com.android.application'
    android {
    
        compileSdkVersion 25
        buildToolsVersion "25.0.0"
    
        defaultConfig {
            applicationId "com.pankaj.mail_in_background"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:25.0.0'
        testCompile 'junit:junit:4.12'
       
    
       //add dependencies here
    compile files('libs/additionnal.jar')
    compile files('libs/mail.jar')
    compile files('libs/activation.jar')
    }
      

  7. Open your main_activity.xml and update it-    
  8. Now create a class(GMailSender.java) and update it like below code, for authentication with your email account.
  9. package com.pankaj.mail_in_background;
    /**
    * Created by pankaj on 2/24/2017.
    */
    import javax.activation.DataHandler;
    import javax.activation.DataSource;
    import javax.mail.Message;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.security.Security;
    import java.util.Properties;
    public class GMailSender extends javax.mail.Authenticator {
      private String mailhost = "smtp.gmail.com";
      private String user;
      private String password;
      private Session session;
      static {
          Security.addProvider(new JSSEProvider());
      }
      public GMailSender(String user, String password) {
          this.user = user;
          this.password = password;
          Properties props = new Properties();
          props.setProperty("mail.transport.protocol", "smtp");
          props.setProperty("mail.host", mailhost);
          props.put("mail.smtp.auth", "true");
          props.put("mail.smtp.port", "465");
          props.put("mail.smtp.socketFactory.port", "465");
          props.put("mail.smtp.socketFactory.class",
                  "javax.net.ssl.SSLSocketFactory");
          props.put("mail.smtp.socketFactory.fallback", "false");
          props.setProperty("mail.smtp.quitwait", "false");
          session = Session.getDefaultInstance(props, this);
      }
      protected PasswordAuthentication getPasswordAuthentication() {
          return new PasswordAuthentication(user, password);
      }
      public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception {
          try{
              MimeMessage message = new MimeMessage(session);
              DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));
              message.setSender(new InternetAddress(sender));
              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));
              Transport.send(message);
          }catch(Exception e){
          }
      }
      public class ByteArrayDataSource implements DataSource {
          private byte[] data;
          private String type;
          public ByteArrayDataSource(byte[] data, String type) {
              super();
              this.data = data;
              this.type = type;
          }
          public ByteArrayDataSource(byte[] data) {
              super();
              this.data = data;
          }
          public void setType(String type) {
              this.type = type;
          }
          public String getContentType() {
              if (type == null)
                  return "application/octet-stream";
              else
                  return type;
          }
          public InputStream getInputStream() throws IOException {
              return new ByteArrayInputStream(data);
          }
          public String getName() {
              return "ByteArrayDataSource";
          }
          public OutputStream getOutputStream() throws IOException {
              throw new IOException("Not Supported");
          }
      }
    }
      
  10. Now create a class(
    JSSEProvider
    .java
    ) and update it like below code.
  11. package com.pankaj.mail_in_background;
    /**
    * Created by Pankaj on 2/24/2017.
    */
    import java.security.AccessController;
    import java.security.Provider;
    public final class JSSEProvider extends Provider {
      public JSSEProvider() {
          super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
          AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
              public Void run() {
                  put("SSLContext.TLS",
                          "org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
                  put("Alg.Alias.SSLContext.TLSv1", "TLS");
                  put("KeyManagerFactory.X509",
                          "org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
                  put("TrustManagerFactory.X509",
                          "org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
                  return null;
              }
          });
      }
    }
     
  12. Now create a class(
    LongOperatio
    .java) and update it like below code, for send mail in background.
  13. package com.pankaj.mail_in_background;
    import android.os.AsyncTask;
    import android.util.Log;
    /**
    * Created by GsolC on 2/24/2017.
    */
    public class LongOperation extends AsyncTask<Void, Void, String> {
      @Override
      protected String doInBackground(Void... params) {
          try {
              GMailSender sender = new GMailSender("gsolc.developers@gmail.com", "your@password");
              sender.sendMail("This is a testing mail",
                      "This is Body of testing mail","gsolc.developers@gmail.com",
                      "pankajgurjar90@gmail.com,gsolc.developers@gmail.com")                   ;
          } catch (Exception e) {
              Log.e("error", e.getMessage(), e);
              return "Email Not Sent";
          }
          return "Email Sent";
      }
      @Override
      protected void onPostExecute(String result) {
          Log.e("LongOperation",result+"");
      }
      @Override
      protected void onPreExecute() {
      }
      @Override
      protected void onProgressUpdate(Void... values) {
      }
    }
     
  14. Open your main_activity.xml and update it-
  15. <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/activity_main"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:gravity="center"
      tools:context="com.pankaj.mail_in_background.MainActivity">
      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:onClick="sendMail"
          android:text="send mail" />
     
    </RelativeLayout>
     
  16. Open your MainActivity.JAVA class and update it -

    package com.pankaj.mail_in_background;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    public class MainActivity extends AppCompatActivity {
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
      }
      public void sendMail(View view) {
          try
          {
              LongOperation l=new LongOperation();
              l.execute();  //sends the email in background
              Toast.makeText(this, l.get(), Toast.LENGTH_SHORT).show();
          } catch (Exception e) {
              Log.e("SendMail", e.getMessage(), e);
          }
      }
    }

  17. Now all the development steps for Send mail in Background has completed, Please run the application and see the screen of device.

  18. Now click on "SEND MAIL" and see the screen -

  19. Now check on the mail it should receive mail like-

  20. The detail of the sender and receiver will be like -
  21. Good bye, Thanks to read this blog.

7 comments:

  1. mail not send .....becz google blocked

    ReplyDelete
    Replies
    1. try this
      https://myaccount.google.com/lesssecureapps

      Delete
  2. Thanks for your great efforts.
    How to attach picture to the mail??

    ReplyDelete
  3. Thankyou man got a lill bit confusing at the begining but ok now
    Same as him can i add images in the mail or any pdf

    ReplyDelete
  4. It says email send but nothing received on email.

    ReplyDelete
  5. https://github.com/nlubello/BackgroundMailLibrary

    Above library is showing how to attach any file to mail.

    And also do not forget to allow less secure apps. To do this, please look at https://docs.mailshake.com/article/38-blocked-sign-in-attempt-and-less-secure-app-notification .

    ReplyDelete
  6. It says email send but nothing received on email.

    ReplyDelete