前言:
時(shí)隔5年再次在項(xiàng)目中需要遠(yuǎn)程獲取設(shè)備上的Log信息來定位程序Bug的場景,應(yīng)用程序把Log以txt文本的形式存儲到指定SD卡的目錄下咆畏,然后通過遠(yuǎn)程給指定的設(shè)備發(fā)送一條讀取Log的消息(消息里帶有接收郵件的郵箱信息)來觸發(fā)讀取設(shè)備本地記錄的Log文本信息琐脏,然后通過發(fā)送帶附件郵件的形式發(fā)送到指定的接收郵箱里攒砖,實(shí)現(xiàn)遠(yuǎn)程讀取設(shè)備Log信息。
項(xiàng)目簡介:
項(xiàng)目是一個(gè)智能輪椅項(xiàng)目:1:藍(lán)牙通信實(shí)現(xiàn)手機(jī)端遙控功能日裙;2:攝像頭獲取視頻流上傳到服務(wù)器吹艇,手機(jī)端獲取視頻流數(shù)據(jù)查看輪椅周圍的環(huán)境;3:使用騰訊實(shí)時(shí)音視頻(TRTC)實(shí)現(xiàn)視頻通話功能昂拂;4:集成思必馳(DUI)SDK實(shí)現(xiàn)語音交互功能受神;
準(zhǔn)備工作
在編碼之前首先需要在我們的AS項(xiàng)目中的build.gradle的dependencies模塊里引入發(fā)送郵箱相關(guān)的依賴庫:
// E_mail
implementation 'com.sun.mail:android-mail:1.5.5'
implementation 'com.sun.mail:android-activation:1.5.5'
然后在AndroidStudio的清單文件AndroidManifest.xml里添加網(wǎng)絡(luò)訪問權(quán)限及SD卡讀寫權(quán)限。
<!-- 網(wǎng)絡(luò)權(quán)限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SD_Card權(quán)限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
編碼
新建一個(gè)E_MailUtils.java的工具類政钟,把發(fā)送郵件的操作都放里面路克,直接上代碼:
package com.roy.www.smartbox.e_mail;
import android.os.Environment;
import android.util.Log;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
/**
* Created by Roy
* On 2021/7/17
* Email: 631934797@qq.com
* Description: 利用JavaMail的API來創(chuàng)建和發(fā)送郵件工具類
*/
public class E_MailUtils {
private static final String MAIL_SERVER = "smtp.163.com";
private static final String MAILBOX = "******@163.com";//這里替換成自己的發(fā)送郵件的郵箱地址
private static final String PASSWORD = "******";
private E_MailInfoBean mEmailInfo;
private String path;
public E_MailUtils(String path){
this.path = path;
}
/**
* 以文本格式發(fā)送郵件
* @param mailInfo 待發(fā)送的郵件信息
* @return
*/
public boolean sendTextEmail(E_MailInfoBean mailInfo){
mEmailInfo = mailInfo;
//判斷是否需要身份驗(yàn)證
Properties properties = mailInfo.getProperties();
//1、根據(jù)郵件會話屬性和密碼驗(yàn)證器構(gòu)造一個(gè)發(fā)送郵件的session
Session sendMailSession = Session.getDefaultInstance(properties);
//開啟Session的debug模式养交,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)
sendMailSession.setDebug(true);
try {
//2精算、通過session得到transport對象,以便連接郵箱并發(fā)送
Transport transport = sendMailSession.getTransport();
//3、使用郵箱的用戶名和密碼連上郵件服務(wù)器碎连,發(fā)送郵件時(shí)灰羽,發(fā)件人需要提交郵箱的用戶名和密碼給SMTP服務(wù)器,用戶名和密碼都通過驗(yàn)證之后才能夠正常發(fā)送郵件給收件人鱼辙。
transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
//4廉嚼、創(chuàng)建郵件消息
Message mailMessage = createSimpleMail(sendMailSession);
//5、發(fā)送郵件消息
transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
transport.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return false;
}
/**
* 發(fā)送內(nèi)容帶有圖片的郵件
*
* @return
*/
public boolean sendImageEmail(E_MailInfoBean mailInfo){
mEmailInfo = mailInfo;
Properties properties = mailInfo.getProperties();
//1倒戏、根據(jù)郵件會話屬性和密碼驗(yàn)證器構(gòu)造一個(gè)發(fā)送郵件的session
Session sendMailSession = Session.getDefaultInstance(properties);
//開啟Session的debug模式怠噪,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)
sendMailSession.setDebug(true);
try {
//2、通過session得到transport對象,以便連接郵箱并發(fā)送
Transport transport = sendMailSession.getTransport();
//3杜跷、使用郵箱的用戶名和密碼連上郵件服務(wù)器傍念,發(fā)送郵件時(shí)矫夷,發(fā)件人需要提交郵箱的用戶名和密碼給SMTP服務(wù)器,用戶名和密碼都通過驗(yàn)證之后才能夠正常發(fā)送郵件給收件人憋槐。
transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
//4双藕、創(chuàng)建郵件消息
Message mailMessage = createImageMail(sendMailSession);
//5、發(fā)送郵件消息
transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
transport.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 發(fā)送帶有附件的郵件
*
* @param mailInfo
* @return
*/
public boolean sendAttachmentEmail(E_MailInfoBean mailInfo, ArrayList<String> list){
mEmailInfo = mailInfo;
Properties properties = mailInfo.getProperties();
//1阳仔、根據(jù)郵件會話屬性和密碼驗(yàn)證器構(gòu)造一個(gè)發(fā)送郵件的session
Session sendMailSession = Session.getDefaultInstance(properties);
//開啟Session的debug模式忧陪,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)
sendMailSession.setDebug(true);
try {
//2、通過session得到transport對象,以便連接郵箱并發(fā)送
Transport transport = sendMailSession.getTransport();
//3近范、使用郵箱的用戶名和密碼連上郵件服務(wù)器嘶摊,發(fā)送郵件時(shí),發(fā)件人需要提交郵箱的用戶名和密碼給SMTP服務(wù)器顺又,用戶名和密碼都通過驗(yàn)證之后才能夠正常發(fā)送郵件給收件人更卒。
transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
//4等孵、創(chuàng)建郵件消息
Message mailMessage = createAttachmentMail(sendMailSession,list);
//5稚照、發(fā)送郵件消息
transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
transport.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 發(fā)送復(fù)雜郵件
* @param mailInfo
*/
public void sendMixedEmail(E_MailInfoBean mailInfo, ArrayList<String> list){
mEmailInfo = mailInfo;
Properties properties = mailInfo.getProperties();
//1、根據(jù)郵件會話屬性和密碼驗(yàn)證器構(gòu)造一個(gè)發(fā)送郵件的session
Session sendMailSession = Session.getDefaultInstance(properties);
//開啟Session的debug模式俯萌,這樣就可以查看到程序發(fā)送Email的運(yùn)行狀態(tài)
sendMailSession.setDebug(true);
try {
//2果录、通過session得到transport對象,以便連接郵箱并發(fā)送
Transport transport = sendMailSession.getTransport();
//3、使用郵箱的用戶名和密碼連上郵件服務(wù)器咐熙,發(fā)送郵件時(shí)弱恒,發(fā)件人需要提交郵箱的用戶名和密碼給SMTP服務(wù)器,用戶名和密碼都通過驗(yàn)證之后才能夠正常發(fā)送郵件給收件人棋恼。
transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
//4返弹、創(chuàng)建郵件消息
Message mailMessage = createMixedMail(sendMailSession,list);
//5、發(fā)送郵件消息
transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
transport.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 創(chuàng)建復(fù)雜的郵件(包括圖片和多附件的郵件)
* @param sendMailSession
* @param list 是選中CSV文件的集合
* @return
*/
private Message createMixedMail(Session sendMailSession,ArrayList<String> list) {
// 創(chuàng)建郵件
MimeMessage message = null;
try {
message = new MimeMessage(sendMailSession);
// 設(shè)置郵件的基本信息
//創(chuàng)建郵件發(fā)送者地址
Address from = new InternetAddress(mEmailInfo.getFromAddress());
//設(shè)置郵件消息的發(fā)送者
message.setFrom(from);
//創(chuàng)建郵件的接受者地址爪飘,并設(shè)置到郵件消息中
Address to = new InternetAddress(mEmailInfo.getToAddress());
//設(shè)置郵件消息的接受者, Message.RecipientType.TO屬性表示接收者的類型為TO
message.setRecipient(Message.RecipientType.TO, to);
//郵件標(biāo)題
message.setSubject(mEmailInfo.getSubject());
// 正文
MimeBodyPart text = new MimeBodyPart();
text.setContent(mEmailInfo.getContent(),
"text/html;charset=UTF-8");
/*// 圖片
MimeBodyPart image = new MimeBodyPart();
image.setDataHandler(new DataHandler(new FileDataSource(Environment.getExternalStorageDirectory().getPath()+"/貓咪.jpg")));
image.setContentID("貓咪.jpg");*/
// 附件1
MimeBodyPart attach = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource(Environment.getExternalStorageDirectory().getPath()+"/zed_authorize.txt"));
attach.setDataHandler(dh);
attach.setFileName(dh.getName());
// 附件2
MimeBodyPart attach2 = new MimeBodyPart();
DataHandler dh2 = new DataHandler(new FileDataSource(Environment.getExternalStorageDirectory().getPath()+"/error_log_z9.txt"));
attach2.setDataHandler(dh2);
attach2.setFileName(MimeUtility.encodeText(dh2.getName()));
/*// 描述關(guān)系:正文和圖片
MimeMultipart mp1 = new MimeMultipart();
mp1.addBodyPart(image);
mp1.setSubType("related");*/
// 描述關(guān)系:正文和附件
MimeMultipart mp2 = new MimeMultipart();
mp2.addBodyPart(text);
mp2.addBodyPart(attach);
mp2.addBodyPart(attach2);
/*// 代表正文的BodyPart
MimeBodyPart content = new MimeBodyPart();
content.setContent(mp1);
mp2.addBodyPart(content);*/
mp2.setSubType("mixed");
message.setContent(mp2);
message.saveChanges();
// 將創(chuàng)建的Email寫入到E盤存儲
//message.writeTo(new FileOutputStream("E:\\MixedMail.eml"));
} catch (Exception e) {
Log.e("TAG", "創(chuàng)建復(fù)雜郵件失敗");
e.printStackTrace();
}
// 返回創(chuàng)建好的的郵件
return message;
}
/**
* 創(chuàng)建帶有附件的郵件
* @param sendMailSession
* @param list 選中的CSV文件的集合
* @return
*/
private Message createAttachmentMail(Session sendMailSession,ArrayList<String> list) {
//創(chuàng)建郵件
MimeMessage message = null;
try {
message = new MimeMessage(sendMailSession);
// 設(shè)置郵件的基本信息
//創(chuàng)建郵件發(fā)送者地址
Address from = new InternetAddress(mEmailInfo.getFromAddress());
//設(shè)置郵件消息的發(fā)送者
message.setFrom(from);
//創(chuàng)建郵件的接受者地址义起,并設(shè)置到郵件消息中
Address to = new InternetAddress(mEmailInfo.getToAddress());
//設(shè)置郵件消息的接受者, Message.RecipientType.TO屬性表示接收者的類型為TO
message.setRecipient(Message.RecipientType.TO, to);
//郵件標(biāo)題
message.setSubject(mEmailInfo.getSubject());
// 創(chuàng)建郵件正文,為了避免郵件正文中文亂碼問題师崎,需要使用CharSet=UTF-8指明字符編碼
MimeBodyPart text = new MimeBodyPart();
text.setContent(mEmailInfo.getContent(), "text/html;charset=UTF-8");
// 創(chuàng)建容器描述數(shù)據(jù)關(guān)系
MimeMultipart mp = new MimeMultipart();
mp.addBodyPart(text);
for (int i = 0; i < list.size(); i++) {
// 創(chuàng)建郵件附件
MimeBodyPart attach = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource(path + list.get(i)));
attach.setDataHandler(dh);
attach.setFileName(MimeUtility.encodeText(dh.getName()));
mp.addBodyPart(attach);
}
mp.setSubType("mixed");
message.setContent(mp);
message.saveChanges();
// 將創(chuàng)建的Email寫入到E盤存儲
//message.writeTo(new FileOutputStream("E:\\attachMail.eml"));
} catch (Exception e) {
Log.e("TAG", "創(chuàng)建帶附件的郵件失敗");
e.printStackTrace();
}
// 返回生成的郵件
return message;
}
/**
*生成一封郵件正文帶圖片的郵件
* @param sendMailSession
* @return
*/
private MimeMessage createImageMail(Session sendMailSession) {
//創(chuàng)建郵件
MimeMessage mailMessage = null;
try {
mailMessage = new MimeMessage(sendMailSession);
// 設(shè)置郵件的基本信息
//創(chuàng)建郵件發(fā)送者地址
Address from = new InternetAddress(mEmailInfo.getFromAddress());
//設(shè)置郵件消息的發(fā)送者
mailMessage.setFrom(from);
//創(chuàng)建郵件的接受者地址默终,并設(shè)置到郵件消息中
Address to = new InternetAddress(mEmailInfo.getToAddress());
//設(shè)置郵件消息的接受者, Message.RecipientType.TO屬性表示接收者的類型為TO
mailMessage.setRecipient(Message.RecipientType.TO, to);
//郵件標(biāo)題
mailMessage.setSubject(mEmailInfo.getSubject());
// 準(zhǔn)備郵件數(shù)據(jù)
// 準(zhǔn)備郵件正文數(shù)據(jù)
MimeBodyPart text = new MimeBodyPart();
text.setContent("這是一封郵件正文帶圖片<img src='cid:xxx.jpg'>的郵件", "text/html;charset=UTF-8");
// 準(zhǔn)備圖片數(shù)據(jù)
MimeBodyPart image = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource("src\\1.jpg"));
image.setDataHandler(dh);
image.setContentID("xxx.jpg");
// 描述數(shù)據(jù)關(guān)系
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related");
mailMessage.setContent(mm);
mailMessage.saveChanges();
//將創(chuàng)建好的郵件寫入到E盤以文件的形式進(jìn)行保存
mailMessage.writeTo(new FileOutputStream("E:\\ImageMail.eml"));
//返回創(chuàng)建好的郵件
} catch (Exception e) {
Log.e("TAG", "創(chuàng)建帶有圖片的郵件消息失敗");
e.printStackTrace();
}
return mailMessage;
}
/**
* 創(chuàng)建純文本內(nèi)容的郵件消息
* @param sendMailSession
* @return
*/
public MimeMessage createSimpleMail(Session sendMailSession){
MimeMessage mailMessage = null;
try {
//根據(jù)session創(chuàng)建一條郵件信息
mailMessage = new MimeMessage(sendMailSession);
//創(chuàng)建郵件發(fā)送者地址
Address from = new InternetAddress(mEmailInfo.getFromAddress());
//設(shè)置郵件消息的發(fā)送者
mailMessage.setFrom(from);
//創(chuàng)建郵件的接受者地址,并設(shè)置到郵件消息中
Address to = new InternetAddress(mEmailInfo.getToAddress());
//設(shè)置郵件消息的接受者, Message.RecipientType.TO屬性表示接收者的類型為TO
mailMessage.setRecipient(Message.RecipientType.TO, to);
//設(shè)置郵件標(biāo)題
mailMessage.setSubject(mEmailInfo.getSubject());
//設(shè)置郵件內(nèi)容
mailMessage.setText(mEmailInfo.getContent());
//設(shè)置郵件發(fā)送的時(shí)間
mailMessage.setSentDate(new Date());
} catch (Exception e) {
Log.e("TAG", "郵件消息創(chuàng)建失敗");
e.printStackTrace();
}
return mailMessage;
}
}
再新建一個(gè)E_MailInfoBean.java的實(shí)體類犁罩,用來配置郵件配置信息齐蔽,也是直接上代碼:
package com.roy.www.smartbox.e_mail;
import java.util.Properties;
/**
* Created by Roy
* On 2021/7/17
* Email: 631934797@qq.com
* Description:
*/
public class E_MailInfoBean {
/**
* 發(fā)送郵件的服務(wù)器的IP和端口
*/
private String mailServerHost;
private String mailServerPort;
/**
* 郵件發(fā)送者的郵件地址
*/
private String fromAddress;
/**
* 郵件接受者的郵件地址
*/
private String toAddress;
/**
* 登陸郵件發(fā)送服務(wù)器的用戶名和密碼
*/
private String userName;
private String passWord;
/**
* 是否需要身份驗(yàn)證
*/
private boolean validate = false;
/**
* 郵件發(fā)送的主題
*/
private String subject;
/**
* 郵件發(fā)送的內(nèi)容
*/
private String content;
/**
* 郵件附件的文件名
*/
private String[] attachFileNames;
/**
* 獲取郵件會話屬性
* @return
*/
public Properties getProperties(){
Properties p = new Properties();
p.put("mail.smtp.host", this.mailServerHost);
p.put("mail.smtp.port", this.mailServerPort);
p.put("mail.transport.protocol", "smtp");
p.put("mail.smtp.auth", validate ? "true" : "false");
return p;
}
public String getMailServerHost() {
return mailServerHost;
}
public void setMailServerHost(String mailServerHost) {
this.mailServerHost = mailServerHost;
}
public String getMailServerPost() {
return mailServerPort;
}
public void setMailServerPost(String mailServerPost) {
this.mailServerPort = mailServerPost;
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public String getToAddress() {
return toAddress;
}
public void setToAddress(String toAddress) {
this.toAddress = toAddress;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String[] getAttachFileNames() {
return attachFileNames;
}
public void setAttachFileNames(String[] attachFileNames) {
this.attachFileNames = attachFileNames;
}
}
以上就是核心代碼,這里在再把發(fā)送郵件的代碼也給附上:
/**
* 發(fā)送郵件
*
* @param jsonResult
*/
private static void sendE_Mail( String jsonResult) {
// 先創(chuàng)建一個(gè)實(shí)體來配置郵件信息
E_MailInfoBean info = new E_MailInfoBean();
info.setMailServerHost("smtp.163.com");
info.setMailServerPost("25");
info.setValidate(true);
info.setUserName("******@163.com");//郵箱
info.setPassWord("******");//郵箱密碼
info.setFromAddress("******@163.com");//發(fā)送郵件郵箱地址
// 設(shè)置收件人郵箱(這里是從消息數(shù)據(jù)里獲取的)
info.setToAddress(GsonUtil.acceptAndStopField(jsonResult,"mailbox"));
// 設(shè)置郵件主題
info.setSubject("Smart_Box_" + BoxApplication.Device_ID + "客戶端LOG_INFO");
// 設(shè)置郵件內(nèi)容
info.setContent("Smart_Box_" + BoxApplication.Device_ID + "客戶端日志信息床估。 祥見附件含滴!");
// 獲取所有制定目錄下的所有Log文本
ArrayList<String> fileName = SDCardUtil.readAllFile(Constant.SMART_BOX_LOG_PATH);
// 這個(gè)類用來發(fā)送郵件 是否成功
boolean state = new E_MailUtils(Constant.SMART_BOX_LOG_PATH).sendAttachmentEmail(info, fileName);
Map<String, Object> map = new HashMap<>();
map.put("state", state ? "success" : "err");
map.put("device_id", BoxApplication.Device_ID);
map.put("command", GsonUtil.acceptAndStopField(jsonResult,"command") + "_ack");
map.put("protocol", GsonUtil.acceptAndStopField(jsonResult,"protocol"));
String responseMsg = GsonUtil.ObjectToString(map);
//響應(yīng)數(shù)據(jù)
BoxMqttService.publishMessage(responseMsg);
}