前面说完发邮件,现在开始收邮件了。
对不同的协议来进行不同的处理,POP3协议邮箱在服务器上只定义一个邮箱,所以需要自己完成删除,移动,标记等功能,
而Imap则相反,大大降低了客户端代码量。
1.Imap
接收时只需要知道服务器,账户,密码就可以了,当然也可以设置端口号。
public static Message[] getAllIMAPMail(String mailBoxType, String mailType) {
Message[] messages = null;
<span style="white-space:pre"> </span>// 设置邮件支持多种格式
<span style="white-space:pre"> </span>sendAndCollect();
// 用户名,密码登陆
PopupAuthenticator popupAuthenticator = new PopupAuthenticator();
Session session = Session.getDefaultInstance(System.getProperties(),
popupAuthenticator);
Store store = null;
Folder folder = null;
try {
// 修改协议
// pop3/imap
store = session.getStore(mailBoxType);
// 服务器, 用户名, 密码
store.connect("", "", "");
// pop3只有INBOX
// 而imap则有如下
// INBOX --- 收件箱
// 已发送 --- 已发送邮件
// 已删除 --- 已删除邮件
// 草稿箱 --- 草稿箱
folder = store.getFolder(mailType);
folder.open(Folder.READ_WRITE);
// 得到总邮件数
int mailCount = folder.getMessageCount();
if (mailCount > 0) {
messages = folder.getMessages();
}
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} finally {
}
// 将数据倒序显示
List<Message> list = new ArrayList<>();
for (int i = 0; i < messages.length; i++) {
list.add(messages[i]);
}
Collections.reverse(list);
list.toArray(messages);
return messages;
}
如上所示,在后面需要将得到的邮箱内容倒序,因为我们得到的邮箱是时间排序,第一个是最早收到的邮件。在这里说一下,在将
邮件内容插入到界面后,一定要将打开的邮箱关闭。并且要支持多种格式的邮件,否则会得到一个流而不是邮件容器。
在得到邮件后可以得到基本的邮件内容:发送人,收件人,抄送人,密送人,主题,时间。
之后就都是需要一步步解析的了(拆包)。
判断邮件类型,得到邮件容器,找到对应类型并处理相对应的数据。在这里我做的并完整,但是该代码可以基本解析大部分
HTML邮件+内嵌图片,在匹配到内嵌图片时也只能用最笨的方法把HTML中img标签的cid转换为下载好图片文件的绝对地址,来
勉强实现内嵌图片的内容(如果有更好的方法,据说是Swing JEditorPane,不吝赐教)。在通过查找标签,删除标签,插入标签后,
就可以显示内嵌图片到WebView上。
// 得到HTML数据
// 显示在具体内容中
public static String getHTMLContent(Part message, StringBuffer bodytext)
throws MessagingException, IOException {
if (message.isMimeType("message/rfc822")) {
} else if (message.isMimeType("multipart/*")) {
Multipart multipart = (Multipart) message.getContent();
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart m = multipart.getBodyPart(i);
if (m.isMimeType("multipart/*")) {
getHTMLContent(m, bodytext);
}
if (m.isMimeType("text/html")) {
bodytext.append((String) m.getContent());
}
if (m.isMimeType("image/*")) {
// 得到HTML文件中所有图片的Content-ID,里面包含图片的cid名称
String[] strs = m.getHeader("Content-ID");
for (int j = 0; j < strs.length; j++) {
// cid名称规范化
if (strs[0].startsWith("<") && strs[0].endsWith(">")) {
strs[0] = "cid:"
+ strs[0]
.substring(1, strs[0].length() - 1);
} else {
strs[0] = "\"cid:" + strs[0] + "\"";
}
// 文件名
File file = new File(
Environment.getExternalStorageDirectory() + "/"
+ m.getFileName());
// 文件判断是否存在
if (!file.exists()) {
try {
BufferedInputStream bis = new BufferedInputStream(
m.getInputStream());
BufferedOutputStream bos;
bos = new BufferedOutputStream(
new FileOutputStream(file));
int len = -1;
while ((len = bis.read()) != -1) {
bos.write(len);
bos.flush();
}
bos.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
Log.d("--->", "下载失败");
}
}
// 找到图片绝对路径
String url = file.getAbsolutePath();
int index = bodytext.indexOf(strs[0]);
// 交换图片内嵌地址
// TODO 图片缩放
if (index != -1) {
bodytext.delete(index, bodytext.indexOf(">", index));
bodytext.insert(index, "file://" + url
+ "\" width=\"100%\"");
}
}
}
}
}
return bodytext.toString();
}
当然还可以得到邮件的纯文本内容,和上面很想:
// 得到邮件文本内容
// 只显示在列表上
public static StringBuffer getMailContent(Part message,
StringBuffer bodytext) throws Exception {
boolean isContainTextAttach = message.getContentType().indexOf("name") > 0;
if (message.isMimeType("text/*") && !isContainTextAttach) {
bodytext.append(message.getContent() + "");
} else if (message.isMimeType("message/rfc822")) {
getMailContent((Part) message.getContent(), bodytext);
} else if (message.isMimeType("multipart/*")) {
Multipart multipart = (Multipart) message.getContent();
if (multipart.getCount() > 0) {
BodyPart bodyPart = multipart.getBodyPart(0);
if (bodyPart.isMimeType("multipart/alternative")) {
getMailContent(bodyPart, bodytext);
} else if (bodyPart.isMimeType("text/plain")) {
bodytext.append(bodyPart.getContent());
}
}
}
return bodytext;
}
最后就是附件了,问题不会很大,也可以在网上找些代码来设置点击打开相对应的附件,在这里会放回文件名及文件的Map集合。
// 下载附件
public static Map<String, File> getEnFilesDownload(Message message)
throws MessagingException, IOException {
Map<String, File> files = new HashMap<>();
Multipart multipart = (Multipart) message.getContent();
for (int i = 0, n = multipart.getCount(); i < n; i++) {
Part part = multipart.getBodyPart(i);
String disposition = part.getDisposition();
if ((disposition != null)
&& ((disposition.equals(Part.ATTACHMENT) || (disposition
.equals(Part.INLINE))))) {
String fileName = part.getFileName();
if (fileName.startsWith("=?")) {
// 需要解析中文名称的文件名(将中文名称加入邮件时用encodeText)
fileName = MimeUtility.decodeText(fileName);
}
// 文件名
File file = new File(Environment.getExternalStorageDirectory()
+ "/" + fileName);
// 文件判断是否存在
if (!file.exists()) {
try {
BufferedInputStream bis = new BufferedInputStream(
part.getInputStream());
BufferedOutputStream bos;
bos = new BufferedOutputStream(new FileOutputStream(
file));
int len = -1;
while ((len = bis.read()) != -1) {
bos.write(len);
bos.flush();
}
bos.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
Log.d("--->", "下载失败");
}
}
// 直接寻找
files.put(fileName, file);
}
}
return files;
}