主要类别:

package com.example.callstatus;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast; /**
* 捕获android程序崩溃日志<br>
* UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序.
*
* @author PMTOAM
*
*/
@SuppressLint("SimpleDateFormat")
public class CrashHandler implements UncaughtExceptionHandler
{ public static final String TAG = CrashHandler.class.getCanonicalName(); // 系统默认的UncaughtException处理类
private Thread.UncaughtExceptionHandler mDefaultHandler;
// CrashHandler实例
private static CrashHandler INSTANCE = new CrashHandler();
// 程序的Context对象
private Context mContext;
// 用来存储设备信息和异常信息
private Map<String, String> infos = new HashMap<String, String>(); // 用于格式化日期,作为日志文件名称的一部分
private DateFormat formatter = new SimpleDateFormat("yyyyMMdd_HHmmss"); /**
* 保证仅仅有一个实例
*/
private CrashHandler()
{
} /**
* 获取实例 ,单例模式
*/
public static CrashHandler getInstance()
{
return INSTANCE;
} /**
* 初始化
*
* @param context
*/
public void init(Context context)
{
mContext = context;
// 获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
} /**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex)
{
if (!handleException(ex) && mDefaultHandler != null)
{
// 假设用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
}
else
{
try
{
Thread.sleep(3000);
}
catch (InterruptedException e)
{
Log.e(TAG, "error : ", e);
} // 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
} /**
* 自己定义错误处理,收集错误信息 发送错误报告等操作均在此完毕.
*
* @param ex
* @return true:假设处理了该异常信息;否则返回false.
*/
private boolean handleException(Throwable ex)
{
if (ex == null)
{
return false;
} // 使用Toast来显示异常信息
new Thread()
{
@Override
public void run()
{
Looper.prepare();
Toast.makeText(mContext, "非常抱歉。程序出现异常。 ", Toast.LENGTH_LONG)
.show();
Looper.loop();
}
}.start(); // 收集设备參数信息
collectDeviceInfo(mContext); // 保存日志文件
String str = saveCrashInfo2File(ex);
Log.e(TAG, str); return false;
} /**
* 收集设备參数信息
*
* @param ctx
*/
public void collectDeviceInfo(Context ctx)
{
try
{
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageInfo(ctx.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);
} }
catch (NameNotFoundException e)
{
Log.e(TAG, "an error occured when collect package info", e);
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields)
{
try
{
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
Log.d(TAG, field.getName() + " : " + field.get(null));
}
catch (Exception e)
{
Log.e(TAG, "an error occured when collect crash info", e);
}
}
} /**
* 保存错误信息到文件里
*
* @param ex
* @return 返回文件名称称,便于将文件传送到server
*/
private String saveCrashInfo2File(Throwable ex)
{ StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> entry : infos.entrySet())
{
String key = entry.getKey();
String value = entry.getValue();
sb.append("[" + key + ", " + value + "]\n");
} sb.append("\n" + getStackTraceString(ex)); try
{
String time = formatter.format(new Date()); TelephonyManager mTelephonyMgr = (TelephonyManager) mContext
.getSystemService(Context.TELEPHONY_SERVICE);
String imei = mTelephonyMgr.getDeviceId();
if (TextUtils.isEmpty(imei))
{
imei = "unknownimei";
} String fileName = "CRS_" + time + "_" + imei + ".txt"; File sdDir = null; if (Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED))
sdDir = Environment.getExternalStorageDirectory(); File cacheDir = new File(sdDir + File.separator + "dPhoneLog");
if (!cacheDir.exists())
cacheDir.mkdir(); File filePath = new File(cacheDir + File.separator + fileName); FileOutputStream fos = new FileOutputStream(filePath);
fos.write(sb.toString().getBytes());
fos.close(); return fileName;
}
catch (Exception e)
{
Log.e(TAG, "an error occured while writing file...", e);
}
return null;
} /**
* 获取捕捉到的异常的字符串
*/
public static String getStackTraceString(Throwable tr)
{
if (tr == null)
{
return "";
} Throwable t = tr;
while (t != null)
{
if (t instanceof UnknownHostException)
{
return "";
}
t = t.getCause();
} StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
tr.printStackTrace(pw);
return sw.toString();
}
}

用法:

package com.example.callstatus;

import android.app.Application;

public class MyApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate(); CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(getApplicationContext());
}
}

所需权限:

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

版权声明:本文博主原创文章。博客,未经同意不得转载。

捕android程序崩溃日志的更多相关文章

  1. 保存android程序崩溃日志到SD卡

    private boolean writeToSDCard(Throwable ex) { boolean isDealing = false; if (Environment.getExternal ...

  2. android 程序崩溃crash日志的捕捉

    android 程序崩溃crash日志的捕捉 之前在项目开发过程中,一直会遇到程序崩溃了,但是测试組的哥哥们又没及时的导出日志.... 后来在诳群的时候听别人说起,腾讯有那么一个叫bugly的东西 将 ...

  3. Android程序崩溃异常收集框架

    最近在写Android程序崩溃异常处理,完成之后,稍加封装与大家分享. 我的思路是这样的,在程序崩溃之后,将异常信息保存到一个日志文件中,然后对该文件进行处理,比如发送到邮箱,或发送到服务器. 所以, ...

  4. iOS - 捕获应用程序崩溃日志

    作为一名iOS移动应用开发者,为了确保你的应用程序正确无误,在将应用程序提交到应用商店之前,你必定会进行大量的测试工作:而且在你测试的过程中应用程序运行的很好,但是在应用商店上线之后,还是有用户抱怨应 ...

  5. iOS 中捕获程序崩溃日志

    iOS 中捕获程序崩溃日志 (2014-04-22 17:35:59) 转载▼     iOS开发中遇到程序崩溃是很正常的事情,如何在程序崩溃时捕获到异常信息并通知开发者,是大多数软件都选择的方法.下 ...

  6. android app崩溃日志收集以及上传

    源代码获取请到github:https://github.com/DrJia/AndroidLogCollector 已经做成sdk的形式,源代码已公开,源代码看不懂的请自行google. 假设想定制 ...

  7. Android 应用程序崩溃日志捕捉

    程序崩溃是应用迭代中不可避免的问题,即使有着5年或者10年经验的程序猿也无法完全保证自己的代码没有任何的bug导致崩溃,现在有一些第三方平台可以帮助我们搜集应用程序的崩溃,比如友盟,详情如下图 虽然能 ...

  8. Android 程序崩溃后的处理

    在应用发布以后,由于安卓机型的千差万别 ,可能会出现各种各样的问题,这时候如果我们可以将这些信息收集起来,并进行修改就很不错了.下面就来讨论一下怎么处理程序崩溃以后,错误信息的手机. Java中已经提 ...

  9. iOS开发-捕获程序崩溃日志

    iOS开发中遇到程序崩溃是很正常的事情,如何在程序崩溃时捕获到异常信息并通知开发者,是大多数软件都选择的方法.下面就介绍如何在iOS中实现: 1. 在程序启动时加上一个异常捕获监听,用来处理程序崩溃时 ...

随机推荐

  1. 一.去除字符串中的html标记及标记中的内容

    --1.创建函数 )) ) as begin declare @i int begin set @i=len(@maco) set @maco=replace(@maco, substring(@ma ...

  2. C#设计模式-创建型模式(转)

    一.简单工厂模式 简单工厂模式Simple Factory,又称静态工厂方法模式.它是类的创建模式.是由一个工厂对象决定创建出哪一种产品类的实例,是不同的工厂方法模式的一个特殊实现. 优点: u 模式 ...

  3. Linux 0.11下信号量的实现和应用

    Linux 011下信号量的实现和应用 生产者-消费者问题 实现信号量 信号量的代码实现 关于sem_wait和sem_post sem_wait和sem_post函数的代码实现 信号量的完整代码 实 ...

  4. Yii2的相关学习记录,alert等美化、confirm异步、session中的flash及小部件的使用(六)

    呃,系统自带的alert.confirm等弹出框实在是难看,作为一个颜控,这能忍? 这里我用的是kartik-v/yii2-dialog,这个是基于bootstrap3-dialog这个来做了一些常用 ...

  5. 【转】.NET开发者必备的11款免费工具

    摘要:本文介绍一些最适合.NET开发人员简化Web开发的最佳工具,这些工具都是开源的,有的开发工具你既可以从网上下载可执行文件,也可以下载源代码.一些工具拥有可扩展的框架,是一个持续集成工具. 原文链 ...

  6. js JSONP实例

    <script type="text/javascript"> $(function(){ checkuserstatus(); $('#loginbutton').c ...

  7. 由于权限不足而无法读取配置文件出现的HTTP 500.19解决办法

    无法访问请求的页面,因为该页的相关配置数据无效. 如下图: 解决方法, 到站点目录的属性,安全标签,添加用户(Everyone),并给修改权限:

  8. spring mvc velocity多视图

    1.ViewResolverUrlBasedViewResolver 这个东西是根据url 进行路由的.网上搜了 1.order 排序,同名出现各种问题 2.XmlViewResolver,BeanN ...

  9. gets与scanf

    gets与scanf 从功能上可以看出不同之处:1 终止条件不同: gets只有遇到\n时才会结束输入,而scanf遇到空格或制表符时,也会结束输入.比如输入"test string\n&q ...

  10. 百度地图LBS云平台读写数据操作类

    最近写了个叫<行踪记录仪>的手机软件,用了百度云来记录每个用户的最近位置,以便各用户能在地图上找到附近的人,为此写了个类来读写数据,大致如下: import java.util.Array ...