0

I need to fix my code, it is not sending after adding attachment code

Email.java

package com.leenah.app;  
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.CommandMap;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.MailcapCommandMap;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 * Created by Leenah 21/03/2017.
 */

public class Email extends javax.mail.Authenticator {
    private String _user;
    private String _pass;

    private List<String> _to;
    private String _from;

    private String _port;
    private String _sport;

    private String _host;

    private String _subject;
    private String _body;

    private boolean _auth;

    private boolean _debuggable;

    private Multipart _multipart;


    public Email() {
        _host = "smtp.gmail.com"; // default smtp server
        _port = "465"; // default smtp port
        _sport = "465"; // default socketfactory port

        _user = ""; // username
        _pass = ""; // password
        _from = ""; // email sent from
        _subject = ""; // email subject
        _body = ""; // email body

        _debuggable = false; // debug mode on or off - default off
        _auth = true; // smtp authentication - default on

        _multipart = new MimeMultipart();

        // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added.
        MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
        mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
        mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
        mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
        mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
        mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
        CommandMap.setDefaultCommandMap(mc);
    }

    public Email(String user, String pass) {
        this();

        _user = user;
        _pass = pass;
    }

    public boolean send() throws Exception {
        Properties props = _setProperties();

        if(!_user.equals("") && !_pass.equals("") && _to.size() > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) {
            Session session = Session.getInstance(props, this);

            MimeMessage msg = new MimeMessage(session);

            msg.setFrom(new InternetAddress(_from));

            InternetAddress[] addressTo = new InternetAddress[_to.size()];
            for (int i = 0; i < _to.size(); i++) {
                addressTo[i] = new InternetAddress(_to.get(i));
            }
            msg.setRecipients(MimeMessage.RecipientType.TO, addressTo);

            msg.setSubject(_subject);
            msg.setSentDate(new Date());

            // setup message body
            BodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setText(_body);
            _multipart.addBodyPart(messageBodyPart);

            // Put parts in message
            msg.setContent(_multipart);

            // send email
            Transport.send(msg);

            return true;
        } else {
            return false;
        }
    }
    BodyPart messageBodyPart = new MimeBodyPart();

    public void addAttachment(String filename) throws Exception {
        DataSource source = new FileDataSource(filename);
        messageBodyPart.setDataHandler(new DataHandler(source));
        messageBodyPart.setFileName(filename);

        _multipart.addBodyPart(messageBodyPart);


    }

    @Override
    public PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(_user, _pass);
    }

    private Properties _setProperties() {
        Properties props = new Properties();

        props.put("mail.smtp.host", _host);

        if(_debuggable) {
            props.put("mail.debug", "true");
        }

        if(_auth) {
            props.put("mail.smtp.auth", "true");
        }

        props.put("mail.smtp.port", _port);
        props.put("mail.smtp.socketFactory.port", _sport);
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");

        return props;
    }

    // the getters and setters
    public String getBody() {
        return _body;
    }
    public void setBody(String body) {
        this._body = body;
    }

    public List<String> getTo(){
        return _to;
    }
    public void setTo(List<String> toArr) {
        this._to = toArr;
    }

    public String getFrom(){
        return _from;
    }
    public void setFrom(String from){
        this._from = from;
    }

public String getSubject(){
    return _subject;
}
public void setSubject(String string) {
    this._subject = string;
}

}

ProcessEmail.java

   package com.leenah.app;
     private ProgressDialog statusDialog;
    private Activity sendMailActivity;

    public ProcessEmail(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....");
            Email sendMail = new Email(args[0].toString(), args[1].toString());

            publishProgress("Preparing mail message....");
            sendMail.setFrom(args[0].toString());
            sendMail.setTo((List<String>) args[2]);
            sendMail.setSubject(args[3].toString());
            sendMail.setBody(args[4].toString());
            sendMail.addAttachment(args[5].toString());

            publishProgress("Sending email....");
            sendMail.send();

            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();
    }

}

This main activity for sending mail with attachment MainActivity.java

    package com.leenah.app;

    import android.content.Intent;
    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.ImageButton;
    import android.widget.TextView;
    import android.widget.Toast;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;

    public class MainActivity extends AppCompatActivity {

        String FilePath;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        Button addImage = (Button) findViewById(R.id.send_email);
        addImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String fromEmail = "*******@gmail.com";
                String fromPassword = "*******";
                List<String> toEmails = new ArrayList();
                toEmails.add("*******@hotmail.com");
                toEmails.add("*******@hotmail.com");
                String emailSubject = "This is an email sent using my Mail JavaMail wrapper from an Android device.";
                String emailBody= "Email body.";




                new ProcessEmail(Send.this).execute(
                        fromEmail, fromPassword, toEmails, emailSubject, emailBody, FilePath);
            }
        });

        Button selectFile= (Button) findViewById(R.id.selectFile);
        selectFile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("*/*");
                startActivityForResult(intent, FILE_SELECT_CODE);
            }
        });
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if ((requestCode == FILE_SELECT_CODE) && (resultCode == RESULT_OK)) {
            Uri uri = data.getData();
            FilePath = getRealPathFromURI(uri);
            Toast.makeText(this,FilePath+ "", Toast.LENGTH_SHORT).show();

        }

    }


    private String getRealPathFromURI(Uri uri){
        String filePath="";
        String[] filePahColumn = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(uri, filePahColumn, null, null, null);
        if (cursor != null) {
            if(cursor.moveToFirst()){
                int columnIndex = cursor.getColumnIndex(filePahColumn[0]);
                filePath = cursor.getString(columnIndex);
                Toast.makeText(this,columnIndex+"....."+ "", Toast.LENGTH_SHORT).show();
            }
            cursor.close();
        }

        return filePath;
    }

}

When I click send button: I got the following error:

E/SendMailTask: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
                                                                  java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a
 null object reference
 at com.philosophy.great.ProcessEmail.doInBackground(ProcessEmail.java:43)
 at android.os.AsyncTask$2.call(AsyncTask.java:292)
 at java.util.concurrent.FutureTask.run(FutureTask.java:237)
 at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
 at java.lang.Thread.run(Thread.java:818)
03-21 13:41:10.032 968-968/? E/fast-dormancy: [FDM]:  rrc_state=0
03-21 13:41:10.065 968-968/? E/fast-dormancy: [FDM]:  rrc_state=0

UPDATE #2

This code for pick files insted of images only, But the getRealPathFromURI return null

///////////////////////////////////the new code for file attachment//////////////////////////////////
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if ((requestCode == FILE_SELECT_CODE) && (resultCode == RESULT_OK)) {
            Uri uri = data.getData();
            FilePath = getRealPathFromURI(uri);

            Toast.makeText(this, FilePath + "", Toast.LENGTH_SHORT).show();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }


    private String getRealPathFromURI(Uri uri) {
        String filePath = "";
        String[] filePahColumn = {MediaStore.Files.FileColumns.DATA};
        Cursor cursor = getContentResolver().query(uri, filePahColumn, null, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndex(filePahColumn[0]);
                filePath = cursor.getString(columnIndex);
                Toast.makeText(this, columnIndex + "....." + "", Toast.LENGTH_SHORT).show();
            }
            cursor.close();
        }

        return filePath;

    }

    public void attach(View view) {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.setType("*/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent,FILE_SELECT_CODE);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////
Leenah
  • 850
  • 3
  • 15
  • 36

1 Answers1

0

The directory you are trying to access might not exist yet. According to API, the code ensures the directory exists using mkdirs()

File path = Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");

try {
    // Make sure the Pictures directory exists.
    path.mkdirs();
...

Hope it helps.

EDIT

Meanwhile make sure that,

  1. Your filename is correct
  2. You are not writing to the root folder
  3. Your path is correct
  4. You have give the appropriate permissions

EDIT # 2

You are getting the FilePath in a wrong way. Change your onActivityResult with below one

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if ((requestCode == FILE_SELECT_CODE) && (resultCode == RESULT_OK)) {
        Uri uri = data.getData();
        FilePath = getRealPathFromURI(uri);
    }

}


private String getRealPathFromURI(Uri uri){
    String filePath = "";
    String[] filePahColumn = {MediaStore.Images.Media.DATA};
    Cursor cursor = getContentResolver().query(uri, filePahColumn, null, null, null);
    if (cursor != null) {
        if(cursor.moveToFirst()){
            int columnIndex = cursor.getColumnIndex(filePahColumn[0]);
            filePath = cursor.getString(columnIndex);
        }
        cursor.close();
    }
    return filePath;
}

Now use this FilePath.

EDIT 3

Change your intent call to this.

Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Leenah
  • 850
  • 3
  • 15
  • 36
Waqas Ahmed Ansari
  • 1,683
  • 15
  • 30
  • Thank you for your answer , but where I will replace this code please? – Leenah Mar 21 '17 at 06:03
  • You are selecting file from gallery only? – Waqas Ahmed Ansari Mar 21 '17 at 06:07
  • Yes I would like to select the file from gallery only – Leenah Mar 21 '17 at 06:10
  • Thank you for your answer and trying helping me But still not working after add the new code this error Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference at com.leenah.app.ProcessEmail.doInBackground(ProcessEmail.java:43) – Leenah Mar 21 '17 at 06:25
  • Post your complete log in your question – Waqas Ahmed Ansari Mar 21 '17 at 06:44
  • Debug and check which of your argument is null. – Waqas Ahmed Ansari Mar 21 '17 at 07:44
  • **This is the null line** sendMail.addAttachment(args[5].toString()); – Leenah Mar 21 '17 at 07:47
  • could you please try the code, I really need to fix it and I'm appreciate your continuous help – Leenah Mar 21 '17 at 08:40
  • You can debug `onActivityResult` and `getRealPathFromUri` to see where the problem is. – Waqas Ahmed Ansari Mar 21 '17 at 09:07
  • FilePath in onActivityResult returns null – Leenah Mar 21 '17 at 09:11
  • Dear, debug every piece of code. Check if `data.getData()` is null, or something in a function `getRealPathFromUri`. Test every line till you find what is actually null. – Waqas Ahmed Ansari Mar 21 '17 at 09:17
  • Sorry for disturbs you, but I really did not know how to fix the problem with 'getRealPathFromURI' because the uri is not null but the 'FilePath = getRealPathFromURI(uri)' equals null – Leenah Mar 21 '17 at 09:25
  • Then check inside `getRealPathFromUri` – Waqas Ahmed Ansari Mar 21 '17 at 09:37
  • See the new update. Change your intent call like above – Waqas Ahmed Ansari Mar 21 '17 at 09:57
  • unfortunately, select file button not working at all with the new intent also I couldn't get the null in "getRealPathFromURI" – Leenah Mar 21 '17 at 10:08
  • `filePath = cursor.getString(columnIndex);` also null and the value of `columnIndex` is 0 So what should I do now please? – Leenah Mar 21 '17 at 10:39
  • Try something to open gallery using the `Intent` I provided – Waqas Ahmed Ansari Mar 21 '17 at 10:51
  • Thank you for your continues support, Intent code in EDIT # 2 above works fine for choose file but the problem with `getRealPathFromUri` method I post the updated code and I hope you have a look on it – Leenah Mar 21 '17 at 15:56
  • 1
    Change your intent line to `Intent intent new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)` – Waqas Ahmed Ansari Mar 22 '17 at 07:22
  • Thank you so much it's working, I really appreciate your efforts! The last question please: How can I open pdf file or doc? I tried something like `Intent intent = new Intent(Intent.ACTION_GET_CONTENT, Uri.parse(MediaStore.Files.FileColumns.DATA)); intent.setType("application/pdf"); startActivityForResult(intent, FILE_SELECT_CODE);` but it is not working and uri still null – Leenah Mar 22 '17 at 16:22
  • You can refer to [this](https://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT) – Waqas Ahmed Ansari Mar 23 '17 at 10:21
  • Thank you so much for your efforts! – Leenah Mar 23 '17 at 10:45
  • Could you please help me with pick file instead of images only, what I have to change in order to pick file and get uri. I tried many ways but it never work. Please get a look at the last part of the question include the updated code. – Leenah Mar 27 '17 at 12:58