天天看點

javamail 基于imap和smtp協定手機用戶端開發,郵件收件箱、發件箱、郵件詳情、轉發回複、附件下載下傳、郵件正文顯示表情等功能

    前一陣子,園區的APP要開發手機端的郵箱功能,NND,就這個功能開發了三個版本,我也是醉了,前兩個版本都是基于背景去開發給移動端提供接口的,but,背景不願意了,說是他們工作量太大做不了,WTF ?!,後來直接說讓我們移動端自己開發....,哎,自己開發就開發吧,之前沒接觸過,也是踩着無數坑過來的呀,希望對大家有所幫助吧,不盡完美,勉強能用,求大神指引方向。看圖:

javamail 基于imap和smtp協定手機用戶端開發,郵件收件箱、發件箱、郵件詳情、轉發回複、附件下載下傳、郵件正文顯示表情等功能
javamail 基于imap和smtp協定手機用戶端開發,郵件收件箱、發件箱、郵件詳情、轉發回複、附件下載下傳、郵件正文顯示表情等功能
javamail 基于imap和smtp協定手機用戶端開發,郵件收件箱、發件箱、郵件詳情、轉發回複、附件下載下傳、郵件正文顯示表情等功能
javamail 基于imap和smtp協定手機用戶端開發,郵件收件箱、發件箱、郵件詳情、轉發回複、附件下載下傳、郵件正文顯示表情等功能

1、收件箱與發件箱

 廢話不多說,直接上代碼

/**
 * Created by wz on 2018/10/16.
 * 發件箱
 * 實作上下拉重新整理
 */

public class IMAPEmailSentListModel extends BaseModel  {

    private int mPageSize = 10;//當有分頁加載資料時,每頁顯示的資料條數
    public ArrayList<EMAIL_LIST> records = new ArrayList<EMAIL_LIST>();
    public int total;

    public IMAPEmailSentListModel(Context context) {
        super(context);
    }

    /**
     * 清單
     */
    public void list(final String userName, final String password, final String host, final int port, Handler handler) {
        EmailThreadUtil.stop();
        EmailListUP up = new EmailListUP(userName, password, "Sent", host, port, 1, 10,handler,false);//線程
        EmailThreadUtil.execute(up);//線程池

    }

    /**
     * 更多
     */
    public void more(String userName, String password, String host, int port,Handler handler) {
        EmailThreadUtil.stop();
        int start = (total - records.size() - mPageSize + 1) < 1 ? 1 : (total - records.size() - mPageSize + 1);
        EmailListUP up = new EmailListUP(userName, password, "Sent", host, port, start, total - records.size(),handler,true);
        EmailThreadUtil.execute(up);

    }
}
           
/**
 * Created by wz on 2018/10/16.
 * 發件箱清單
 * 實作上下拉重新整理
 */

public class IMAPEmailGetListModel extends BaseModel  {

    private int mPageSize = 10;//當有分頁加載資料時,每頁顯示的資料條數
    public ArrayList<EMAIL_LIST> records = new ArrayList<EMAIL_LIST>();
    public int total  = 0 ;

    public IMAPEmailGetListModel(Context context) {
        super(context);
    }

    /**
     * 清單
     */
    public void list(final String userName, final String password, final String host, final int port, Handler handler) {
        EmailThreadUtil.stop();
        EmailListUP up = new EmailListUP(userName, password, "INBOX", host, port, 1, 10,handler,false);
        EmailThreadUtil.execute(up);

    }

    /**
     * 更多
     */
    public void more(String userName, String password, String host, int port,Handler handler) {
        EmailThreadUtil.stop();
        int start = (total - records.size() - mPageSize + 1) < 1 ? 1 :(total - records.size() - mPageSize + 1);
        EmailListUP up = new EmailListUP(userName, password, "INBOX", host, port, start, total - records.size(),handler,true);
        EmailThreadUtil.execute(up);

    }


}
           

上邊是我寫的發件箱清單和收件箱清單的model, 分别實作兩個清單的上拉和加載更多的接口部署。

/*
* 郵件清單entity
*/
public class EMAIL_LIST implements Serializable {
    public String emailUrl;

    public Long email_id;

    public String sender; // 發件人

    public String subject; // 主題

    public String date; // 日期

    public String href;

    public int allEmmailLenth;

    public int hasAttachment; // 是否有附件,0沒有,1有

    public boolean isRead; // 是否已讀

    public void fromJson(JSONObject jsonObject) throws JSONException {
        if( null == jsonObject ) {
            return ;
        }

        JSONArray subItemArray = new JSONArray();

        this.emailUrl = jsonObject.optString("emailUrl");
        this.sender = jsonObject.optString("sender");
        this.subject = jsonObject.optString("subject");
        this.date = jsonObject.optString("date");
        this.href = jsonObject.optString("href");
        this.hasAttachment = jsonObject.optInt("hasAttachment");
        this.isRead = jsonObject.optBoolean("isRead");
        return;
    }

    public JSONObject toJson() throws JSONException {
        JSONObject localItemObject = new JSONObject();
        JSONArray itemJSONArray = new JSONArray();
        localItemObject.put("emailUrl", emailUrl);
        localItemObject.put("sender", sender);
        localItemObject.put("subject", subject);
        localItemObject.put("date", date);
        localItemObject.put("href", href);
        localItemObject.put("hasAttachment", hasAttachment);
        localItemObject.put("isRead", isRead);
        return localItemObject;
    }
}
           
/**
 * Created by wz on 2018/10/16.
 * 線程池
 */
public class EmailThreadUtil {

    /**
     * 請求線程池隊列,同時允許1個線程操作
     */
    private static ThreadPoolExecutor mPool;

    public static Map<String, EmailListUP> downTask = new HashMap<String, EmailListUP>();

    //當線程池中的線程小于mCorePoolSize,直接建立新的線程加入線程池執行任務
    private static final int mCorePoolSize = 1;
    //最大線程數
    private static final int mMaximumPoolSize = 3;
    //線程執行完任務後,且隊列中沒有可以執行的任務,存活的時間,後面的參數是時間機關
    private static final long mKeepAliveTime = 5L;

    /**
     * 執行任務,當線程池處于關閉,将會重新建立新的線程池
     */
    private static ExecutorService executor;

    //參數說明
    //當線程池中的線程小于mCorePoolSize,直接建立新的線程加入線程池執行任務
    //當線程池中的線程數目等于mCorePoolSize,将會把任務放入任務隊列BlockingQueue中
    //當BlockingQueue中的任務放滿了,将會建立新的線程去執行,
    //但是當總線程數大于mMaximumPoolSize時,将會抛出異常,交給RejectedExecutionHandler處理
    //mKeepAliveTime是線程執行完任務後,且隊列中沒有可以執行的任務,存活的時間,後面的參數是時間機關
    //ThreadFactory是每次建立新的線程工廠
    public synchronized static void execute(Runnable run) {
        if (run == null) {
            return;
        }
        if (mPool == null || mPool.isShutdown()) {
            mPool = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, mKeepAliveTime,
                    TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
                    Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
        }
        mPool.execute(run);
        //     System.out.println("hashcode"+mPool.hashCode());
       /* if (executor == null || executor.isShutdown()) {
            executor = Executors.newFixedThreadPool(1);
        }
        executor.execute(run);*/
        downTask.put(String.valueOf(System.currentTimeMillis()),(EmailListUP) run);
    }

    /**
     * 取消線程池中某個還未執行的任務
     */
    public synchronized static boolean cancel(Runnable run) {
        if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
            return mPool.getQueue().remove(run);
        } else {
            return false;
        }
    }

    /**
     * 檢視線程池中是否還有某個還未執行的任務
     */
    public synchronized static boolean contains(Runnable run) {
        if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
            return mPool.getQueue().contains(run);
        } else {
            return false;
        }
    }

    /**
     * 立刻關閉線程池,并且正在執行的任務也将會被中斷
     */
    public static void stop() {
        if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
            mPool.shutdownNow();
        }
    }

    /**
     * 平緩關閉單任務線程池,但是會確定所有已經加入的任務都将會被執行完畢才關閉
     */
    public synchronized static void shutdown() {
        if (mPool != null && (!mPool.isShutdown() || mPool.isTerminating())) {
            mPool.shutdownNow();
        }
    }



}
           
/*
* Create By wz
* 收件箱、發件箱請求
*/

public class EmailListUP implements Runnable {

    private String userName;
    private String password;
    private String type;
    private String host;
    private int start;
    private int end;
    private int port;
    private ArrayList<EMAIL_LIST> list;
    private boolean isFirst = true;
    private Handler handler;
    private boolean isLoadMore;

    /**
     * @param userName 姓名
     * @param password 密碼
     * @param type     INBOX收件箱 Sent發件箱
     * @param start    開始位置
     * @param end      結束位置
     * @param isLoadMore     判斷是下來重新整理還是加載更多
     */
    public EmailListUP(String userName, String password, String type, String host, int port, int start, int end, Handler handler,boolean isLoadMore) {
        this.userName = userName;
        this.password = password;
        this.type = type;
        this.start = start;
        this.host = host;
        this.port = port;
        this.end = end;
        this.handler = handler;
        this.isLoadMore = isLoadMore;
    }

    public EmailListUP() {

    }

    @Override
    public void run() {

        getImapEmail();
    }

    /**
     * 以imap方式讀取郵件,可以判定讀取郵件是否為已讀
     */
    private void getImapEmail() {
        String user = this.userName;// 郵箱的使用者名
        String password = this.password; // 郵箱的密碼

        Properties prop = System.getProperties();
        prop.put("mail.store.protocol", "imap");
        prop.put("mail.imap.host", this.host);
        prop.put("mail.imap.port", this.port);

        Session session = Session.getDefaultInstance(prop);

        int total = 0;
        IMAPStore store;
        try {
            store = (IMAPStore) session.getStore("imap"); // 使用imap會話機制,連接配接伺服器
            store.connect(user, password);
            IMAPFolder folder = (IMAPFolder) store.getFolder(this.type);
            folder.open(Folder.READ_WRITE);
            // 擷取總郵件數
            total = folder.getMessages().length;
//            System.out.println("---共有郵件:" + total + " 封---");
            // 得到收件箱檔案夾資訊,擷取郵件清單
            list = new ArrayList<EMAIL_LIST>();
//            System.out.println("未讀郵件數:" + folder.getUnreadMessageCount());
            Message[] messages = null;
          
           //這裡提供了folder.getMessages(),folder.getMessages(start,end) 兩種方法
           //剛好可以實作分頁功能
           if(!isLoadMore) {//下拉重新整理
               if (total < 10) {
                   messages = folder.getMessages();
               } else {
                   messages = folder.getMessages(total - 10 < 1 ? 1 : (total - 10), total);
               }
           } else {//加載更多
               messages = folder.getMessages(start,end);
           }

            if (messages.length > 0) {
                Map<String, Object> map;
                System.out.println("Messages's length: " + messages.length);
                ReciveOneMail pmm = null;
                for (int i = 0; i < messages.length; i++) {
//                    System.out.println("======================");
                    pmm = new ReciveOneMail((MimeMessage) messages[i]);
//                    System.out.println("Message " + i + " subject: " + pmm.getSubject());
                    try {
//                        System.out.println("Message " + i + " sentdate: " + pmm.getSentDate());
//                        System.out.println("Message " + i + " replysign: " + pmm.getReplySign());
                        boolean isRead;// 用來判斷該郵件是否為已讀
                        String read;
                        Flags flags = messages[i].getFlags();

//                        System.out.println("Message " + i + " hasRead: " + isRead);
//                        System.out.println("Message " + i + "  containAttachment: " + pmm.isContainAttach((Part) messages[i]));
//                        System.out.println("Message " + i + " form: " + pmm.getFrom());
//                        System.out.println("Message " + i + " to: " + pmm.getMailAddress("to"));
//                        System.out.println("Message " + i + " cc: " + pmm.getMailAddress("cc"));
//                        System.out.println("Message " + i + " bcc: " + pmm.getMailAddress("bcc"));
                        pmm.setDateFormat("yy年MM月dd日 HH:mm");
//                        System.out.println("Message " + i + " sentdate: " + pmm.getSentDate());
//                        System.out.println("Message " + i + " Message-ID: " + pmm.getMessageId());
                        // 獲得郵件内容===============
//                        pmm.getMailContent((Part) messages[i]);
//                        System.out.println("Message " + i
//                                + " bodycontent: \r\n" + pmm.getBodyText());
//                        String file_path = File.separator + "mnt"
//                                + File.separator + "sdcard" + File.separator;
//                        System.out.println(file_path);
//                        pmm.setAttachPath(file_path);
//                        pmm.saveAttachMent((Part) messages[i]);


                        EMAIL_LIST email = new EMAIL_LIST();
                        email.hasAttachment = pmm.isContainAttach((Part) messages[i]) ? 1 : 0;
                        email.sender = pmm.getFrom();
                        email.subject = pmm.getSubject();
                        email.date = pmm.getSentDate();
                        email.email_id = folder.getUID(messages[i]);//郵箱ID,用來擷取單個郵件詳情的
                        email.allEmmailLenth = total;
                        if (flags.contains(Flags.Flag.SEEN)) {
                            email.isRead = true;
                        } else {
                            email.isRead = false;
                        }
                        list.add(email);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                 //我這裡 用的是handler給view層回報資訊的 ,大佬可以自行修改
                android.os.Message msgg = new android.os.Message();
                msgg.what = CustomMessageConstant.IMAP_LIST_REFRESH;
                if (type.equals("INBOX")) {//收件箱
                    msgg.arg1 = EmailIMAPListView.INBOX;
                } else if (type.equals("Sent")) {//發件箱
                    msgg.arg1 = EmailIMAPListView.OUTBOX;
                }
                if (!isLoadMore) {//下拉重新整理
                    msgg.arg2 = 0;
                } else { //上拉更多
                    msgg.arg2 = 1;
                }
                msgg.obj = list;
                handler.sendMessage(msgg);
            }
        } catch (javax.mail.NoSuchProviderException e) {
            e.printStackTrace();
        } catch (AuthenticationFailedException e) {
         //此異常是個坑,會崩潰,原因:郵箱賬戶密碼驗證不通過
            android.os.Message msgg = new android.os.Message();
            msgg.what = CustomMessageConstant.IMAP_NAME_INVLID;
            handler.sendMessage(msgg);
        } catch (MessagingException e) {
            e.printStackTrace();
        }

    }

}
           
//大佬們可以根據自己的上下拉控件,自行修改
Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            handleMsg(msg);
        }
    };
 private void handleMsg(Message msg){
         if (msg.what == CustomMessageConstant.IMAP_LIST_REFRESH) {
             if (msg.arg1 == INBOX) {//收件箱
                 mListView.stopRefresh();
                 mListView.stopLoadMore();
                if (msg.arg2 == 0) {//下拉
                    mGetModel.total = ((ArrayList<EMAIL_LIST>) msg.obj).get(0).allEmmailLenth;
                    mGetModel.records.clear();
                    mGetModel.records = (ArrayList<EMAIL_LIST>) msg.obj;
                } else if (msg.arg2 == 1) {//上拉
                    mGetModel.records.addAll((ArrayList<EMAIL_LIST>) msg.obj);
                }
                 if (mEmailAdapter == null) {
                     mEmailAdapter = new EmailIAMPAdapter(getContext(), mGetModel.records,INBOX);
                     mListView.setAdapter(mEmailAdapter);
                 } else {
                     mEmailAdapter.mData = mGetModel.records;
                     mEmailAdapter.sortAndNotifyDataSetChanged();
                 }
                 if (mGetModel.total <= mGetModel.records.size()) {
                     mListView.setPullLoadEnable(false);
                 } else {
                     mListView.setPullLoadEnable(true);
                 }

             } else if (msg.arg1 == OUTBOX) {//發件箱
                 mListView.stopRefresh();
                 mListView.stopLoadMore();
                if (msg.arg2 == 0) {//下拉
                    mSendModel.total = ((ArrayList<EMAIL_LIST>) msg.obj).get(0).allEmmailLenth;
                    mSendModel.records.clear();
                    mSendModel.records = (ArrayList<EMAIL_LIST>) msg.obj;
                } else if (msg.arg2 == 1) {//上拉
                    mSendModel.records.addAll((ArrayList<EMAIL_LIST>) msg.obj);
                }
                 if (mEmailAdapter == null) {
                     mEmailAdapter = new EmailIAMPAdapter(getContext(), mSendModel.records,OUTBOX);
                     mListView.setAdapter(mEmailAdapter);
                 } else {
                     mEmailAdapter.mData = mSendModel.records;
                     mEmailAdapter.sortAndNotifyDataSetChanged();
                 }
                 if (mSendModel.total <= mSendModel.records.size()) {
                     mListView.setPullLoadEnable(false);
                 } else {
                     mListView.setPullLoadEnable(true);
                 }
             }
         } else if (msg.what == CustomMessageConstant.IMAP_NAME_INVLID){
             ToastUtil.toastShow(getContext(),"郵箱賬号密碼錯誤");
         }
     }
           

2、郵件詳情與附件下載下傳

上邊擷取郵件清單的時候,擷取到的UID,這裡用到去擷取郵件詳情

EmailThreadUtil.stop();
EmailDetailUP  up = new EmailDetailUP(SESSION.getInstance().getEmail(), SESSION.getInstance().getOAPassword(), mEmailType, SESSION.getInstance().getEmailHost(), SESSION.getInstance().getEmailPost(),emailUID, handler);
        EmailThreadUtil.execute(up);
           
/**
*Create by wz
* 郵件詳情請求
*
*/

public class EmailDetailUP extends EmailListUP {

    private String userName;
    private String password;
    private String type;
    private String host;
    private int port;
    private ArrayList<EMAIL> list;
    private boolean isFirst = true;
    private Handler handler;
    private long uid;

    private ReciveOneMail pmm;

    /**
     * @param userName 姓名
     * @param password 密碼
     * @param type     INBOX收件箱 Sent發件箱
     */
    public EmailDetailUP(String userName, String password, String type, String host, int port,long uid,Handler handler) {
        this.userName = userName;
        this.password = password;
        this.type = type;
        this.host = host;
        this.port = port;
        this.uid = uid;
        this.handler = handler;
    }


    @Override
    public void run() {

        getImapEmail();
    }

    /**
     * 以imap方式讀取郵件,可以判定讀取郵件是否為已讀
     */
    private void getImapEmail() {
        String user = this.userName;// 郵箱的使用者名
        String password = this.password; // 郵箱的密碼

        Properties prop = System.getProperties();
        prop.put("mail.store.protocol", "imap");
        prop.put("mail.imap.host", this.host);
        prop.put("mail.imap.port", this.port);

        Session session = Session.getDefaultInstance(prop);

        int total = 0;
        IMAPStore store;
        try {
            store = (IMAPStore) session.getStore("imap"); // 使用imap會話機制,連接配接伺服器

            store.connect(user, password);

            IMAPFolder folder = (IMAPFolder) store.getFolder(this.type);
            folder.open(Folder.READ_WRITE);
            // 擷取總郵件數
            total = folder.getMessages().length;
//            System.out.println("---共有郵件:" + total + " 封---");
            // 得到收件箱檔案夾資訊,擷取郵件清單
            list = new ArrayList<EMAIL>();
//            System.out.println("未讀郵件數:" + folder.getUnreadMessageCount());
            Message[] messages = new Message[1];
            //messages = folder.getMessages(start, end);
     //其實跟擷取清單沒什麼不同,隻是用到的方法不同而已
            Message message = folder.getMessageByUID(uid);
            messages[0] = message;
            if (messages.length > 0) {
                Map<String, Object> map;
//                System.out.println("Messages's length: " + messages.length);

                for (int i = 0; i < messages.length; i++) {
//                    System.out.println("======================");
                    pmm = new ReciveOneMail((MimeMessage) messages[i]);
//                    System.out.println("Message " + i + " subject: " + pmm.getSubject());
                    try {
//                        System.out.println("Message " + i + " sentdate: " + pmm.getSentDate());
//                        System.out.println("Message " + i + " replysign: " + pmm.getReplySign());
                        boolean isRead;// 用來判斷該郵件是否為已讀
                        String read;
                        Flags flags = messages[i].getFlags();
                        if (flags.contains(Flags.Flag.SEEN)) {
//                            System.out.println("這是一封已讀郵件");
                            isRead = true;
                            read = "已讀";
                        } else {
//                            System.out.println("未讀郵件");
                            isRead = false;
                            read = "未讀";
                        }
                        //設定為已讀
                        messages[i].setFlag(Flags.Flag.SEEN, true);
//                        System.out.println("Message " + i + " hasRead: " + isRead);
                        System.out.println("Message " + i + "  containAttachment: " + pmm.isContainAttach((Part) messages[i]));
//                        System.out.println("Message " + i + " form: " + pmm.getFrom());
//                        System.out.println("Message " + i + " to: " + pmm.getMailAddress("to"));
//                        System.out.println("Message " + i + " cc: " + pmm.getMailAddress("cc"));
//                        System.out.println("Message " + i + " bcc: " + pmm.getMailAddress("bcc"));
                        pmm.setDateFormat("yy年MM月dd日 HH:mm");
//                        System.out.println("Message " + i + " sentdate: " + pmm.getSentDate());
//                        System.out.println("Message " + i + " Message-ID: " + pmm.getMessageId());
                        // 獲得郵件内容===============
                        pmm.getMailContent((Part) messages[i]);
//                        System.out.println("Message " + i
//                                + " bodycontent: \r\n" + pmm.getBodyText());
//                        String file_path = File.separator + "mnt"
//                                + File.separator + "sdcard" + File.separator;
//                        System.out.println(file_path);
//                        pmm.setAttachPath(file_path);
                        // 下載下傳附件并儲存到本地,此處包含附件以及内嵌資源(内嵌表情,内嵌圖檔等)
                        pmm.saveAttachMent((Part) messages[i],pmm.getSentDate());
                        EMAIL email = new EMAIL();
                        email.sender_email = pmm.getFrom();
                        if(pmm.getFrom().split("<")[0].equals("")){
                            email.sender_name = pmm.getFrom().split("@")[0].split("<")[1];
                        }else {
                            email.sender_name = pmm.getFrom().split("<")[0];
                        }
                        email.content = pmm.getBodyText();
                        email.subject = pmm.getSubject();
                        email.time = pmm.getSentDate();
                        email.to = pmm.getMailList("to");
                        email.copy = pmm.getMailList("cc");
                        email.attachment = pmm.getAttachMent((Part) messages[i]);
                        list.add(email);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //此處 大佬可自行更換,憋人用的hanlder
                android.os.Message msgg = new android.os.Message();
                msgg.what = CustomMessageConstant.IMAP_DETAIL_REFRESH;
                if (type.equals("INBOX")) {//收件箱
                    msgg.arg1 = EmailIMAPListView.INBOX;
                } else if (type.equals("Sent")) {//發件箱
                    msgg.arg1 = EmailIMAPListView.OUTBOX;
                }
                msgg.obj = list;
                handler.sendMessage(msgg);
            }
        } catch (javax.mail.NoSuchProviderException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }

    }


}
           
/**
 * 接收郵箱中的郵件,可以接收帶附件的
 * (目前接收的郵件中含有中文内容,會出現亂碼,但是标題不會亂碼)
 * 郵件中的内容如果用專門的閱讀器也不會出現亂碼現象,圖檔等都可以下載下傳
 */
@SuppressLint("DefaultLocale")
public class ReciveOneMail {

    private MimeMessage mimeMessage = null;
    private String saveAttachPath = ""; // 附件下載下傳後的存放目錄
    private StringBuffer bodytext = new StringBuffer();// 存放郵件内容
    private String dateformat = "yy-MM-dd HH:mm"; // 預設的日前顯示格式

    public ReciveOneMail(MimeMessage mimeMessage) {
        this.mimeMessage = mimeMessage;
    }

    public void setMimeMessage(MimeMessage mimeMessage) {
        this.mimeMessage = mimeMessage;
    }

    /**
     * 獲得發件人的位址和姓名
     */
    public String getFrom() throws Exception {
        InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
        String from = address[0].getAddress();
        if (from == null)
            from = "";
        String personal = address[0].getPersonal();
        if (personal == null)
            personal = "";
        String fromaddr = personal + "<" + from + ">";
        return fromaddr;
    }

    /**
     * 獲得郵件的收件人,抄送,和密送的位址和姓名,根據所傳遞的參數的不同 "to"----收件人 "cc"---抄送人位址 "bcc"---密送人位址
     */
    @SuppressLint("DefaultLocale")
    public String getMailAddress(String type) throws Exception {
        String mailaddr = "";
        String addtype = type.toUpperCase();
        InternetAddress[] address = null;
        if (addtype.equals("TO") || addtype.equals("CC")
                || addtype.equals("BCC")) {
            if (addtype.equals("TO")) {
                address = (InternetAddress[]) mimeMessage
                        .getRecipients(Message.RecipientType.TO);
            } else if (addtype.equals("CC")) {
                address = (InternetAddress[]) mimeMessage
                        .getRecipients(Message.RecipientType.CC);
            } else {
                address = (InternetAddress[]) mimeMessage
                        .getRecipients(Message.RecipientType.BCC);
            }
            if (address != null) {
                for (int i = 0; i < address.length; i++) {
                    String email = address[i].getAddress();
                    if (email == null)
                        email = "";
                    else {
                        email = MimeUtility.decodeText(email);
                    }
                    String personal = address[i].getPersonal();
                    if (personal == null)
                        personal = "";
                    else {
                        personal = MimeUtility.decodeText(personal);
                    }
                    String compositeto = personal + "<" + email + ">";
                    mailaddr += "," + compositeto;
                }
                mailaddr = mailaddr.substring(1);
            }
        } else {
            throw new Exception("Error emailaddr type!");
        }
        return mailaddr;
    }

    @SuppressLint("DefaultLocale")
    public ArrayList<RECIPIENTS> getMailList(String type) throws Exception {
        ArrayList<RECIPIENTS> toOrccList = new ArrayList<RECIPIENTS>(); // 收件人
        String mailaddr = "";
        String addtype = type.toUpperCase();
        InternetAddress[] address = null;
        if (addtype.equals("TO") || addtype.equals("CC")
                || addtype.equals("BCC")) {
            if (addtype.equals("TO")) {
                address = (InternetAddress[]) mimeMessage
                        .getRecipients(Message.RecipientType.TO);
            } else if (addtype.equals("CC")) {
                address = (InternetAddress[]) mimeMessage
                        .getRecipients(Message.RecipientType.CC);
            } else {
                address = (InternetAddress[]) mimeMessage
                        .getRecipients(Message.RecipientType.BCC);
            }
            toOrccList.clear();
            if (address != null) {
                for (int i = 0; i < address.length; i++) {
                    String email = address[i].getAddress();
                    if (email == null)
                        email = "";
                    else {
                        email = MimeUtility.decodeText(email);
                    }
                    String personal = address[i].getPersonal();
                    if (personal == null)
                        personal = "";
                    else {
                        personal = MimeUtility.decodeText(personal);
                    }
                    String compositeto = personal + "<" + email + ">";
                    mailaddr += "," + compositeto;
                    RECIPIENTS recipients = new RECIPIENTS();
                    recipients.address = email;
                    recipients.name = personal;
                    toOrccList.add(recipients);
                }
                mailaddr = mailaddr.substring(1);
            }
        } else {
            throw new Exception("Error emailaddr type!");
        }
        return toOrccList;
    }

    /**
     * 獲得郵件主題
     */
    public String getSubject() throws MessagingException {
        String subject = "";
        try {
            subject = MimeUtility.decodeText(mimeMessage.getSubject());
            if (subject == null)
                subject = "";
        } catch (Exception exce) {
        }
        return subject;
    }

    /**
     * 獲得郵件發送日期
     */
    @SuppressLint("SimpleDateFormat")
    public String getSentDate() throws Exception {
        Date sentdate = mimeMessage.getSentDate();
        SimpleDateFormat format = new SimpleDateFormat(dateformat);
        return format.format(sentdate);
    }

    /**
     * 獲得郵件正文内容
     */
    public String getBodyText() {
        return bodytext.toString();
    }

    /**
     * 解析郵件,把得到的郵件内容儲存到一個StringBuffer對象中,解析郵件 主要是根據MimeType類型的不同執行不同的操作,一步一步的解析
     */
    public void getMailContent(Part part) throws Exception {
        String contenttype = part.getContentType();
        int nameindex = contenttype.indexOf("name");
        boolean conname = false;
        if (nameindex != -1)
            conname = true;
        System.out.println("CONTENTTYPE: " + contenttype);
        if (part.isMimeType("text/plain") && !conname) {
            bodytext.append((String) part.getContent());
        } else if (part.isMimeType("text/html") && !conname) {
            bodytext.append((String) part.getContent());
        } else if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();
            int counts = multipart.getCount();
            for (int i = 0; i < counts; i++) {
                getMailContent(multipart.getBodyPart(i));
            }
        } else if (part.isMimeType("message/rfc822")) {
            getMailContent((Part) part.getContent());
        } else {
        }
    }

    /**
     * 判斷此郵件是否需要回執,如果需要回執傳回"true",否則傳回"false"
     */
    public boolean getReplySign() throws MessagingException {
        boolean replysign = false;
        String needreply[] = mimeMessage
                .getHeader("Disposition-Notification-To");
        if (needreply != null) {
            replysign = true;
        }
        return replysign;
    }

    /**
     * 獲得此郵件的Message-ID
     */
    public String getMessageId() throws MessagingException {
        return mimeMessage.getMessageID();
    }

    /**
     * 【判斷此郵件是否已讀,如果未讀傳回傳回false,反之傳回true】pop3協定使用時不能判斷。
     */
    public boolean isNew() throws MessagingException {
        boolean isnew = false;//由于isnew設為false是以每次顯示的都為未讀
        Flags flags = ((Message) mimeMessage).getFlags();
//        System.out.println("--------flags-------" + flags);
        Flags.Flag[] flag = flags.getSystemFlags();
//        System.out.println("----flag----" + flag);
//        System.out.println("flags's length: " + flag.length);
        for (int i = 0; i < flag.length; i++) {
//            System.out.println("flag=======" + flag[i]);
//            System.out.println("-=-=-=Flags.Flag.SEEN=-=-=-=" + Flags.Flag.SEEN);
            if (flag[i] == Flags.Flag.SEEN) {
                isnew = true;
//                System.out.println("seen Message.......");
                break;
            }
        }
        return isnew;
    }

    /**
     * 判斷此郵件是否包含附件
     */
    @SuppressLint("DefaultLocale")
    public boolean isContainAttach(Part part) throws Exception {
        boolean attachflag = false;
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mpart = mp.getBodyPart(i);
                String disposition = mpart.getDisposition();
                if ((disposition != null) && (disposition.equals(Part.ATTACHMENT) || (disposition.equals(Part.INLINE)))) {
                    if (mpart.getContentType().toLowerCase().indexOf("name") != -1) {
                        attachflag = true;
                    } else if (mpart.getFileName() != null) {
                        attachflag = true;
                    } else {
                        attachflag = false;
                    }

                } /*else if((disposition != null) && (disposition.equals(Part.INLINE))){
                    attachflag = false;
                }*/ else if (mpart.isMimeType("multipart/*")) {
                    attachflag = isContainAttach((Part) mpart);
                } else {
                    String contype = mpart.getContentType();
                    if (contype.toLowerCase().indexOf("application") != -1)
                        attachflag = true;
                    if (contype.toLowerCase().indexOf("name") != -1)
                        attachflag = true;
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            attachflag = isContainAttach((Part) part.getContent());
        }
        return attachflag;
    }

    /**
     * 【儲存附件】
     */
    @SuppressLint("DefaultLocale")
    public void saveAttachMent(Part part, String emailTimei) throws Exception {
        if (isContainAttach(part)) {
            String fileName = "";
            if (part.isMimeType("multipart/*")) {
                Multipart mp = (Multipart) part.getContent();
                for (int i = 0; i < mp.getCount(); i++) {
                    BodyPart mpart = mp.getBodyPart(i);//主體部分得到處理
                    if (mpart.isMimeType("multipart/*")) {
                        saveAttachMent(mpart, emailTimei);
                    } else {
                        String disposition = mpart.getDisposition();
                        if ((disposition != null)
                                && (disposition.equals(Part.ATTACHMENT) || (disposition.equals(Part.INLINE)))) {//ATTACHMENT附件
                            fileName = mpart.getFileName();
                            if (fileName != null) {
                               /* if (fileName.toLowerCase().indexOf("gb2312") != -1 || fileName.toLowerCase().indexOf("gb1803") != -1 ||fileName.toLowerCase().indexOf("gbk") != -1) {
                                    fileName = MimeUtility.decodeText(fileName);
                                }
                                if (fileName.toLowerCase().indexOf("utf-8") != -1) {//gb18030
                                    fileName = MimeUtility.decodeText(fileName);
                                }*/
                                fileName = MimeUtility.decodeText(fileName);
                                saveFile(emailTimei + fileName, mpart.getInputStream());//郵件發送時間+附件名稱 生成新的附件名稱,這裡為了防止附件重名
                            }
                        } else {
                            fileName = mpart.getFileName();
                            if (fileName == null && mpart.getContentType().contains("name=")) {
                                fileName = mpart.getContentType().split("name=")[1];
                            }
                            if (fileName != null) {
                                /*if ((fileName.toLowerCase().indexOf("gb2312") != -1)
                                        && (fileName.toLowerCase().indexOf("utf-8") != -1)
                                        ) {*/

                                fileName = MimeUtility.decodeText(fileName);
                                saveFile(emailTimei + fileName, mpart.getInputStream());
//                                }
                            }
                        }
                    }
                }
            } else if (part.isMimeType("message/rfc822")) {
                saveAttachMent((Part) part.getContent(), emailTimei);
            }
        }
    }

    /**
     * 【擷取附件】
     */
    ArrayList<ATTACHMENT> attachments = new ArrayList<ATTACHMENT>();

    @SuppressLint("DefaultLocale")
    public ArrayList<ATTACHMENT> getAttachMent(Part part) throws Exception {

        ATTACHMENT attachment;

        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mpart = mp.getBodyPart(i);//主體部分得到處理
                if (mpart.isMimeType("multipart/*")) {
                    getAttachMent(mpart);
                } else {
                    String disposition = mpart.getDisposition();
                    if ((disposition != null)
                            && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                            .equals(Part.INLINE)))) {//ATTACHMENT附件,INLINE嵌入
                        String fileName = "";
                        fileName = mpart.getFileName();

                        if (fileName != null) {
                           /* if (fileName.toLowerCase().indexOf("gb2312") != -1 || fileName.toLowerCase().indexOf("gb1803") != -1 || fileName.toLowerCase().indexOf("gbk") != -1 ) {//gb18030
                                fileName = MimeUtility.decodeText(fileName);
                            }
                            if (fileName.toLowerCase().indexOf("utf-8") != -1) {//gb18030
                                fileName = MimeUtility.decodeText(fileName);
                            }*/
                            fileName = MimeUtility.decodeText(fileName);
                            int fileSize = mpart.getSize();
                            attachment = new ATTACHMENT();
                            attachment.filesize = GetFileSize.FormetFileSize(fileSize);
                            //附件沒有cid,内嵌圖檔表情等資源有Cid
                            attachment.cid = getCid(mpart);
                            attachment.realname = fileName.replace("\\","");
                            attachment.filelocalPath = AppStoragePath.getCachePath() + File.separator + fileName;
                            attachments.add(attachment);
                        }
                    } else {
                        String fileName = "";
                        fileName = mpart.getFileName();
                        if (fileName == null && mpart.getContentType().contains("name=")) {
                            fileName = mpart.getContentType().split("name=")[1];
                        }
                        if (fileName != null) {
                               /* if (fileName.toLowerCase().indexOf("gb2312") != -1 && fileName.toLowerCase().indexOf("gb1803") != -1 && fileName.toLowerCase().indexOf("gbk") != -1
                                && (fileName.toLowerCase().indexOf("utf-8") != -1)
                                ) {
                                  fileName = MimeUtility.decodeText(fileName);
                                }*/
                            fileName = MimeUtility.decodeText(fileName);
                            attachment = new ATTACHMENT();
                            attachment.filesize = GetFileSize.FormetFileSize(mpart.getSize());
           //附件沒有cid,内嵌圖檔表情等資源有Cid
                            attachment.cid = getCid(mpart);
                            attachment.realname = fileName.replace("\\","");
                            attachment.filelocalPath = AppStoragePath.getCachePath() + File.separator + fileName;
                            attachments.add(attachment);
                        }
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            getAttachMent((Part) part.getContent());
        }
        return attachments;
    }

    /**
     * 擷取内嵌資源id
     * 判斷是否是表情或者正文圖檔的重要依據 ,判斷是否有cid
     * @param p
     * @return
     * @throws MessagingException
     */
    public static String getCid(Part p) throws MessagingException {
        String content, cid;
        String[] headers = p.getHeader("Content-Id");
        if (headers != null && headers.length > 0) {
            content = headers[0];
        } else {
            return null;
        }
        if (content.startsWith("<") && content.endsWith(">")) {
            cid = "cid:" + content.substring(1, content.length() - 1);
        } else {
            cid = "cid:" + content;
        }
        return cid;
    }


    /**
     * 【設定附件存放路徑】
     */
    public void setAttachPath(String attachpath) {
        this.saveAttachPath = attachpath;
    }

    /**
     * 【設定日期顯示格式】
     */
    public void setDateFormat(String format) throws Exception {
        this.dateformat = format;
    }

    /**
     * 【獲得附件存放路徑】
     */
    public String getAttachPath() {
        return saveAttachPath;
    }

    /**
     * 【真正的儲存附件到指定目錄裡】
     */
    @SuppressLint("DefaultLocale")
    public void saveFile(String fileName, InputStream in) throws Exception {

        fileName = fileName.replace("\\","");
        File storefile = new File(AppStoragePath.getCachePath() + File.separator + fileName);
        if (!storefile.exists()) {
            storefile.createNewFile();

            BufferedOutputStream bos = null;
            BufferedInputStream bis = null;
            try {
                bos = new BufferedOutputStream(new FileOutputStream(storefile));
                bis = new BufferedInputStream(in);
                int c;
                while ((c = bis.read()) != -1) {
                    bos.write(c);
                    bos.flush();
                }
            } catch (Exception exception) {
            } finally {
                bos.close();
                bis.close();
            }
        }
    }


// 附件下載下傳完成 回調接口
    public interface OnDownloadListener {
        void onSuccess();

        void onFaild();
    }

    OnDownloadListener onDownloadListener;
}
           
/**
* Create by wz
* 附件entity
*/

public class ATTACHMENT implements Serializable {
    public String fileid; // id

    public String realname; // 名稱

    public String filesize; // 大小

    public String filelocalPath ;//檔案本地路徑

    public String cid;


    public void fromJson(JSONObject jsonObject) throws JSONException {
        if( null == jsonObject ) {
            return ;
        }

        JSONArray subItemArray = new JSONArray();

        this.fileid = jsonObject.optString("fileid");
        this.realname = jsonObject.optString("realname");
        this.filesize = jsonObject.optString("filesize");
        this.cid = jsonObject.optString("cid");
        return;
    }

    public JSONObject toJson() throws JSONException {
        JSONObject localItemObject = new JSONObject();
        JSONArray itemJSONArray = new JSONArray();
        localItemObject.put("fileid", fileid);
        localItemObject.put("realname", realname);
        localItemObject.put("filesize", filesize);
        localItemObject.put("cid", cid);
        return localItemObject;
    }
}
           
/**
* Create by wz
* 郵件詳情entity
* 此處與收發郵箱清單entity差別:清單出不需要有附件的詳細内容,此處确實需要
*/

public class EMAIL implements Serializable {
    public String unid; // 郵件unid

    public String sender_email; // 發件人

    public String sender_name; // 發件人

    public ArrayList<RECIPIENTS> to = new ArrayList<RECIPIENTS>(); // 收件人

    public ArrayList<RECIPIENTS> copy = new ArrayList<RECIPIENTS>(); // 抄送

    public String time; // 時間

    public String message_id; // id

    public String subject; // 主題

    public String content; // 内容

    public ArrayList<ATTACHMENT> attachment = new ArrayList<ATTACHMENT>(); // 附件

    public void fromJson(JSONObject jsonObject) throws JSONException {
        if( null == jsonObject ) {
            return ;
        }

        JSONArray subItemArray = new JSONArray();
        this.unid = jsonObject.optString("unid");
        this.sender_email = jsonObject.optString("sender_email");
        this.sender_name = jsonObject.optString("sender_name");
        subItemArray = jsonObject.optJSONArray("to");
        if(null != subItemArray) {
            for(int i = 0;i < subItemArray.length();i++) {
                JSONObject subItemObject = subItemArray.getJSONObject(i);
                RECIPIENTS subItem = new RECIPIENTS();
                subItem.fromJson(subItemObject);
                this.to.add(subItem);
            }
        }
        subItemArray = jsonObject.optJSONArray("copy");
        if(null != subItemArray) {
            for(int i = 0;i < subItemArray.length();i++) {
                JSONObject subItemObject = subItemArray.getJSONObject(i);
                RECIPIENTS subItem = new RECIPIENTS();
                subItem.fromJson(subItemObject);
                this.copy.add(subItem);
            }
        }
        this.time = jsonObject.optString("time");
        this.message_id = jsonObject.optString("message_id");
        this.subject = jsonObject.optString("subject");
        this.content = jsonObject.optString("content");
        subItemArray = jsonObject.optJSONArray("attachment");
        if(null != subItemArray) {
            for(int i = 0;i < subItemArray.length();i++) {
                JSONObject subItemObject = subItemArray.getJSONObject(i);
                ATTACHMENT subItem = new ATTACHMENT();
                subItem.fromJson(subItemObject);
                this.attachment.add(subItem);
            }
        }
        return;
    }

    public JSONObject toJson() throws JSONException {
        JSONObject localItemObject = new JSONObject();
        JSONArray itemJSONArray = new JSONArray();
        localItemObject.put("unid", unid);
        localItemObject.put("sender_email", sender_email);
        localItemObject.put("sender_name", sender_name);
        itemJSONArray = new JSONArray();
        for(int i =0; i< to.size(); i++) {
            RECIPIENTS itemData =to.get(i);
            JSONObject itemJSONObject = itemData.toJson();
            itemJSONArray.put(itemJSONObject);
        }
        localItemObject.put("to", itemJSONArray);

        itemJSONArray = new JSONArray();
        for(int i =0; i< copy.size(); i++) {
            RECIPIENTS itemData =copy.get(i);
            JSONObject itemJSONObject = itemData.toJson();
            itemJSONArray.put(itemJSONObject);
        }
        localItemObject.put("copy", itemJSONArray);

        localItemObject.put("time", time);
        localItemObject.put("message_id", message_id);
        localItemObject.put("subject", subject);
        localItemObject.put("content", content);
        itemJSONArray = new JSONArray();
        for(int i =0; i< attachment.size(); i++) {
            ATTACHMENT itemData =attachment.get(i);
            JSONObject itemJSONObject = itemData.toJson();
            itemJSONArray.put(itemJSONObject);
        }
        localItemObject.put("attachment", itemJSONArray);

        return localItemObject;
    }
}
           
//郵件詳情頁面拿到資料後進行展示 ,bindData();
Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == CustomMessageConstant.IMAP_DETAIL_REFRESH) {
                if(((ArrayList<EMAIL>) msg.obj).size() > 0) {
                    mEmail = ((ArrayList<EMAIL>) msg.obj).get(0);
                    bindData();
                }
            } else if (msg.what == CustomMessageConstant.IMAP_DETAIL_DOWNLOAD) {
                if (mProgressDialog != null && mProgressDialog.isShowing()) {
                    mProgressDialog.dismiss();
                }
            }
        }
    };
           

3、郵件發送與轉發回複,已經添加到發件箱(此處一坑,如果不手動添加進去,發件箱是不會重新整理出你發送成功的郵件的)

//發送郵件
            EmailThreadUtil.stop();
            SentEmailUP sentEmailUP = new SentEmailUP(theme,content,mSelectUsersShou,mSelectUsersChao,mSelectUsersMi,mFiles,handler,mEmail);
            EmailThreadUtil.execute(sentEmailUP);
           
/*
* Create by wz
* 發送郵件請求 以及 儲存件到發件箱
*/

public class SentEmailUP extends EmailListUP {

    private String userName;
    private String password;
    private String host;
    private int port;
    private ArrayList<RECIPIENTS> to;
    private ArrayList<RECIPIENTS> cc;
    private ArrayList<RECIPIENTS> bcc;
    private EMAIL mEmail;
    private String content;
    private String subject;
    private ArrayList<String> mFiles;
    private Handler handler;


    /**
     * @param subject 主題
     * @param content 内容
     * @param to      收件者
     * @param cc      抄送
     * @param bcc     密送
     * @param mFiles  附件
     * @param handler
     */
    public SentEmailUP(String subject, String content, ArrayList<RECIPIENTS> to, ArrayList<RECIPIENTS> cc, ArrayList<RECIPIENTS> bcc, ArrayList<String> mFiles, Handler handler,EMAIL mEmail) {
        this.to = to;
        this.content = content;
        this.subject = subject;
        this.mFiles = mFiles;
        this.cc = cc;
        this.bcc = bcc;
        this.handler = handler;
        this.userName = SESSION.getInstance().getEmail();
        this.password = SESSION.getInstance().getOAPassword();
        this.host = SESSION.getInstance().getEmailHost();
        this.port = SESSION.getInstance().getSendEmailPost();
        this.mEmail = mEmail;

    }

    @Override
    public void run() {
        sendAttachmentMail();
    }

    /**
     * 發送附件郵件
     *
     * @throws Exception
     */
    public void sendAttachmentMail() {
        Properties pro = System.getProperties();
        pro.setProperty("mail.transport.protocol", "smtp"); // 設定郵件傳輸采用的協定smtp
        pro.put("mail.smtp.host", this.host);
        pro.put("mail.smtp.port", this.port);
        pro.put("mail.smtp.auth", "true");
        pro.setProperty("mail.smtp.starttls.enable", "true");     // 設定驗證機制

        try {
            // 根據郵件會話屬性和密碼驗證器構造一個發送郵件的session
            Session sendMailSession = Session.getInstance(pro,
                    new Authenticator() {
                        @Override
                        protected PasswordAuthentication getPasswordAuthentication() {
                            return new PasswordAuthentication(userName, password);
                        }
                    });
            // 根據session建立一個郵件消息
            Message mailMessage = new MimeMessage(sendMailSession);
            // 設定郵件消息的發送者
            mailMessage.setFrom(new InternetAddress(userName, SESSION.getInstance().getRealname(), "UTF-8"));

            // 建立郵件的接收者位址,并設定到郵件消息中
            if (to.size() > 0) {
                InternetAddress[] sendTo = new InternetAddress[to.size()];
                for (int i = 0; i < to.size(); i++) {
                    String address;
                    if (to.get(i).address.contains("<") && to.get(i).address.contains(">")) {
                        address = to.get(i).address.split("<")[1].split(">")[0];
                    } else {
                        address = to.get(i).address;
                    }
                    sendTo[i] = new InternetAddress(address, to.get(i).name, "UTF-8");
                }
                mailMessage.addRecipients(Message.RecipientType.TO, sendTo);
            }

            // 建立郵件的抄送者位址,并設定到郵件消息中
            if (cc.size() > 0) {
                InternetAddress[] ccTo = new InternetAddress[cc.size()];
                for (int i = 0; i < cc.size(); i++) {
                    String address;
                    if (cc.get(i).address.contains("<") && cc.get(i).address.contains(">")) {
                        address = cc.get(i).address.split("<")[1].split(">")[0];
                    } else {
                        address = cc.get(i).address;
                    }
                    ccTo[i] = new InternetAddress(address, to.get(i).name, "UTF-8");
                }
                mailMessage.addRecipients(Message.RecipientType.CC,
                        ccTo);
            }
            // 建立郵件的密送者位址,并設定到郵件消息中
            if (bcc.size() > 0) {
                InternetAddress[] bccTo = new InternetAddress[bcc.size()];
                for (int i = 0; i < bcc.size(); i++) {
                    String address;
                    if (bcc.get(i).address.contains("<") && bcc.get(i).address.contains(">")) {
                        address = bcc.get(i).address.split("<")[1].split(">")[0];
                    } else {
                        address = bcc.get(i).address;
                    }
                    bccTo[i] = new InternetAddress(address, to.get(i).name, "UTF-8");
                }
                mailMessage.addRecipients(Message.RecipientType.BCC,
                        bccTo);
            }

           /* mailMessage.setRecipient(Message.RecipientType.BCC,
                    new InternetAddress(bcc));*/
            // 設定郵件消息的主題
            mailMessage.setSubject(this.subject);
            // 設定郵件消息發送的時間
            mailMessage.setSentDate(new Date());

            MimeMultipart multipart = new MimeMultipart("mixed");

            BodyPart messageBodyPart = new MimeBodyPart();
            String htmlText = "<html><body><div>" + content + "</div></body></html>";
            messageBodyPart.setContent(htmlText, "text/html; charset=utf-8");
            multipart.addBodyPart(messageBodyPart);

            if (mFiles.size() > 0) {
                String file;
                for (int i = 0 ;i < mFiles.size() ; i++) {
                    file = mFiles.get(i);
                    MimeBodyPart imageBodyPart = new MimeBodyPart();
                    File imageFile = new File(file);
                    DataSource fds = new FileDataSource(imageFile);
                    imageBodyPart.setDataHandler(new DataHandler(fds));
                    String[] name = imageFile.getName().replace(" ","").split("\\.");
                    //由于我在儲存附件的時候為了防止附件名稱重複,在附件的名稱前邊加了郵箱的時間戳
                    // 所在在發送的時候要把前邊的時間戳去掉
                    String filename = name[0].split(":")[name[0].split(":").length-1];
                    filename = filename.substring(2,filename.length()).replace("\\","");
                   //MimeUtility.encodeWord 防止附件名稱中文亂碼
                    imageBodyPart.setFileName(MimeUtility.encodeWord(filename+"." + name[name.length-1]));
                    String path ;
                     //UserAppConst.IS_SHOW_EMAIL_CID 這個判斷可以自行去掉,我們暫時沒有展示表情的需求,是以我做了個開關,暫時關掉了
                     if(UserAppConst.IS_SHOW_EMAIL_CID && mEmail != null) {
                        for(ATTACHMENT att : mEmail.attachment){
                            path = AppStoragePath.getCachePath() + File.separator + mEmail.time + att.realname;
                            if(path.equals(file) && !TextUtils.isEmpty(att.cid)){
                                imageBodyPart.setContentID(att.cid.split(":")[1]);
                            }
                        }
                    }

                    multipart.addBodyPart(imageBodyPart);

                }
            }
            mailMessage.setContent(multipart);
            // 發送郵件
            Transport.send(mailMessage);
            //儲存到IMAP伺服器發件箱
            copyIntoSent(mailMessage);
            //成功
            android.os.Message msg = new android.os.Message();
            msg.what = IMAPSentEmailActivity.SENT_SUCCESS;
            handler.sendMessage(msg);
        } catch (Exception e) {
            e.printStackTrace();
            //失敗
            android.os.Message msg = new android.os.Message();
            msg.what = IMAPSentEmailActivity.SENT_FAILD;
            handler.sendMessage(msg);
        }
    }


    /**
     * 儲存郵件到發件箱
     *
     * @param msg 郵件資訊
     */
    private void copyIntoSent(Message msg) {
        IMAPStore store = null;
        IMAPFolder folder = null;
        try {
            Properties prop = System.getProperties();
            prop.put("mail.store.protocol", "imap");
            prop.put("mail.imap.host", this.host);
            prop.put("mail.imap.port", SESSION.getInstance().getEmailPost());

            Session session = Session.getDefaultInstance(prop);


            store = (IMAPStore) session.getStore("imap"); // 使用imap會話機制,連接配接伺服器

            store.connect(this.userName, this.password);

            folder = (IMAPFolder) store.getFolder("Sent");
            if (!folder.exists()) {
                folder.create(Folder.HOLDS_MESSAGES);
            }
            folder.open(Folder.READ_WRITE);
            folder.appendMessages(new Message[]{msg});
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 判斷發件檔案夾是否打開如果打開則将其關閉
            if (folder != null && folder.isOpen()) {
                try {
                    folder.close(true);
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
            }
            // 判斷郵箱存儲是否打開如果打開則将其關閉
            if (store != null && store.isConnected()) {
                try {
                    store.close();
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
            }
        }
    }


}
           

 注意 注意 注意 :此處一個超級大坑,如果附件名稱太長,會在其他郵箱用戶端擷取不到附件名稱,超級大坑啊,我隻說解決辦法:在application的初始化裡邊加上一行代碼:

System.setProperty("mail.mime.splitlongparameters","false");
           

ok,這個也解決了,具體原因看我上一篇部落格,有詳細解釋的。

4、郵件正文顯示表情

 上邊注釋說到,這個“附件”啊,其實并不是就是你發郵件時候附帶的檔案,他還包含你發送郵件時候正文裡邊夾雜的表情啊什麼的。因為我們在擷取附件的時候,已經全部都下載下傳到本地了,這裡展示表情等内嵌資源就會簡單的多了,上代碼。

/**
     * 給文本嵌套css樣式
     * 我這裡為了讓郵件正文看起來跟順眼一點,外邊加了css
     */
    private void setHtml() {
        String css = "<style type=\"text/css\">" +
                "body {" +
                "font-size:15px;"+
                //允許自動換行(漢字網頁應該不需要這一屬性,這個用來強制英文單詞換行,類似于word/wps中的西文換行)
                "word-wrap:break-word;" +
                "}" +
                "</style>";




        String content = mEmail.content;
        if (UserAppConst.IS_SHOW_EMAIL_CID) {//此處判斷,你們可以自行去掉,因為這個顯示表情的需求暫時沒有,是以我做了個開關,把他先給屏蔽了
            for (int i = 0; i < mEmail.attachment.size(); i++) {
                if (!TextUtils.isEmpty(mEmail.attachment.get(i).cid) && content.contains(mEmail.attachment.get(i).cid)) {
                    content = content.replace(mEmail.attachment.get(i).cid, "file://" + AppStoragePath.getCachePath() + File.separator + mEmail.time + mEmail.attachment.get(i).realname);
                }
            }
        }
        String html = "<html><header>" + css + "</header><body>" + content + "</body></html>";
    //    mContent.loadData(html, "text/html; charset=UTF-8", null);
        mContent.loadDataWithBaseURL(null,html,"text/html","UTF-8",null);
    }
           

其實就是把郵箱正文中的 cid:85545245 換成附件的本地位址  file://.... 

注意:這裡一定要是file:// + 附件本地位址。

總結,希望能幫到大家吧,有什麼不足的地方還望大家指正,我寫的這些也不是很好,比如附件怎麼做到先不下載下傳,想看的時候點選摸個附件的時候才下載下傳并且打開呢,我還在思考中,好了今天就到這裡了。