HiPhoneZhu的专栏

好几年没写博客了,还是大学生的时候记录过很多学习Android时候遇到的问题以及解决方案。转眼3,4年过去了,前段时间看了看自己以前写的博客,发现水准比较低,所以把以前的博客都给删了,这也间接说明自己成长了许多。本人文采不咋样,所以废话不多说,今天给大家带来一个小工具,一般我们做的App上线后都会去收集客户端崩溃的日志,有很多第三方帮我们做了这个工具,从各种维度进行了分析,,但这种一般作为开发者不会去看的,运营专员才会去看。开发讲究的就是立马通知我哪里哪里出问题了,马上修改,好了,那我们就借助java发送邮件的功能在Android中集成一个崩溃信息邮件通知功能吧。

一、准备java发送邮件所需要的jar包

二、建立Android项目

这里只简单介绍几个重要的类

1、自己的Application代码片段

@Overridepublic void onCreate(){super.onCreate();Thread.setDefaultUncaughtExceptionHandler(new GlobalExceptionHandler(getApplicationContext()));}2、全局异常类package com.android.exception2email;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintStream;import java.util.ArrayList;import java.util.List;import java.util.Properties;import org.xml.sax.Attributes;import android.content.Context;import android.content.pm.PackageManager.NameNotFoundException;import android.os.Build;import android.sax.Element;import android.sax.ElementListener;import android.sax.EndTextElementListener;import android.sax.RootElement;import android.util.Xml;/** * 全局异常处理 * @author hiphonezhu@gmail.com * @version [2014-6-25] */public final class GlobalExceptionHandler implementsThread.UncaughtExceptionHandler{private static final String SMTP_SINA_COM = "smtp.sina.com";private static final String LINE_SEPARATOR = System.getProperty("line.separator");private Thread.UncaughtExceptionHandler defaultHandler;private boolean caughtException = false;private String clientInfo;private Context appContext;/*** 全局错误处理构造函数*/public GlobalExceptionHandler(Context appContext){this.appContext = appContext;this.defaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 收集客户端信息this.clientInfo = collectClientInfo();loadEmails();}private List<AccountInfo> fromEmailList = new ArrayList<AccountInfo>();private List<String> toEmailList = new ArrayList<String>();private AccountInfo mailInfo = null;/*** 读取邮件列表信息*/private void loadEmails(){try{InputStream is = appContext.getAssets().open("emails.xml");RootElement document = new RootElement("addrs");Element fromList = document.getChild("from-list");Element itemFrom = fromList.getChild("item");itemFrom.setElementListener(new ElementListener(){@Overridepublic void end(){fromEmailList.add(mailInfo);}@Overridepublic void start(Attributes attributes){mailInfo = new AccountInfo();}});itemFrom.getChild("account").setEndTextElementListener(new EndTextElementListener(){@Overridepublic void end(String body){mailInfo.setAccount(body);}});itemFrom.getChild("password").setEndTextElementListener(new EndTextElementListener(){@Overridepublic void end(String body){mailInfo.setPassword(body);}});Element toList = document.getChild("to-list");Element itemTo = toList.getChild("item");itemTo.setEndTextElementListener(new EndTextElementListener(){@Overridepublic void end(String body){toEmailList.add(body);}});Xml.parse(new InputStreamReader(is), document.getContentHandler());}catch (Exception e){e.printStackTrace();}}/*** 返回版本号* @return*/public String getVerName(){String verName = "";try{verName = appContext.getPackageManager().getPackageInfo(appContext.getPackageName(),0).versionName;}catch (NameNotFoundException e){e.printStackTrace();}return verName;}/*** 返回包名* @return*/public String getPackageName(){return appContext.getPackageName();}/*** 捕获到异常** @param thread 异常线程* @param throwable 异常信息*/@Overridepublic void uncaughtException(final Thread thread, final Throwable throwable){if (caughtException){defaultHandler.uncaughtException(thread,throwable);return;}ByteArrayOutputStream baos = new ByteArrayOutputStream();PrintStream ps = new PrintStream(baos);throwable.printStackTrace(ps);final String errorMsg = new String(baos.toByteArray());final String mailContent = errorMsg + LINE_SEPARATOR + LINE_SEPARATOR+ clientInfo;// 将报错信息发送到指定的邮箱Thread sendMailThread = new Thread(){@Overridepublic void run(){try{String subject = getPackageName() + "_v" + getVerName() + " Crash Report";Properties props = new Properties();props.put("mail.smtp.host",SMTP_SINA_COM);props.put("mail.smtp.auth","true");MailUtil.MailInfo mailInfo = new MailUtil.MailInfo();int index = (int) (Math.floor(Math.random() * fromEmailList.size()));AccountInfo info = fromEmailList.get(index);mailInfo.setFrom(info.getAccount());mailInfo.setPassword(info.getPassword());mailInfo.setSmtpHost(SMTP_SINA_COM);mailInfo.setNeedAuth(true);String[] tos = new String[toEmailList.size()];toEmailList.toArray(tos);mailInfo.setToList(tos);mailInfo.setSubject(subject);mailInfo.setContent(mailContent);try{MailUtil.sendMail(mailInfo);}catch (Exception e){e.printStackTrace();}}catch (Exception e){e.printStackTrace();}finally{if (!handleException() && defaultHandler != null){defaultHandler.uncaughtException(thread, throwable);}}}};sendMailThread.start();}/*** 自定义错误处理、收集错误信息 、发送错误报告等操作均在此完成.* @return true:如果处理了该异常信息;否则返回false.*/private boolean handleException(){try{android.os.Process.killProcess(android.os.Process.myPid());System.exit(1);return true;}catch (Exception e){e.printStackTrace();return false;}}private String collectClientInfo(){StringBuilder systemInfo = new StringBuilder();systemInfo.append("CLIENT-INFO");systemInfo.append(LINE_SEPARATOR);systemInfo.append("Id: ");systemInfo.append(Build.ID);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Display: ");systemInfo.append(Build.DISPLAY);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Product: ");systemInfo.append(Build.PRODUCT);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Device: ");systemInfo.append(Build.DEVICE);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Board: ");systemInfo.append(Build.BOARD);systemInfo.append(LINE_SEPARATOR);systemInfo.append("CpuAbility: ");systemInfo.append(Build.CPU_ABI);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Manufacturer: ");systemInfo.append(Build.MANUFACTURER);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Brand: ");systemInfo.append(Build.BRAND);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Model: ");systemInfo.append(Build.MODEL);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Type: ");systemInfo.append(Build.TYPE);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Tags: ");systemInfo.append(Build.TAGS);systemInfo.append(LINE_SEPARATOR);systemInfo.append("FingerPrint: ");systemInfo.append(Build.FINGERPRINT);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Version.Incremental: ");systemInfo.append(Build.VERSION.INCREMENTAL);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Version.Release: ");systemInfo.append(Build.VERSION.RELEASE);systemInfo.append(LINE_SEPARATOR);systemInfo.append("SDK: ");systemInfo.append(Build.VERSION.SDK);systemInfo.append(LINE_SEPARATOR);systemInfo.append("SDKInt: ");systemInfo.append(Build.VERSION.SDK_INT);systemInfo.append(LINE_SEPARATOR);systemInfo.append("Version.CodeName: ");systemInfo.append(Build.VERSION.CODENAME);systemInfo.append(LINE_SEPARATOR);String clientInfomation = systemInfo.toString();systemInfo.delete(0, systemInfo.length());return clientInfomation;}}3、邮件发送辅助类package com.android.exception2email;import java.util.Date;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;/** * 邮件操作封装 * @author hiphonezhu@gmail.com * @version [2014-6-25] */public abstract class MailUtil{/*** 发送邮件** @param info 邮件信息* @throws MessagingException MessagingException*/public static void sendMail(final MailInfo info) throws MessagingException{Properties props = new Properties();props.put("mail.smtp.host",info.getSmtpHost());props.put("mail.smtp.auth",String.valueOf(info.isNeedAuth()));Session session = Session.getDefaultInstance(props,new Authenticator(){@Overridepublic PasswordAuthentication getPasswordAuthentication(){return new PasswordAuthentication(info.getFrom(),info.getPassword());}});MimeMessage msg = new MimeMessage(session);msg.setFrom(new InternetAddress(info.getFrom()));InternetAddress[] address = new InternetAddress[info.getToList().length];for (int i = 0; i < info.getToList().length; i++){address[i] = new InternetAddress(info.getToList()[i]);}msg.setRecipients(Message.RecipientType.TO,address);Date current = new Date();msg.setSubject(info.getSubject());Multipart mp = new MimeMultipart();MimeBodyPart mbpContent = new MimeBodyPart();mbpContent.setText(info.getContent());mp.addBodyPart(mbpContent);msg.setContent(mp);msg.setSentDate(current);Transport.send(msg,address);}/*** 邮件信息*/public static class MailInfo{private String from;private String password;private String[] toList;private String subject;private String content;private boolean needAuth;private String smtpHost;public String getFrom(){return from;}public void setFrom(String from){this.from = from;}public String getPassword(){return password;}public void setPassword(String password){this.password = password;}public String[] getToList(){return toList;}public void setToList(String[] toList){this.toList = toList;}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 boolean isNeedAuth(){return needAuth;}public void setNeedAuth(boolean needAuth){this.needAuth = needAuth;}public String getSmtpHost(){return smtpHost;}public void setSmtpHost(String smtpHost){this.smtpHost = smtpHost;}}}4、邮件发送者和接受者列表(防止同一个账号发送多次邮件被服务器拒绝,这里我们尽量申请多个Email账号),xml文件可配置,增加灵活性孤独是一种无奈的选择,孤独是因为没有找到合适的同行者,

HiPhoneZhu的专栏

相关文章:

你感兴趣的文章:

标签云: