最近项目里有一个需求,要求在项目报错时可以发邮件到指定邮箱。这个功能不算难,但实现起来也有不少的坑。所以记录一下实现过程。
直接发送
首先明确一下直接发送的需求,这里要求的是直接在自己的App中点击发送,而不是跳转第三方的邮件App。
环境配置
这里发送邮件的实现方式是使用JavaMail for Andorid,需要用到android-mail和android-activation这两个包。
在gradle文件中加入以下配置。具体可参考https://javaee.github.io/javamail/#JavaMail_for_Android。
当然, 你也可以下载Jar包集成到项目中,这里是下载地址:https://code.google.com/archive/p/javamail-android/downloads。
Gradle文件配置:
1 | dependencies { |
这里需要注意的是,Release包下,还需要处理混淆文件,不然会导致Release包下功能失效。
在proguard-rules.pro文件中加入以下代码。
1 | -keep class javax.mail.**{*;} |
简单实现
环境配置好后,我们就可以直接在自己的App中发送邮件了。下面直接分享一下来自官网的Demo,https://javaee.github.io/javamail/docs/api/,亲测可行。
1 | Properties props = new Properties(); |
当然了,这里的参数得改成你自己的,所以做下简单说明。
首先是第2行的props.put,这里可以理解为配置邮箱类别。这里key是不用改的,直接改它的value就可以。举个例子,如果是由126邮箱发出去的,就将value改为smtp.126.com;如果是outlook邮箱发出去的,就将value改为smtp-mail.outlook.com等等。这个值直接搜索某某邮箱的smtp设置就可以得到。
接着是设置Message。顾名思义,msg.setFrom是设置发件箱,msg.setRecipients第二个参数是收件箱,msg.setSubject是邮箱标题,msg.setSentDate是邮件日期,msg.setText是邮件内容。
最后是Transport.send发送,这里需要注意最后一个参数。对于大部分类别的邮箱,这个password不是邮箱的密码,而是邮箱的授权码,具体需要网页登陆自己的邮箱获取。
这样,最简单的邮件发送就实现了。由于是一个网络耗时操作,记得在子线程中调用,就可以成功发送邮件出去了。
项目封装
当然,实际项目中不可能像Demo一样简单,需要根据自己的需要做一些封装。
首先是封装邮件的消息体。如果要使用例如outlook这种不支持SSL,只支持TLS的邮箱,一定要加上prop.put(“mail.smtp.starttls.enable”, “true”)这句配置。
1 | import java.util.Properties; |
接着是对权限的封装,也就是发件箱的账号和密码/授权码。
1 | import javax.mail.Authenticator; |
然后就是对发送方法的封装了,代码非常清晰简单,相信不用做过多解释就可以看懂。唯一要注意的就是,如果通过MimeMultipart来添加附件,会导致mailMessage.setText这个添加正文的方法无效,需要额外通过MimeBodyPart.setText来重新设置正文。
1 | import java.io.IOException; |
最后就是代码的调用了。这里的FeedbackMessage类就是封装了邮件需要传的属性的一个Bean类,可以根据自己项目的需求自己来写。
1 | import com.google.gson.Gson; |
第三方发送
在自己程序里发送邮件简单快捷,但由于之前是将发件箱定死了,每天如果发的邮件过多,发件箱可能会认为是在发垃圾邮件,会有将发件箱锁死,导致当天不能再发的风险。
所以,我们监测一下发件状态,在sendMail()方法里catch所有的exception。如果发送失败了,就跳转第三方的邮箱,并获取到发件箱,标题,正文等信息,由用户操作发送。
1 | public class MailUtils { |
总结
完毕收工!不管是在项目中直接集成邮件发送,还是跳转第三方邮件APP再发送,下次再实现起来都可以一气呵成了。