javamail 基于imap和smtp协议手机客户端开发,邮件收件箱、发件箱、邮件详情、转发回复、附件下载、邮件正文显示表情等功能

本文介绍了如何使用javamail通过imap和smtp协议开发Android手机客户端的邮箱功能,包括收件箱、发件箱的展示,邮件详情查看,附件下载,邮件正文表情显示以及转发回复邮件的操作。在开发过程中遇到的如附件名称过长问题及邮件正文表情显示的方法进行了详细说明。
摘要由CSDN通过智能技术生成

    前一阵子,园区的APP要开发手机端的邮箱功能,NND,就这个功能开发了三个版本,我也是醉了,前两个版本都是基于后台去开发给移动端提供接口的,but,后台不愿意了,说是他们工作量太大做不了,WTF ?!,后来直接说让我们移动端自己开发....,哎,自己开发就开发吧,之前没接触过,也是踩着无数坑过来的呀,希望对大家有所帮助吧,不尽完美,勉强能用,求大神指引方向。看图:

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: 
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值