一、实现Thread.UncaughtExceptionHandler
UnChecked异常发生时,由于没有相应的try…catch处理该异常对象,所以Java运行环境将会终止,程序将退出,也就是我们所说的Crash。Java API提供了一个全局异常捕获处理器,Android应用在Java层捕获Crash依赖的就是Thread.UncaughtExceptionHandler处理器接口,通常我们只需实现这个接口,并重写其中的uncaughtException方法,在该方法中可以读取Crash的堆栈信息

public class CrashManager implements Thread.UncaughtExceptionHandler {

    private Thread.UncaughtExceptionHandler mDefaultHandler;
private Map<String, String> infos;
private MyApplication application;
private static SimpleDateFormat logfile = new SimpleDateFormat("yyyy-MM-dd");// 日志文件格式 public CrashManager(MyApplication application){
//获取系统默认的UncaughtExceptionHandler
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
this.application = application;
} private boolean handleException(final Throwable exc){
if (exc == null) {
return false;
}
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();//准备
Log.i("Urmytch","崩溃正在写入日志");
flushBufferedUrlsAndReturn();
//处理崩溃
collectDeviceAndUserInfo(application);
writeCrash(exc);
Looper.loop();
}
}).start();
return true;
} /**
* 把未存盘的url和返回数据写入日志文件
*/
private void flushBufferedUrlsAndReturn(){
//TODO 可以在请求网络时把url和返回xml或json数据缓存在队列中,崩溃时先写入以便查明原因
} /**
* 采集设备和用户信息
* @param context 上下文
*/
private void collectDeviceAndUserInfo(Context context){
PackageManager pm = context.getPackageManager();
infos = new HashMap<String, String>();
try {
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null?"null":pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName",versionName);
infos.put("versionCode",versionCode);
infos.put("crashTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
} catch (PackageManager.NameNotFoundException e) {
Log.e("Urmytch",e.getMessage());
}
Field[] fields = Build.class.getDeclaredFields();
try {
for (Field field : fields) {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
}
} catch (IllegalAccessException e) {
Log.e("Urmytch",e.getMessage());
}
} /**
* 采集崩溃原因
* @param exc 异常
*/ private void writeCrash(Throwable exc){
StringBuffer sb = new StringBuffer();
sb.append("------------------crash----------------------");
sb.append("\r\n");
for (Map.Entry<String,String> entry : infos.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key+"="+value+"\r\n");
}
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
exc.printStackTrace(pw);
Throwable excCause = exc.getCause();
while (excCause != null) {
excCause.printStackTrace(pw);
excCause = excCause.getCause();
}
pw.close();
String result = writer.toString();
sb.append(result);
sb.append("\r\n");
sb.append("-------------------end-----------------------");
sb.append("\r\n");
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
String sdcardPath = Environment.getExternalStorageDirectory().getPath();
Log.i("路径:",""+Environment.getExternalStorageDirectory().getPath());
//String filePath = sdcardPath + "//Urmytch/crash/";
String filePath = sdcardPath + "//kantu/crash/";
writeLog(sb.toString(), filePath); }
}
/**
*
* @param log 文件内容
* @param name 文件路径
* @return 返回写入的文件路径
* 写入Log信息的方法,写入到SD卡里面
*/
private String writeLog(String log, String name)
{
Date nowtime = new Date();
String needWriteFiel = logfile.format(nowtime);
//String filename = name + "mycrash"+ ".log";
String filename = name + "mycrash"+ needWriteFiel+".txt";
File file =new File(filename);
if(!file.getParentFile().exists()){
Log.i("Urmytch","新建文件");
file.getParentFile().mkdirs();
}
if (file != null && file.exists() && file.length() + log.length() >= 64 * 1024) {
//控制日志文件大小
file.delete();
}
try
{
file.createNewFile();
FileWriter fw=new FileWriter(file,true);
BufferedWriter bw = new BufferedWriter(fw);
//写入相关Log到文件
bw.write(log);
bw.newLine();
bw.close();
fw.close();
//发送邮件
SendMailUtil.send(file,"changyiqiang123@126.com");
return filename;
}
catch(IOException e)
{
Log.w("Urmytch",e.getMessage());
return null;
} }
@Override
public void uncaughtException(Thread thread, Throwable exc) {
if(!handleException(exc) && mDefaultHandler != null){
//如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, exc);
Log.i("打印:","1111");
}else{
Log.i("打印:","222"); try{
Thread.sleep(2000);
}catch (InterruptedException e){
Log.w("Urmytch",e.getMessage());
}
Intent intent = new Intent(application.getApplicationContext(), LoginActivity.class);
PendingIntent restartIntent = PendingIntent.getActivity(application.getApplicationContext(), 0, intent, 0);
//退出程序
AlarmManager mgr = (AlarmManager)application.getSystemService(Context.ALARM_SERVICE);
//1秒后重启应用
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent);
android.os.Process.killProcess(android.os.Process.myPid());
} ////这里可以上传异常信息到服务器,便于开发人员分析日志从而解决Bug
// uploadExceptionToServer();
} /**
* 将错误信息上传至服务器
*/
private void uploadExceptionToServer() {
File file = new File(Environment.getExternalStorageDirectory()+File.separator+"test.txt");
OutputStream os = null;
try {
os = new FileOutputStream(file);
String str = "hello world";
byte[] data = str.getBytes();
os.write(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if (os != null)os.close();
} catch (IOException e) {
}
}
SendMailUtil.send(file,"changyiqiang123@126.com");
} }

  

二、在Application中注册

public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashManager crashHandler = new CrashManager(this);
Thread.setDefaultUncaughtExceptionHandler(crashHandler);
}
}

最后权限:

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

  

  完成

参考于:https://blog.csdn.net/urmytch/article/details/53642945

获取Android崩溃crash信息并写入日志发送邮件的更多相关文章

  1. 获取 Android APP 版本信息工具类(转载)

    获取 Android APP 版本信息工具类 获取手机APP版本信息工具类 1.获取版本名称 2.获取版本号 3.获取App的名称 package com.mingyue.nanshuibeidiao ...

  2. 常用获取Android崩溃日志和IOS崩溃日志的几种方法

    一:前言 在日常测试app时,经常会遇到崩溃问题,测试快速抓取到崩溃日志可以有效方便开发进行定位,快速解决问题所在测试做到测试分析,定位是非常重要的,这也是判断一个测试能力指标的一大维度. 二:And ...

  3. android 之 Crash信息的持久化处理

    需求: 持久化运行时异常的信息 1.CrashHandler.java import android.content.Context; import android.content.pm.Packag ...

  4. 使用CrashHandler来获取应用的crash信息

    源码地址https://github.com/king1039/android-art-res/tree/master/Chapter_13/CrashTest/src/com/ryg/crashte ...

  5. Windows Phone & Windows App应用程序崩溃crash信息抓取方法

    最近有用户反馈,应用有崩溃的情况,可是本地调试却无法重现问题,理所当然的,我想到了微软的开发者仪表盘,可以查看一段时间内的carsh记录,不过仪表盘生成carsh记录不是实时的,而且生成的报告查看非常 ...

  6. 获取android手机联系人信息

    package com.yarin.android.Examples_04_04; import android.app.Activity; import android.database.Curso ...

  7. 获取Android系统应用信息

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. java--何时处理Exception(哪一个层级),包装的基础类处理任务尽可能简洁,写入日志,检查null等运行时异常

    1. 运行时异常和受检异常 2. 提前预防运行时异常.最常发生的是NPE,而检查NPE是程序员的基本职责.其他的,如除0等运行时异常的检查,需要程序员仔细检查,每个函数都得检查(除非可以确定不会有空指 ...

  9. (转)获取android手机内部存储空间和外部存储空间的参数 && 如何决定一个apk的安装位置

    转:http://blog.csdn.net/zhandoushi1982/article/details/8560233 获取android文件系统的信息,需要Environment类和StatFs ...

随机推荐

  1. 曹玉中-201871010105《面向对象程序设计(java)》第6-7周学习总结

    曹玉中-201871010105<面向对象程序设计(java)>第6-7周学习总结 项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>    https://www.c ...

  2. jQuery的DataTables中的TableTools的基本使用

    DataTables的TableTools插件提供复制,导出excel.pdf,打印等功能. DataTables官网:http://datatables.net TableTools示例:http: ...

  3. woocommerce如何隐藏SKU

    有时我们不想在woocommerce网站前台显示SKU,如下图所示,因为sku一多整个排版可能会乱,那么要如何隐藏sku呢?随ytkah一起来看看 在当前主题的function.php文件中加入如下代 ...

  4. Location配置与ReWrite语法(五)

    原文链接:https://www.cnblogs.com/crazylqy/p/6892010.html location表示uri方式定位,基础语法有三种: location = pattern { ...

  5. zz姚班天才少年鬲融凭非凸优化研究成果获得斯隆研究奖

    姚班天才少年鬲融凭非凸优化研究成果获得斯隆研究奖 近日,美国艾尔弗·斯隆基金会(The Alfred P. Sloan Foundation)公布了2019年斯隆研究奖(Sloan Research ...

  6. [LeetCode] 767. Reorganize String 重构字符串

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to ...

  7. [LeetCode] 81. Search in Rotated Sorted Array II 在旋转有序数组中搜索之二

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  8. 软件推荐【Windows】

    随时更新...链接为官网,自用保证安全(不信任可以把鼠标放在超链接上预览一下)        如有备注,下载链接均为最新(因为都是官方自动更新的下载链) 首先: 推荐一个软件管家(毕竟有时外网不稳定, ...

  9. GreenPlum 大数据平台--segment 失效问题恢复《二》(全部segment宕机情况下)

    01,情况描述 主Segment和它的镜像都宕掉.导致了greenplum数据库不可用状态 02,重启greenplum数据库 gpstop -r 03,恢复 gprecoverseg 04,状态检查 ...

  10. SpringBoot 第一篇:入门篇

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/10819728.html 版权声明:本文为博主原创文章,转载请附上博文链接! 前言   博主从去年 ...