Android通过邮件附件的形式获取设备上的Log信息

前言:

时隔5年再次在项目中需要远程获取设备上的Log信息来定位程序Bug的场景,应用程序把Log以txt文本的形式存储到指定SD卡的目录下,然后通过远程给指定的设备发送一条读取Log的消息(消息里带有接收邮件的邮箱信息)来触发读取设备本地记录的Log文本信息,然后通过发送带附件邮件的形式发送到指定的接收邮箱里,实现远程读取设备Log信息。

项目简介:

项目是一个智能轮椅项目:1:蓝牙通信实现手机端遥控功能;2:摄像头获取视频流上传到服务器,手机端获取视频流数据查看轮椅周围的环境;3:使用腾讯实时音视频(TRTC)实现视频通话功能;4:集成思必驰(DUI)SDK实现语音交互功能;

准备工作

在编码之前首先需要在我们的AS项目中的build.gradle的dependencies模块里引入发送邮箱相关的依赖库:
    // E_mail
    implementation 'com.sun.mail:android-mail:1.5.5'
    implementation 'com.sun.mail:android-activation:1.5.5'
然后在AndroidStudio的清单文件AndroidManifest.xml里添加网络访问权限及SD卡读写权限。
    <!-- 网络权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
     <!-- SD_Card权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

编码

新建一个E_MailUtils.java的工具类,把发送邮件的操作都放里面,直接上代码:
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来创建和发送邮件工具类
 */

public class E_MailUtils {

    private static final String MAIL_SERVER = "smtp.163.com";
    private static final String MAILBOX = "******@163.com";//这里替换成自己的发送邮件的邮箱地址
    private static final String PASSWORD = "******";
    private E_MailInfoBean mEmailInfo;
    private String path;

    public E_MailUtils(String path){
        this.path = path;
    }

    /**
     * 以文本格式发送邮件
     * @param mailInfo 待发送的邮件信息
     * @return
     */
    public boolean sendTextEmail(E_MailInfoBean mailInfo){
        mEmailInfo = mailInfo;
        //判断是否需要身份验证
        Properties properties = mailInfo.getProperties();
        //1、根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession  = Session.getDefaultInstance(properties);
        //开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
        sendMailSession.setDebug(true);
        try {

            //2、通过session得到transport对象,以便连接邮箱并发送
            Transport transport = sendMailSession.getTransport();
            //3、使用邮箱的用户名和密码连上邮件服务器,发送邮件时,发件人需要提交邮箱的用户名和密码给SMTP服务器,用户名和密码都通过验证之后才能够正常发送邮件给收件人。
            transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
            //4、创建邮件消息
            Message mailMessage = createSimpleMail(sendMailSession);
            //5、发送邮件消息
            transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 发送内容带有图片的邮件
     *
     * @return
     */
    public boolean sendImageEmail(E_MailInfoBean mailInfo){
        mEmailInfo = mailInfo;
        Properties properties = mailInfo.getProperties();
        //1、根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession  = Session.getDefaultInstance(properties);
        //开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
        sendMailSession.setDebug(true);
        try {

            //2、通过session得到transport对象,以便连接邮箱并发送
            Transport transport = sendMailSession.getTransport();
            //3、使用邮箱的用户名和密码连上邮件服务器,发送邮件时,发件人需要提交邮箱的用户名和密码给SMTP服务器,用户名和密码都通过验证之后才能够正常发送邮件给收件人。
            transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
            //4、创建邮件消息
            Message mailMessage = createImageMail(sendMailSession);
            //5、发送邮件消息
            transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }
    /**
     * 发送带有附件的邮件
     *
     * @param mailInfo
     * @return
     */
    public boolean sendAttachmentEmail(E_MailInfoBean mailInfo, ArrayList<String> list){
        mEmailInfo = mailInfo;
        Properties properties = mailInfo.getProperties();
        //1、根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession  = Session.getDefaultInstance(properties);
        //开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
        sendMailSession.setDebug(true);
        try {
            //2、通过session得到transport对象,以便连接邮箱并发送
            Transport transport = sendMailSession.getTransport();
            //3、使用邮箱的用户名和密码连上邮件服务器,发送邮件时,发件人需要提交邮箱的用户名和密码给SMTP服务器,用户名和密码都通过验证之后才能够正常发送邮件给收件人。
            transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
            //4、创建邮件消息
            Message mailMessage = createAttachmentMail(sendMailSession,list);
            //5、发送邮件消息
            transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 发送复杂邮件
     * @param mailInfo
     */
    public void sendMixedEmail(E_MailInfoBean mailInfo, ArrayList<String> list){

        mEmailInfo = mailInfo;
        Properties properties = mailInfo.getProperties();
        //1、根据邮件会话属性和密码验证器构造一个发送邮件的session
        Session sendMailSession  = Session.getDefaultInstance(properties);
        //开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
        sendMailSession.setDebug(true);
        try {
            //2、通过session得到transport对象,以便连接邮箱并发送
            Transport transport = sendMailSession.getTransport();
            //3、使用邮箱的用户名和密码连上邮件服务器,发送邮件时,发件人需要提交邮箱的用户名和密码给SMTP服务器,用户名和密码都通过验证之后才能够正常发送邮件给收件人。
            transport.connect(MAIL_SERVER, MAILBOX, PASSWORD );
            //4、创建邮件消息
            Message mailMessage = createMixedMail(sendMailSession,list);
            //5、发送邮件消息
            transport.sendMessage(mailMessage, mailMessage.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建复杂的邮件(包括图片和多附件的邮件)
     * @param sendMailSession
     * @param list 是选中CSV文件的集合
     * @return
     */
    private Message createMixedMail(Session sendMailSession,ArrayList<String> list) {
        // 创建邮件
        MimeMessage message = null;
        try {
            message = new MimeMessage(sendMailSession);

            // 设置邮件的基本信息
            //创建邮件发送者地址
            Address from = new InternetAddress(mEmailInfo.getFromAddress());
            //设置邮件消息的发送者
            message.setFrom(from);
            //创建邮件的接受者地址,并设置到邮件消息中
            Address to = new InternetAddress(mEmailInfo.getToAddress());
            //设置邮件消息的接受者, Message.RecipientType.TO属性表示接收者的类型为TO
            message.setRecipient(Message.RecipientType.TO, to);
            //邮件标题
            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()));

            /*// 描述关系:正文和图片
            MimeMultipart mp1 = new MimeMultipart();
            mp1.addBodyPart(image);
            mp1.setSubType("related");*/

            // 描述关系:正文和附件
            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();

            // 将创建的Email写入到E盘存储
            //message.writeTo(new FileOutputStream("E:\\MixedMail.eml"));
        } catch (Exception e) {
            Log.e("TAG", "创建复杂邮件失败");
            e.printStackTrace();
        }
        // 返回创建好的的邮件
        return message;

    }
    /**
     * 创建带有附件的邮件
     * @param sendMailSession
     * @param list 选中的CSV文件的集合
     * @return
     */
    private Message createAttachmentMail(Session sendMailSession,ArrayList<String> list) {
        //创建邮件
        MimeMessage message = null;
        try {
            message = new MimeMessage(sendMailSession);
            // 设置邮件的基本信息
            //创建邮件发送者地址
            Address from = new InternetAddress(mEmailInfo.getFromAddress());
            //设置邮件消息的发送者
            message.setFrom(from);
            //创建邮件的接受者地址,并设置到邮件消息中
            Address to = new InternetAddress(mEmailInfo.getToAddress());
            //设置邮件消息的接受者, Message.RecipientType.TO属性表示接收者的类型为TO
            message.setRecipient(Message.RecipientType.TO, to);
            //邮件标题
            message.setSubject(mEmailInfo.getSubject());

            // 创建邮件正文,为了避免邮件正文中文乱码问题,需要使用CharSet=UTF-8指明字符编码
            MimeBodyPart text = new MimeBodyPart();
            text.setContent(mEmailInfo.getContent(), "text/html;charset=UTF-8");

            // 创建容器描述数据关系
            MimeMultipart mp = new MimeMultipart();
            mp.addBodyPart(text);
            for (int i = 0; i < list.size(); i++) {
                // 创建邮件附件
                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();
            // 将创建的Email写入到E盘存储
            //message.writeTo(new FileOutputStream("E:\\attachMail.eml"));
        } catch (Exception e) {
            Log.e("TAG", "创建带附件的邮件失败");
            e.printStackTrace();
        }
        // 返回生成的邮件
        return message;
    }
    /**
     *生成一封邮件正文带图片的邮件
     * @param sendMailSession
     * @return
     */
    private MimeMessage createImageMail(Session sendMailSession) {
        //创建邮件
        MimeMessage mailMessage = null;
        try {
            mailMessage = new MimeMessage(sendMailSession);
            // 设置邮件的基本信息
            //创建邮件发送者地址
            Address from = new InternetAddress(mEmailInfo.getFromAddress());
            //设置邮件消息的发送者
            mailMessage.setFrom(from);
            //创建邮件的接受者地址,并设置到邮件消息中
            Address to = new InternetAddress(mEmailInfo.getToAddress());
            //设置邮件消息的接受者, Message.RecipientType.TO属性表示接收者的类型为TO
            mailMessage.setRecipient(Message.RecipientType.TO, to);
            //邮件标题
            mailMessage.setSubject(mEmailInfo.getSubject());
            // 准备邮件数据
            // 准备邮件正文数据
            MimeBodyPart text = new MimeBodyPart();
            text.setContent("这是一封邮件正文带图片<img src='cid:xxx.jpg'>的邮件", "text/html;charset=UTF-8");
            // 准备图片数据
            MimeBodyPart image = new MimeBodyPart();
            DataHandler dh = new DataHandler(new FileDataSource("src\\1.jpg"));
            image.setDataHandler(dh);
            image.setContentID("xxx.jpg");
            // 描述数据关系
            MimeMultipart mm = new MimeMultipart();
            mm.addBodyPart(text);
            mm.addBodyPart(image);
            mm.setSubType("related");
            mailMessage.setContent(mm);
            mailMessage.saveChanges();
            //将创建好的邮件写入到E盘以文件的形式进行保存
            mailMessage.writeTo(new FileOutputStream("E:\\ImageMail.eml"));
            //返回创建好的邮件
        } catch (Exception e) {
            Log.e("TAG", "创建带有图片的邮件消息失败");
            e.printStackTrace();
        }
        return mailMessage;
    }
    /**
     * 创建纯文本内容的邮件消息
     * @param sendMailSession
     * @return
     */
    public MimeMessage createSimpleMail(Session sendMailSession){
        MimeMessage mailMessage = null;
        try {
            //根据session创建一条邮件信息
            mailMessage = new MimeMessage(sendMailSession);
            //创建邮件发送者地址
            Address from = new InternetAddress(mEmailInfo.getFromAddress());
            //设置邮件消息的发送者
            mailMessage.setFrom(from);
            //创建邮件的接受者地址,并设置到邮件消息中
            Address to = new InternetAddress(mEmailInfo.getToAddress());
            //设置邮件消息的接受者, Message.RecipientType.TO属性表示接收者的类型为TO
            mailMessage.setRecipient(Message.RecipientType.TO, to);
            //设置邮件标题
            mailMessage.setSubject(mEmailInfo.getSubject());
            //设置邮件内容
            mailMessage.setText(mEmailInfo.getContent());
            //设置邮件发送的时间
            mailMessage.setSentDate(new Date());
        } catch (Exception e) {
            Log.e("TAG", "邮件消息创建失败");
            e.printStackTrace();
        }
        return mailMessage;
    }
}
再新建一个E_MailInfoBean.java的实体类,用来配置邮件配置信息,也是直接上代码:
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 {
    /**
     * 发送邮件的服务器的IP和端口
     */
    private String mailServerHost;
    private String mailServerPort;
    /**
     * 邮件发送者的邮件地址
     */
    private String fromAddress;
    /**
     * 邮件接受者的邮件地址
     */
    private String toAddress;
    /**
     * 登陆邮件发送服务器的用户名和密码
     */
    private String userName;
    private String passWord;
    /**
     * 是否需要身份验证
     */
    private boolean validate = false;
    /**
     * 邮件发送的主题
     */
    private String subject;
    /**
     * 邮件发送的内容
     */
    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;
    }
}
以上就是核心代码,这里在再把发送邮件的代码也给附上:
/**
     *  发送邮件
     *
     * @param jsonResult
     */
    private static void sendE_Mail( String jsonResult) {
        // 先创建一个实体来配置邮件信息
        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");//发送邮件邮箱地址
        // 设置收件人邮箱(这里是从消息数据里获取的)
        info.setToAddress(GsonUtil.acceptAndStopField(jsonResult,"mailbox"));
        // 设置邮件主题
        info.setSubject("Smart_Box_" + BoxApplication.Device_ID + "客户端LOG_INFO");
        // 设置邮件内容
        info.setContent("Smart_Box_" + BoxApplication.Device_ID + "客户端日志信息。 祥见附件!");
        // 获取所有制定目录下的所有Log文本
        ArrayList<String> fileName = SDCardUtil.readAllFile(Constant.SMART_BOX_LOG_PATH);
        // 这个类用来发送邮件 是否成功
        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);
        //响应数据
        BoxMqttService.publishMessage(responseMsg);
    }

以上就是使用android-mail发送邮件给指定接收邮箱的核心代码;

注:用来发送邮件的邮箱需要开启相关的服务,这里就自行百度设置一下即可;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容