专栏首页Open软件开发小组Android后台发送邮件进行日志反馈

Android后台发送邮件进行日志反馈

概要

最近在和解决用户反馈的问题,但是出现了不方便的事情.就是获取用户操作日志的问题.想来想去还是用比较隐晦的方法---发送邮件.(需要告知用户,不然会当成流氓的!)

发送邮件分为两种:

  1. 调用系统的发邮件功能发送邮件
  2. 使用特定的邮箱密码发送邮件

第一种需要用户登陆邮箱,有的用户可能还没有邮箱,不是很方便.所以采用第二种方法:

在APP内部埋好邮箱,密码给特定的邮箱发送邮件附件添加日志.

发送说明

发送基础

这里要使用JavaMail的三个jar包:

  1. activation.jar
  2. additionnal.jar
  3. mail.jar

发送流程

  1. 设置发送服务器
  2. 设置发送账户和密码
  3. 设置发送显示的名称,主题,内容和附件
  4. 设置接收者地址
  5. 发送邮件给接收者

发送实现

权限

发送带有附件的邮件,需要联网权限和读写SD卡权限,需要在Android Manifest.xml文件添加已下权限:

<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

设置发送信息

以下以163邮箱为例,需要提前在163邮箱设置里面开启smtp.

设置需要的常量

//发送账户private static final String SENDER_NAME = "xxxxx@163.com";//发送账户的密码private static final String SENDER_PASS = "xxxxx";//邮箱服务器private static final String VALUE_MAIL_HOST = "smtp.163.com";//邮箱服务器主机private static final String KEY_MAIL_HOST = "mail.smtp.host";//邮箱是否需要鉴权private static final String KEY_MAIL_AUTH = "mail.smtp.auth";//需要鉴权private static final String VALUE_MAIL_AUTH = "true";

设置发送的属性

Properties properties = System.getProperties();
properties.put(KEY_MAIL_HOST, VALUE_MAIL_HOST);
properties.put(KEY_MAIL_AUTH, VALUE_MAIL_AUTH);

获取Session

Session session = Session.getInstance(properties, getAuthenticator());
private Authenticator getAuthenticator() {    return new Authenticator(){        @Override
       protected PasswordAuthentication getPasswordAuthentication() {            return new PasswordAuthentication(SENDER_NAME, SENDER_PASS);
       }
   };
}

构建邮件消息

//创建消息MimeMessage mimeMessage = new MimeMessage(session);
try {    //设置发送者
   mimeMessage.setFrom(new InternetAddress(SENDER_NAME));    //设置接收者
   InternetAddress[] addresses = new InternetAddress[]{new InternetAddress(SENDER_NAME)};
   mimeMessage.setRecipients(Message.RecipientType.TO, addresses);    //设置邮件的主题
   mimeMessage.setSubject(title);    //设置邮件的内容
   MimeBodyPart textPart = new MimeBodyPart();
   textPart.setContent(content, "text/html");
   Multipart multipart = new MimeMultipart();
   multipart.addBodyPart(textPart);
   mimeMessage.setContent(multipart);    //设置发送时间
   mimeMessage.setSentDate(new Date());
} catch (MessagingException e) {
   e.printStackTrace();
}

添加文件附件

private void appendFile(MimeMessage message, String filePath) {    
try {
       Multipart multipart = (Multipart) message.getContent();
       MimeBodyPart filePart = new MimeBodyPart();
       filePart.attachFile(filePath);
       multipart.addBodyPart(filePart);
   } catch (IOException e) {
       e.printStackTrace();
   } catch (MessagingException e) {
       e.printStackTrace();
   }
}

添加多个文件附件

private void appendMultiFile(MimeMessage message, List<String> pathList) {    
try {
   Multipart multipart = (Multipart) message.getContent();       
           for (String path : pathList) {
           MimeBodyPart filePart = new MimeBodyPart();
           filePart.attachFile(path);
           multipart.addBodyPart(filePart);
       }
   } catch (IOException e) {
       e.printStackTrace();
   } catch (MessagingException e) {
       e.printStackTrace();
   }
}

发送邮件

Transport.send(mimeMessage);

发送结果

1.不带附件的邮件:

// 此处省略

2.带附件的邮件

// 此处省略

完整的发送代码

为了方便使用,就写了个发送邮件的单例,代码如下:

package net.devwiki.mailsender;   import android.os.AsyncTask;   import java.io.IOException;
   import java.util.Date;
   import java.util.List;
   import java.util.Properties;   import javax.mail.Authenticator;
   import javax.mail.Message;
   import javax.mail.MessagingException;
   import javax.mail.Multipart;
   import javax.mail.PasswordAuthentication;
   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;/**
* 邮件管理类
* Created by DevWiki on 2016/8/21.
*/
public class MailManager {
private static final String SENDER_NAME = "xxxxx@163.com";
private static final String SENDER_PASS = "xxxxx";
private static final String VALUE_MAIL_HOST = "smtp.163.com";
private static final String KEY_MAIL_HOST = "mail.smtp.host";
private static final String KEY_MAIL_AUTH = "mail.smtp.auth";
private static final String VALUE_MAIL_AUTH = "true";public static MailManager getInstance() {
   return InstanceHolder.instance;
}private MailManager() {
}private static class InstanceHolder {
   private static MailManager instance = new MailManager();
}class MailTask extends AsyncTask<Void, Void, Boolean> {
   private MimeMessage mimeMessage;   public MailTask(MimeMessage mimeMessage) {
       this.mimeMessage = mimeMessage;
   }   @Override
   protected Boolean doInBackground(Void... voids) {
       try {
           Transport.send(mimeMessage);
           return Boolean.TRUE;
       } catch (MessagingException e) {
           e.printStackTrace();
           return Boolean.FALSE;
       }
   }
}public void sendMail(final String title, final String content) {
   MimeMessage mimeMessage = createMessage(title, content);
   MailTask mailTask = new MailTask(mimeMessage);
   mailTask.execute();
}public void sendMailWithFile(String title, String content, String filePath) {
   MimeMessage mimeMessage = createMessage(title, content);
   appendFile(mimeMessage, filePath);
   MailTask mailTask = new MailTask(mimeMessage);
   mailTask.execute();
}public void sendMailWithMultiFile(String title, String content, List<String> pathList) {
   MimeMessage mimeMessage = createMessage(title, content);
   appendMultiFile(mimeMessage, pathList);
   MailTask mailTask = new MailTask(mimeMessage);
   mailTask.execute();
}private Authenticator getAuthenticator() {
   return new Authenticator() {
       @Override
       protected PasswordAuthentication getPasswordAuthentication() {
           return new PasswordAuthentication(SENDER_NAME, SENDER_PASS);
       }
   };
}private MimeMessage createMessage(String title, String content) {
   Properties properties = System.getProperties();
   properties.put(KEY_MAIL_HOST, VALUE_MAIL_HOST);
   properties.put(KEY_MAIL_AUTH, VALUE_MAIL_AUTH);
   Session session = Session.getInstance(properties, getAuthenticator());
   MimeMessage mimeMessage = new MimeMessage(session);
   try {
       mimeMessage.setFrom(new InternetAddress(SENDER_NAME));
       InternetAddress[] addresses = new InternetAddress[]{new InternetAddress(SENDER_NAME)};
       mimeMessage.setRecipients(Message.RecipientType.TO, addresses);
       mimeMessage.setSubject(title);
       MimeBodyPart textPart = new MimeBodyPart();
       textPart.setContent(content, "text/html");
       Multipart multipart = new MimeMultipart();
       multipart.addBodyPart(textPart);
       mimeMessage.setContent(multipart);
       mimeMessage.setSentDate(new Date());
   } catch (MessagingException e) {
       e.printStackTrace();
   }
   return mimeMessage;
}private void appendFile(MimeMessage message, String filePath) {
   try {
       Multipart multipart = (Multipart) message.getContent();
       MimeBodyPart filePart = new MimeBodyPart();
       filePart.attachFile(filePath);
       multipart.addBodyPart(filePart);
   } catch (IOException e) {
       e.printStackTrace();
   } catch (MessagingException e) {
       e.printStackTrace();
   }
}private void appendMultiFile(MimeMessage message, List<String> pathList) {
   try {
       Multipart multipart = (Multipart) message.getContent();
       for (String path : pathList) {
           MimeBodyPart filePart = new MimeBodyPart();
           filePart.attachFile(path);
           multipart.addBodyPart(filePart);
       }
   } catch (IOException e) {
       e.printStackTrace();
   } catch (MessagingException e) {
       e.printStackTrace();
   }
}
}
    

后记

如果你需要完整的项目代码,请点击此处:MailSender(需要点击文章:http://blog.devwiki.net/index.php/2016/08/21/android-background-send-log-mail.html?utm_source=tuicool&utm_medium=referral)

本文由原作者DevWiki独家授权Open软件开发小组发布,著作权归原作者所有。如需转载请申请授权。

本文分享自微信公众号 - Open软件开发小组(open_dev),作者:DevWiki

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-08-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 深入理解Activity启动流程和AMS框架(三)

    Intent中定义了一个标志FLAGACTIVITYNEW_TASK,在startActivity的Intent参数中加入该标志就能开启一个新的Task。但是,...

    open
  • 深入理解Activity启动流程和AMS框架(二)

    ActivityThread中的成员变量mActivities中保存了所有ActivityClientRecord对象,该类中重要的成员变量如下:

    open
  • Java设计模式精讲(一):责任链模式

    这篇分享作为一个系列分享的第一篇,主要和大家一起学习一下java设计模式方面的基础,我们现在的安卓开发主要还是基于java语言,所以掌握java...

    open
  • 集合去重方法,自备

    听着music睡
  • Android高仿微信照片选择器+预览+显示照片

    版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/49...

    Hankkin
  • 0605-5.16.1-CM告警SNMP中DateAndTime类型解析

    Fayson在前面的文章《如何通过Cloudera Manager配置使用SNMP方式转发告警》和《CM告警SNMP对接补充》介绍了使用SNMP的方式对接,对接...

    Fayson
  • .NET Core采用的全新配置系统[10]: 配置的同步机制是如何实现的?

    配置的同步涉及到两个方面:第一,对原始的配置文件实施监控并在其发生变化之后从新加载配置;第二,配置重新加载之后及时通知应用程序进而使后者能够使用最新的配置。要了...

    蒋金楠
  • 谷歌新论文:教机器人预测3D结构、然后抓取物体

    王小新 编译自 GitHub 量子位 出品 | 公众号 QbitAI 最近,Google的一组科研人员完成了一篇新论文:基于几何感知表征的抓取交互学习(Lear...

    量子位
  • python爬虫练手,爬取名言,实现英语词典

    她们的Html为,通过beautiful库的html.parser解析,通过id,class选择器,提取我们需要的东西。

    东风冷雪
  • python源码阅读笔记之函数的运行机制

    哒呵呵

扫码关注云+社区

领取腾讯云代金券