Java Mail API无法使用附件

时间:2017-03-21 04:56:22

标签: java android api email

我需要修复我的代码,在添加附件代码后它没有发送

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

}

这是发送附件邮件的主要活动 的 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;
    }

}

当我点击发送按钮时:我收到以下错误:

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

更新#2

这个代码仅用于提取图像,但getRealPathFromURI返回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);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////

1 个答案:

答案 0 :(得分:0)

您尝试访问的目录可能尚不存在。根据{{​​3}},代码使用mkdirs()

确保目录存在
File path = Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES);
File file = new File(path, "DemoPicture.jpg");

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

希望它有所帮助。

修改

同时确保,

  1. 您的文件名是否正确
  2. 您没有写入根文件夹
  3. 您的路径是正确的
  4. 您已授予适当的权限
  5. 编辑#2

    您以错误的方式获得FilePath。将您的onActivityResult更改为

    @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;
    }
    

    现在使用此FilePath

    编辑3

    将您的意图调用更改为此。

    Intent intent = new Intent(
                            Intent.ACTION_PICK,
                            MediaStore.Images.Media.EXTERNAL_CONTENT_URI);