Android中Java发送带附件邮件触发UnsupportedDataTypeException错误
问题
在Android中通过Java的AsyncTask实现发送带附件的邮件,fileName是通过context.openFileOutput保存的文件路径。运行时触发致命异常,错误信息为javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed。已尝试使用com.sun.mail:android-mail:1.6.7、com.sun.mail:android-activation:1.6.7以及com.sun.mail:jakarta.mail:2.0.1依赖包,相同代码在Windows PC端Java环境可正常运行。测试发现只要添加附件(无论文件还是JSON格式内容)就报错,不添加附件则可正常发送邮件,求解决方法。
代码示例
Properties props = new Properties(); props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.port", "587"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); Session session = Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("youknow@gmail.com", "psw"); } }); Message message = new MimeMessage(session); try { message.setFrom(new InternetAddress("youknow@gmail.com@gmail.com")); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("receiver@gmail.com")); message.setSubject("Subject line"); message.setText("Email content"); MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText("test"); MimeBodyPart attachmentBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(fileName); attachmentBodyPart.setDataHandler(new DataHandler(source)); attachmentBodyPart.setFileName(source.getName()); MimeMultipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(attachmentBodyPart); message.setContent(multipart); Transport.send(message); } catch (MessagingException ex) { throw new RuntimeException(ex); }
错误日志
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 Process: com.gattolfo.gestionaluber, PID: 6179 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$4.done(AsyncTask.java:415) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383) at java.util.concurrent.FutureTask.setException(FutureTask.java:252) at java.util.concurrent.FutureTask.run(FutureTask.java:271) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923) Caused by: java.lang.RuntimeException: javax.mail.MessagingException: IOException while sending message; nested exception is: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed; boundary="----=_Part_0_82827468.1680314088984" at com.gattolfo.gestionaluber.DataManager.DbRappresentation.Registri.MailSender.sendMailInstant(MailSender.java:296) at com.gattolfo.gestionaluber.DataManager.DbRappresentation.Registri.MailSender.doInBackground(MailSender.java:141) at com.gattolfo.gestionaluber.DataManager.DbRappresentation.Registri.MailSender.doInBackground(MailSender.java:48) at android.os.AsyncTask$3.call(AsyncTask.java:394) at java.util.concurrent.FutureTask.run(FutureTask.java:266) ... 4 more Caused by: javax.mail.MessagingException: IOException while sending message; nested exception is: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed; boundary="----=_Part_0_82827468.1680314088984" at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1350) at javax.mail.Transport.send0(Transport.java:231) at javax.mail.Transport.send(Transport.java:100) at com.gattolfo.gestionaluber.DataManager.DbRappresentation.Registri.MailSender.sendMailInstant(MailSender.java:292) ... 8 more Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed; boundary="----=_Part_0_82827468.1680314088984" at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:878) at javax.activation.DataHandler.writeTo(DataHandler.java:300) at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1670) at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1889) at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1300) ... 11 more
解决方案
这个问题是Android环境中JavaMail的DataContentHandler(DCH)未正确注册导致的——Android的类加载机制和PC端不同,默认不会自动加载Multipart类型的处理器,手动注册即可解决。
方法一:手动注册核心DCH类
在发送邮件的代码前,添加以下注册逻辑,强制加载对应MIME类型的处理器:
try { // 注册multipart/mixed类型处理器 Class.forName("com.sun.mail.handlers.multipart_mixed"); // 注册文本内容处理器(确保正文正常解析) Class.forName("com.sun.mail.handlers.text_plain"); // 注册二进制文件处理器(处理附件) Class.forName("com.sun.mail.handlers.application_octet_stream"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
方法二:通过Activation框架手动绑定处理器
如果方法一无效,直接通过Activation的API指定MIME类型对应的处理器:
import javax.activation.DataHandler; import javax.activation.DataContentHandlerFactory; import com.sun.mail.handlers.multipart_mixed; // 这段代码放在Session初始化之前执行 DataHandler.setDataContentHandlerFactory(new DataContentHandlerFactory() { @Override public DataContentHandler createDataContentHandler(String mimeType) { if ("multipart/mixed".equals(mimeType)) { return new multipart_mixed(); } // 可根据需要添加其他MIME类型的处理器,比如application/json return null; } });
方法三:检查并修正依赖配置
确保使用Android专用的JavaMail依赖,不要混用Jakarta Mail和旧版包,保持版本一致:
dependencies { implementation 'com.sun.mail:android-mail:1.6.7' implementation 'com.sun.mail:android-activation:1.6.7' }
额外注意事项
- 确保邮件发送逻辑在AsyncTask的
doInBackground方法中执行,不要在主线程操作; - 添加附件前检查文件是否存在、是否有读取权限:
File attachmentFile = new File(fileName); if (!attachmentFile.exists() || !attachmentFile.canRead()) { throw new RuntimeException("附件文件不存在或无读取权限:" + fileName); }
内容的提问来源于stack exchange,提问作者Amedeo Braggio
相关产品推荐
相关产品推荐

