由于Android自身不带javamail的jar包,仅仅为了实现一个发邮件功能而引用那么多jar包划不来,
所以通过socket通信用命令行的方式来发邮件。
一个方法即可搞定!
public static boolean sendEmail(String senderEmail, String receiverEmail, String username, String pwd,
String subject, String content) {
boolean isSend = false;
//验证参数
if (senderEmail == null || receiverEmail == null || username == null || pwd == null || subject == null
|| content == null) {
throw new NullPointerException("params can not be null!...........");
}
//验证邮箱
Pattern pattern = Pattern.compile("[//w//.//-]+@([//w//-]+//.)+[//w//-]+", Pattern.CASE_INSENSITIVE);
if (!Utility.RegexMatcher(senderEmail, pattern) || !Utility.RegexMatcher(receiverEmail, pattern)) {
throw new IllegalArgumentException("email format error!.............");
}
Socket sc = null;
InputStream is = null;
OutputStream os = null;
String smtpServer = "smtp." + senderEmail.substring(senderEmail.indexOf("@") + 1, senderEmail.length());// 邮件服务器地址
final String END_TAG = "/r/n";
StringBuffer request = new StringBuffer();
StringBuffer response = new StringBuffer();
Constants.log("smtpServer:" + smtpServer);
try {
sc = new Socket(InetAddress.getByName(smtpServer), 25);
sc.setSoTimeout(30000);//设置超时
is = sc.getInputStream();
os = sc.getOutputStream();
response = response.replace(0, response.length(), transStreamToString(is, 4096));//读取服务器返回数据
Constants.log("<<<" + response);//打印log
if (response.indexOf("220") >= 0) {// 连接smtp服务器成功!
// 打招呼
request.replace(0, request.length(), "ehlo ")
.append(senderEmail.substring(0, senderEmail.indexOf("@"))).append(END_TAG);//发送命令到服务器
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
if (response.indexOf("250") >= 0) {// 打招呼成功!
// 使用login方式登录
request.replace(0, request.length(), "auth login/r/n");
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
// 输入BASE64编码的用户名
request.replace(0, request.length(), username).append(END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
// 输入BASE64编码的密码
request.replace(0, request.length(), pwd).append(END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
if (response.indexOf("235") >= 0) {// 登录成功
// 填写发件人
request.replace(0, request.length(), "mail from:<").append(senderEmail).append(">").append(
END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
if (response.indexOf("250") >= 0) {// 发件人被smtp服务器接受
// 填写收件人
request.replace(0, request.length(), "rcpt to:<").append(receiverEmail).append(">").append(
END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
if (response.indexOf("250") >= 0) {// 收件人被smtp服务器接受
// 开始写邮件
request.replace(0, request.length(), "data").append(END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
// 写邮件发件人
request.replace(0, request.length(), "from:").append(senderEmail).append(END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
// 写邮件收件人
request.replace(0, request.length(), "to:").append(receiverEmail).append(END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
// 写邮件主题
request.replace(0, request.length(), "subject:").append(subject).append(END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
// 写邮件正文
request.replace(0, request.length(), END_TAG).append(content).append(END_TAG).append(
".").append(END_TAG);
Constants.log(">>>" + request);
os.write(request.toString().getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
if (response.indexOf("250") >= 0) {// 发送成功
isSend = true;
}
// 退出
os.write("quit/r/n".getBytes());
response = response.replace(0, response.length(), transStreamToString(is, 4096));
Constants.log("<<<" + response);
request.delete(0, request.length());
response.delete(0, response.length());
os.close();
os = null;
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (sc != null) {
try {
sc.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return isSend;
}
//将输入流转换成字符串
public static String transStreamToString(InputStream is, int maxSize) {
if (is == null) {
throw new NullPointerException("inPutStream can not be null!............");
}
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize can not less than zero.....");
}
String data = null;
byte[] buffer = new byte[maxSize];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
int actualSize = is.read(buffer);
baos.write(buffer, 0, actualSize);
data = new String(baos.toByteArray());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return data;
}
log输出:
06-21 10:52:29.935: INFO/System.out(1453): smtpServer:smtp.3g2win.com
06-21 10:52:29.955: INFO/System.out(1453): <<<220 3g2win.com ESMTP MDaemon 10.1.1; Wed, 22 Jun 2011 10:52:39 +0800
06-21 10:52:29.955: INFO/System.out(1453): >>>ehlo j2metest
06-21 10:52:29.965: INFO/System.out(1453): <<<250-3g2win.com Hello j2metest, pleased to meet you
06-21 10:52:29.965: INFO/System.out(1453): 250-ETRN
06-21 10:52:29.965: INFO/System.out(1453): 250-AUTH=LOGIN
06-21 10:52:29.965: INFO/System.out(1453): 250-AUTH LOGIN CRAM-MD5
06-21 10:52:29.965: INFO/System.out(1453): 250-8BITMIME
06-21 10:52:29.965: INFO/System.out(1453): 250 SIZE
06-21 10:52:29.965: INFO/System.out(1453): >>>auth login
06-21 10:52:29.965: INFO/System.out(1453): <<<334 VXNlcm5hbWU6
06-21 10:52:29.965: INFO/System.out(1453): >>>ajJtZXRlc3Q=
06-21 10:52:29.975: INFO/System.out(1453): <<<334 UGFzc3dvcmQ6
06-21 10:52:29.975: INFO/System.out(1453): >>>M2cyd2luLmNvbQ==
06-21 10:52:29.975: INFO/System.out(1453): <<<235 Authentication successful
06-21 10:52:29.975: INFO/System.out(1453): >>>mail from:<j2metest@3g2win.com>
06-21 10:52:29.975: INFO/System.out(1453): <<<250 <j2metest@3g2win.com>, Sender ok
06-21 10:52:29.975: INFO/System.out(1453): >>>rcpt to:<workwonder@163.com>
06-21 10:52:29.985: INFO/System.out(1453): <<<250 <workwonder@163.com>, Recipient ok
06-21 10:52:29.985: INFO/System.out(1453): >>>data
06-21 10:52:29.995: INFO/System.out(1453): <<<354 Enter mail, end with <CRLF>.<CRLF>
06-21 10:52:29.995: INFO/System.out(1453): >>>from:j2metest@3g2win.com
06-21 10:52:29.995: INFO/System.out(1453): >>>to:workwonder@163.com
06-21 10:52:29.995: INFO/System.out(1453): >>>subject:android email subject
06-21 10:52:29.995: INFO/System.out(1453): >>>
06-21 10:52:29.995: INFO/System.out(1453): this for test android mail function!
06-21 10:52:29.995: INFO/System.out(1453): .
06-21 10:52:30.145: INFO/System.out(1453): <<<250 Ok, message saved <Message-ID: >
06-21 10:52:30.175: INFO/System.out(1453): <<<221 See ya in cyberspace
最后在WIFI,联通3G,联通2G网络情况下都测试通过,没有在移动的SIM卡下测试,有兴趣的同学可以试试。
值得注意的是由于与服务器的交互是问答式的,所以读取服务器返回数据的时候不能一下子读到结尾,我那一下子读4096是估计的,因为一般服务器返回的数据量都挺少的,4096足够了。1024也行。反正就是不能通过判断是否读到了流的结尾(-1)来退出读取,这样会造成阻塞。最主要的是解析读取的内容的返回码(是否包含期望的返回码)来判断交互状态来控制执行步骤。