关于android邮件的收发(第二弹)

前面说完发邮件,现在开始收邮件了。

对不同的协议来进行不同的处理,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;
	}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值