超简单的Android邮件开源库
前言
今年上半年自己在独立写软件的过程中,遇到需要通过验证码来验证用户身份的问题,这样就需要通过短信或邮件来发送验证码,当时了解到的方案是:一、接入提供短信和邮件发送服务的第三方平台(需要付费购买相应的服务)。二、调用Android系统的Mail app(需要用户已登录了自己的邮箱)。三、使用JavaMail来实现邮件发送功能。最后使用第三种方案,当时觉得使用这个方法不错,但是直接使用JavaMail的API感觉有点繁琐。所以下半年利用暑假和课余时间对JavaMail的API进行适度的封装,写成一个开源库,项目的github仓库:Email
电子邮件协议
在介绍该开源库时,先来了解一下和邮件相关的协议。常用的电子邮件协议有SMTP、POP3、IMAP4,它们都隶属于TCP/IP协议簇,默认状态下,分别通过TCP端口25、110和143建立连接。
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。通过SMTP协议所指定的服务器,就可以把E-mail寄到收信人的服务器上了。
POP3全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。
Email for Android
Email for Android 是基于JavaMail封装的电子邮件库,简化在Android客户端中编写发送和接收电子邮件的代码。把它集成到你的Android项目中,只需简单配置邮件服务器,即可使用,所见即所得哦!
集成
步骤一,将JitPack存储库添加到根目录的build.gradle中:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
步骤二,在项目的app模块下的build.gradle里加:
dependencies {
implementation 'com.github.mailhu:email:2.3.2'
}
同时记得在Android项目中的AndroidManifest.xml文件中添加联网权限。
<uses-permission android:name="android.permission.INTERNET"/>
使用
在使用该库前先简单介绍一下 Email for Android 2.3.2 中四个核心的类和相关的方法。
EmailConfig 类
- setAccount( ):设置发信人的邮箱(必写)
- setPassword( ) :设置发信人的邮箱密码或授权码(必写)
- setSmtpHost( ):设置SMTP服务器地址(发送邮件时必写)
- setSmtpPort( ):设置SMTP服务器端口(发送邮件时必写)
- setPopHost( ):设置POP服务器地址(接收邮件时必写)
- setPopPort( ):设置POP服务器端口(接收邮件时必写)
- setImapHost:设置IMAP服务器地址(接收邮件时必写)
- setImapPort:设置IMAP服务器端口(接收邮件时必写)
EmailSendClient 类
- setTo( ):设置收信人邮箱(必写)
- setCc( ):设置抄送人
- setBcc( ):设置密送人
- setNickname( ):设置发信人昵称
- setSubject( ):设置邮件主题(必写)
- setText( ):设置文本型的邮件内容(必写,但 setText( ) 和 setContent( ) 只能二选一)
- setContent( ):设置HTML型的邮件内容(同上)
- sendAsyn( ):异步发送邮件(必写)
EmailReceiveClient 类
- popReceiveAsyn( ):使用POP3协议异步接收邮件
- imapReceiveAsyn( ):使用IMAP协议异步接收邮件
EmailExamine 类
- connectServer( ):检查邮件服务器配置的方法
下面开始讲解使用方法,保证很简单!新建一个项目,在布局文件添加一个按钮控件,这个按钮用于测试邮件的发送,接收,验证等功能,然后在MainActivity中写上相关的代码,但是关于授权码获取将在本文末讲解。
下列为发送邮件的代码示例
package com.example.demo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.smailnet.eamil.Callback.GetSendCallback;
import com.smailnet.eamil.EmailConfig;
import com.smailnet.eamil.EmailSendClient;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//测试按钮
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMailTest(); //发送一封电子邮件
}
});
}
private void sendMailTest(){
//配置邮件服务器
EmailConfig config = new EmailConfig()
.setSmtpHost("smtp.exmail.qq.com") //设置发件服务器地址
.setSmtpPort(465) //设置发件服务器端口
.setAccount("code-noreply@smailnet.com") //你的邮箱地址
.setPassword("******"); //你的邮箱密码或授权码
//邮件发送,确保配置emailConfig的信息正确
EmailSendClient emailSendClient = new EmailSendClient(config);
emailSendClient
.setTo("zguanhu@foxmail.com") //收件人的邮箱地址
.setNickname("百年小糊涂") //设置发信人的昵称
.setSubject("这是一封测试邮件") //邮件主题
.setText("Hello World !") //邮件正文,若是发送HTML类型的正文用setContent()
.sendAsyn(this, new GetSendCallback() {
@Override
public void sendSuccess() {
Toast.makeText(MainActivity.this, "发送成功", Toast.LENGTH_SHORT).show();
}
@Override
public void sendFailure(String errorMsg) {
Toast.makeText(MainActivity.this, "发送失败 " + errorMsg , Toast.LENGTH_SHORT).show();
}
});
}
}
以上主要代码中先要创建一个 EmailConfig 的实例,然后设置SMTP服务器地址和SMTP服务器端口,再设置发信人邮箱和授权码等参数。再创建一个 EmailSendClient 对象,同时传入参数config,接着设置收件人的邮箱,发信人的昵称,邮件主题,邮件正文等内容,最后调用sendAsyn( )方法即可发送一封邮件。发送完毕后,我登录收件人的邮箱查看一下邮件,“卧槽,可以!”,测试的邮件截图如下:
上面已经讲解了邮件发送的方法,接下来再讲一下使用POP协议接收邮件的方法,EmailConfig类的使用和上面提到的用法差不多,只不过接收邮件就需要使用到 EmailReceiveClient 类了。
下列为接收邮件的代码示例
package com.example.demo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.smailnet.eamil.Callback.GetReceiveCallback;
import com.smailnet.eamil.EmailConfig;
import com.smailnet.eamil.EmailMessage;
import com.smailnet.eamil.EmailReceiveClient;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//测试按钮
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
rceiveMailTest(); //获取电子邮件
}
});
}
private void rceiveMailTest(){
//配置邮件服务器
EmailConfig config = new EmailConfig()
.setPopHost("pop.qq.com") //设置收件服务器地址,网易邮箱为pop.163.com
.setPopPort(995) //设置收件服务器端口,网易邮箱为110
.setAccount("zguanhu@foxmail.com") //你的邮箱地址
.setPassword("******"); //你的邮箱密码或授权码
//获取邮件,确保配置emailConfig的信息正确
EmailReceiveClient emailReceiveClient = new EmailReceiveClient(config);
emailReceiveClient.popReceiveAsyn(this, new GetReceiveCallback() {
@Override
public void gainSuccess(List<EmailMessage> messageList, int i) {
//获取邮件成功(这里可更新UI)
Log.d("oversee", "接收到的邮件如下:"); //打印倒数第二封邮件
Log.d("oversee", "发信人:" + messageList.get(1).getFrom());
Log.d("oversee", "收信人:" + messageList.get(1).getTo());
Log.d("oversee", "收信时间:" + messageList.get(1).getDate());
Log.d("oversee", "邮件主题:" + messageList.get(1).getSubject());
Log.d("oversee", "邮件内容:" + messageList.get(1).getContent());
}
@Override
public void gainFailure(String errorMsg) {
//获取邮件失败,errorMsg是错误信息(这里可更新UI)
Log.d("oversee", "错误信息:" + errorMsg);
}
});
}
}
以上代码创建一个EmailReceiveClient实例,然后使用popReceiveAsyn( )方法即可获取到邮箱中的电子邮件。不过获取邮件时会历遍邮箱中的所有邮件,当邮箱中的邮件数量过多,这种操作会十分耗时,而且获取到的邮件内容有时解析不出来,出现“com.sun.mail.util.BASE64DecoderStream@fe6004c”的异常,所以EmailReceiveClient类还有待完善。现在看看这段代码运行的结果,如下图:
日常我们使用的电子邮件客户端时,都是需要输入邮箱地址和密码,有时候还要配置一下邮箱服务器的地址和端口,然后点击登录时,用户输入这些信息会传到邮箱服务器上验证,判断用户信息是否正确,若正确则客户端这边的登录界面就会跳转到邮箱的主界面。这个功能在 Email for Android 中也有提供相应的方法。
邮箱登录验证的代码示例
package com.example.demo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.smailnet.eamil.Callback.GetConnectCallback;
import com.smailnet.eamil.EmailConfig;
import com.smailnet.eamil.EmailExamine;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//测试按钮
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginTest(); //登录验证
}
});
}
private void loginTest(){
//配置邮件服务器
EmailConfig config = new EmailConfig()
.setSmtpHost("smtp.qq.com") //设置发件服务器地址
.setSmtpPort(465) //设置发件服务器端口
.setPopHost("pop.qq.com") //设置收件服务器地址
.setPopPort(995) //设置收件服务器端口
.setAccount("zguanhu@foxmail.com") //你的邮箱地址
.setPassword("******"); //你的邮箱密码或授权码
//验证邮箱和检查邮件服务器
EmailExamine emailExamine = new EmailExamine(config);
emailExamine.connectServer(new GetConnectCallback() {
@Override
public void loginSuccess() {
Log.d("oversee", "登录成功");
}
@Override
public void loginFailure(String errorMsg) {
Log.d("oversee", "登录失败" + errorMsg);
}
});
}
}
以上代码应该很简单了,写法和前面提到的发送邮件或接收邮件的代码写法差不多,接下来看看效果图,如下:
设置
若你使用QQ邮箱发送邮件,请在邮箱账户中开启 POP/SMTP服务 等权限,同时为了确保你的QQ帐号安全,你应该使用 授权码 进行第三方邮箱登录,这样可防止QQ密码泄漏。设置教程:登录QQ邮箱网页版,进入【设置】-【帐户】,把下列服务开启,然后获取授权码。如下图:
结语
JavaMail是Sun发布的用来处理E-mail的API,它可以方便地执行一些常用的邮件传输。当我在Android端开发中使用到JavaMail时感觉代码复杂繁琐,而且在网上搜索了一圈关于在Android使用JavaMaild的教程,都是直接贴源码,质量参差不齐,所以我在使用的过程中顺便对JavaMial的API进行适度的封装,让其在Android端更简单易用,最后写出该开源库——Eamil。在封装的过程也遇到了很多问题,有些问题后来慢慢解决了,有些问题因目前我知识水平有限,实在无法解决,Email for Android 2.3.2 该有的基本功能都有了,接下来我会继续慢慢地完善它,让它更简单易用。但是发送邮件验证码的功能不建议放在客户端中完成,应该交给后台完成,除非是迫不得已才在客户端中这样做。感谢您的阅读,谢谢。