1,公司做第三方公司投影仪适配,无法使用adb所以保存日志到sd卡。方便调错。
LogSaver.java
public class LogSaver {
private static LogSaver INSTANCE = null;
private static String PATH_LOGCAT;
private LogDumper mLogDumper = null;
private int mPId;
public void init(Context context) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中
PATH_LOGCAT = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "log";
} else {// 如果SD卡不存在,就保存到本应用的目录下
PATH_LOGCAT = context.getFilesDir().getAbsolutePath() + File.separator + "log";
}
File file = new File(PATH_LOGCAT);
if (!file.exists()) {
file.mkdirs();
}
}
public static LogSaver getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = new LogSaver(context);
}
return INSTANCE;
}
private LogSaver(Context context) {
init(context);
mPId = android.os.Process.myPid();
}
public void start() {
if (mLogDumper == null) {
mLogDumper = new LogDumper(String.valueOf(mPId), PATH_LOGCAT);
}
Log.i("path", PATH_LOGCAT);/// storage/sdcard0/miniGPS
mLogDumper.start();
}
public void stop() {
if (mLogDumper != null) {
mLogDumper.stopLogs();
mLogDumper = null;
}
}
private class LogDumper extends Thread {
private Process logcatProc;
private BufferedReader mReader = null;
private boolean mRunning = true;
String cmds = null;
private String mPID;
private FileOutputStream out = null;
public LogDumper(String pid, String dir) {
mPID = pid;
try {
out = new FileOutputStream(new File(dir, "GPS-" + new MyDate().getFileName() + ".log"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/**
* 日志等级:*:v , *:d , *:w , *:e , *:f , *:s
* 显示当前mPID程序的 E和W等级的日志.
*/
cmds = "logcat *:e *:i *:d *:w *:v *:d | grep \"(" + mPID + ")\"";// 会打印i,e,w,不会打印d
}
public void stopLogs() {
mRunning = false;
}
@Override
public void run() {
try {
logcatProc = Runtime.getRuntime().exec(cmds);
mReader = new BufferedReader(new InputStreamReader(logcatProc.getInputStream()), 1024);
String line = null;
while (mRunning && (line = mReader.readLine()) != null) {
if (!mRunning) {
break;
}
if (line.length() == 0) {
continue;
}
if (out != null && line.contains(mPID)) {
out.write((new MyDate().getDateEN() + " " + line + "\n").getBytes());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (logcatProc != null) {
logcatProc.destroy();
logcatProc = null;
}
if (mReader != null) {
try {
mReader.close();
mReader = null;
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
out = null;
}
}
}
}
class MyDate {
public String getFileName() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String date = format.format(new Date(System.currentTimeMillis()));
return date;// 2012年10月03日 23:41:31
}
public String getDateEN() {
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1 = format1.format(new Date(System.currentTimeMillis()));
return date1;// 2012-10-03 23:41:31
}
}
}
使用需要初始化
LogSaver.getInstance(this).start();
报错日志打印更直观记录crash日志
CrashLogHandlerUtils.java
public class CrashLogHandlerUtils implements UncaughtExceptionHandler {
private static CrashLogHandlerUtils mSelf;
// 系统默认的UncaughtException处理类
private UncaughtExceptionHandler mDefaultHandler;
// 程序的Context对象
private Context mContext;
//保存log的文件夹
private File mSaveDir;
//在log上面添加的额外信息
private String mTopMsg;
//在log下面添加的额外信息
private String mBottomMsg;
//在保存新log的同时是否删除7天前的log
private boolean mDeleteOld;
// 用于格式化日期,作为日志文件名的一部分
private DateFormat mFormatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
private CrashLogHandlerUtils(Application application) {
mContext = application;
// 设置log默认保存目录
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
mSaveDir = application.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
}
// 设置默认的在log上面添加的额外信息
setDefaultsTopMsg();
// 设置默认的在log下面添加的额外信息
setDefaultsBottomMsg();
}
/**
* @param application 运行环境
* @return 返回实例
*/
public static synchronized CrashLogHandlerUtils getInstance(Application application) {
if (mSelf == null) {
mSelf = new CrashLogHandlerUtils(application);
}
return mSelf;
}
/**
* 设置保存log的文件夹,默认为{@link Environment#DIRECTORY_DOCUMENTS}
* @param saveDir 保存log的文件夹
* @return self
*/
public CrashLogHandlerUtils setSavePath(File saveDir) {
mSelf.mSaveDir = saveDir;
return mSelf;
}
/**
* 设置在log上面添加的额外信息
* @param topMsg 添加在log上面添加的额外信息
* @return self
*/
public CrashLogHandlerUtils setLogTopMessage(String topMsg) {
mSelf.mTopMsg = topMsg;
return mSelf;
}
/**
* 设置在log下面添加的额外信息
* @param bottomMsg 添加在log下面添加的额外信息
* @return self
*/
public CrashLogHandlerUtils setLogBottomMessage(String bottomMsg) {
mSelf.mBottomMsg = bottomMsg;
return mSelf;
}
/**
* 设置在保存新log的同时是否删除7天前的log, 默认为{@code false}
* @param deleteOldLog 是否删除
* @return self
*/
public CrashLogHandlerUtils setDeleteOldLog(boolean deleteOldLog) {
mSelf.mDeleteOld = deleteOldLog;
return mSelf;
}
/**
* 启动异常退出log捕捉
*/
public void start() {
// 获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);
}
}
/**
* @param ex 异常
* @return @code false,因为本工具只保存异常日志,不捕获异常,所以只返回@code false
*/
private boolean handleException(Throwable ex) {
if (ex != null) {
saveCrashInfo2File(ex);
}
return false;
}
/**
* 保存错误信息到文件中
* @param ex Crash异常
* @return 是否保存成功
*/
private boolean saveCrashInfo2File(Throwable ex) {
Calendar calendar = Calendar.getInstance();
StringBuffer sb = new StringBuffer();
sb.append(mTopMsg);
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
sb.append(mBottomMsg);
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File dir = mSaveDir;
if (!dir.exists()) {
dir.mkdirs();
}
FileWriter fWriter = null;
try {
fWriter = new FileWriter(mSaveDir + "/" + getFileNameByCalendar(calendar), true);
fWriter.write(sb.toString());
fWriter.flush();
fWriter.close();
if (mDeleteOld) {
deleteOldFile(calendar);
}
return true;
} catch (IOException e) {
e.printStackTrace();
if (fWriter != null) {
try {
fWriter.flush();
fWriter.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
return false;
}
/**
* 设置默认的在log上面添加的额外信息
*/
private void setDefaultsTopMsg() {
StringBuffer sb = new StringBuffer();
Calendar calendar = Calendar.getInstance();
Date date = new Date(calendar.getTimeInMillis());
long timestamp = calendar.getTimeInMillis();
String time = mFormatter.format(date);
sb.append("--------本次错误开始--------\n");
sb.append(time).append("_").append(timestamp).append("\n");
try {
PackageManager pm = mContext.getPackageManager();
PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
sb.append("versionName:").append(versionName).append("\n");
sb.append("versionCode:").append(versionCode).append("\n");
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
mTopMsg = sb.toString();
}
/**
* 设置默认的在log下面添加的额外信息
*/
private void setDefaultsBottomMsg() {
StringBuffer sb = new StringBuffer();
sb.append("--------本次错误结束---------").append("\n\n");
mBottomMsg = sb.toString();
}
/**
* 删除给定日期的七天(含)前的及以后的log
* @param todayCalendar 所以日期
*/
private void deleteOldFile(Calendar todayCalendar) {
File[] files = mSaveDir.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
Calendar oldCalendar = (Calendar) todayCalendar.clone();
oldCalendar.set(Calendar.DAY_OF_MONTH, oldCalendar.get(Calendar.DAY_OF_MONTH) - 1);
if (file.isFile() && file.exists() && !file.getName().equals(getFileNameByCalendar(todayCalendar))
&& !file.getName().equals(getFileNameByCalendar(getCalendarByCorrection(todayCalendar, -1)))
&& !file.getName().equals(getFileNameByCalendar(getCalendarByCorrection(todayCalendar, -2)))
&& !file.getName().equals(getFileNameByCalendar(getCalendarByCorrection(todayCalendar, -3)))
&& !file.getName().equals(getFileNameByCalendar(getCalendarByCorrection(todayCalendar, -4)))
&& !file.getName().equals(getFileNameByCalendar(getCalendarByCorrection(todayCalendar, -5)))
&& !file.getName().equals(getFileNameByCalendar(getCalendarByCorrection(todayCalendar, -6)))) {
try {
file.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 获取所给日期的修正后的日期
* @param calendar 原始日期
* @param correctionDay 修正值,单位为天
* @return 修正后的日期
*/
private Calendar getCalendarByCorrection(Calendar calendar, int correctionDay) {
Calendar oldCalendar = (Calendar) calendar.clone();
oldCalendar.set(Calendar.DAY_OF_MONTH, oldCalendar.get(Calendar.DAY_OF_MONTH) + correctionDay);
return oldCalendar;
}
/**
* 根据日期获取文件名
* @param calendar 日期
* @return 文件名
*/
private String getFileNameByCalendar(Calendar calendar) {
if (calendar == null) {
return null;
}
String fileName = "crash_log" + "_" + mContext.getResources().getString(R.string.app_name) + ".txt";
return fileName;
}
}
初始化:
CrashLogHandlerUtils.getInstance(this).setSavePath(Environment.getExternalStorageDirectory()).start();
网友评论