前一阵子,园区的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: