/** * Copyright (c) 1993-2023 AutoNavi, Inc. All rights reserved. This software is * the confidential and proprietary information of AutoNavi, Inc. * ("Confidential Information"). You shall not disclose such Confidential * Information and shall use it only in accordance with the terms of the license * agreement you entered into with AutoNavi. */ package com.github.lazylibrary.util; import android.util.Log; import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Locale; /** * 日志相关类:默认是测试环境
* 支持:存储Log日志文件到本地。发送Log日志信息到服务器 * * @author yuchao.wang * @since 2014-4-23 */ public class LogUtil { /* ========================下面的是本地存储相关的========================== */ /** * 写日志对象 */ private LogWriter logWriter; /** * 写入本地日志线程 */ private class LogWriter extends Thread { /** * 文件路径 */ private String mFilePath; /** * 调用这个类的线程 */ private int mPid; /** * 线程运行标志 */ private boolean isRunning = true; /** * @param filePath 文件路径 * @param pid */ public LogWriter(String filePath, int pid) { this.mPid = pid; this.mFilePath = filePath; } @Override public void run() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA);//日期格式化对象 Process process = null;//进程 BufferedReader reader = null; FileWriter writer = null; try { //执行命令行 String cmd = "logcat *:e *:w | grep"; process = Runtime.getRuntime().exec(cmd); //得到输入流 reader = new BufferedReader(new InputStreamReader(process.getInputStream()), 1024); //创建文件 File file = new File(mFilePath); if (!file.exists()) { file.getParentFile().mkdirs(); file.createNewFile(); } writer = new FileWriter(file, true); //循环写入文件 String line = null; while (isRunning) { line = reader.readLine(); if (line != null && line.length() > 0) { writer.append("PID:" + this.mPid + "\t" + sdf.format(new Date(System.currentTimeMillis())) + "\t" + line + "\n"); writer.flush(); } else { break; } } } catch (Exception e) { e.printStackTrace(); } finally { if (process != null) { process.destroy(); } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (writer != null) { try { writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } process = null; reader = null; writer = null; } } public void end() { isRunning = false; } } /** * 整个应用只需要调用一次即可:开始本地记录 * * @param filePath 要写入的目的文件路径 * @param iswrite 是否需要写入sdk */ public void startWriteLogToSdcard(String filePath,boolean iswrite) { if (iswrite) { if (logWriter == null) { try { /** LogUtil这个类的pid,必须在类外面得到 */ logWriter = new LogWriter(filePath, android.os.Process.myPid()); } catch (Exception e) { e.printStackTrace(); } } logWriter.start(); } } /** * 整个应用只需要调用一次即可:结束本地记录 */ public void endWriteLogToSdcard() { if (logWriter != null) { logWriter.end(); } } /* ========================下面的是需要上传的数据========================== */ private LogUploader logUploader; /** * 日志上传线程 */ private class LogUploader extends Thread { /** * 当前线程是否正在运行 */ private boolean isRunning = true; /** * 上传所需要的url */ private String mStrUrl; /** * 上传所需要的其他参数 */ private HashMap mAllParams; /** * 上传所需要pid */ private int mPid; /** * 构造方法 * * @param strUrl 上传所需要的url * @param allParams 需要上传的额外的参数【除了日志以外】 * @param pid 日志所在的pid */ public LogUploader(String strUrl, HashMap allParams, int pid) { this.mStrUrl = strUrl; this.mAllParams = allParams; this.mPid = pid; } @Override public void run() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA);//日期格式化对象 Process process = null;//进程 BufferedReader reader = null; try { //执行命令行,得到输入流 String cmd = "logcat *:e *:w | grep"; process = Runtime.getRuntime().exec(cmd); reader = new BufferedReader(new InputStreamReader(process.getInputStream()), 1024); String line = null; while (isRunning) { line = reader.readLine(); if (line != null && line.length() > 0) { String log = "PID:" + this.mPid + "\t" + sdf.format(new Date(System.currentTimeMillis())) + "\t" + line; mAllParams.put("log", log); } else { break; } } } catch (Exception e) { e.printStackTrace(); } finally { if (process != null) { process.destroy(); } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } process = null; reader = null; } } public void end() { isRunning = false; } } /** * 整个应用调用一次即可:上传日志数据 * * @param strUrl 上传所需要的url * @param allParams 需要上传的额外的参数【除了日志以外】 * @param isUploadLog 是否需要上传 */ public void startUploadLog(String strUrl, HashMap allParams,boolean isUploadLog) { if (isUploadLog) { if (logUploader == null) { logUploader = new LogUploader(strUrl, allParams, android.os.Process.myPid()); } logUploader.start(); } } /** * 整个应用调用一次即可:结束上传日志数据 */ public void endUploadLog() { if (logUploader != null) { logUploader.end(); } } /* ========================下面的是直接使用的========================== */ /** * verbose详细日志 * * @param tag 日志标记 * @param message 日志信息 * @param isShowLog 是否显示 */ public static void v(String tag, String message,boolean isShowLog) { if (isShowLog) { Log.v(tag, getDetailMessage(message)); } } /** * verbose详细日志 * * @param message 日志信息 * @param isShowLog 是否显示 */ public static void v(String message,boolean isShowLog) { if (isShowLog) { String[] output = getTagAndDetailMessage(message); Log.v(output[0], output[1]); } } /** * error错误日志 * * @param tag 日志标记 * @param message 日志信息 * @param isShowLog 是否显示 */ public static void e(String tag, String message,boolean isShowLog) { if (isShowLog) { Log.e(tag, getDetailMessage(message)); } } /** * error错误日志 * * @param message 日志信息 * @param isShowLog isShowLog */ public static void e(String message,boolean isShowLog) { if (isShowLog) { String[] output = getTagAndDetailMessage(message); Log.e(output[0], output[1]); } } /** * info信息日志 * * @param tag 日志标记 * @param message 日志信息 * @param isShowLog isShowLog */ public static void i(String tag, String message,boolean isShowLog) { if (isShowLog) { Log.i(tag, getDetailMessage(message)); } } /** * info信息日志 * * @param message 日志信息 * @param isShowLog isShowLog */ public static void i(String message,boolean isShowLog) { if (isShowLog) { String[] output = getTagAndDetailMessage(message); Log.i(output[0], output[1]); } } /** * debug调试日志 * * @param tag 日志标记 * @param message 日志信息 * @param isShowLog isShowLog */ public static void d(String tag, String message,boolean isShowLog) { if (isShowLog) { Log.d(tag, getDetailMessage(message)); } } /** * debug调试日志 * * @param message 日志信息 * @param isShowLog isShowLog */ public static void d(String message,boolean isShowLog) { if (isShowLog) { String[] output = getTagAndDetailMessage(message); Log.d(output[0], output[1]); } } /** * warn警告日志 * * @param tag 日志标记 * @param message 日志信息 * @param isShowLog isShowLog */ public static void w(String tag, String message,boolean isShowLog) { if (isShowLog) { Log.w(tag, getDetailMessage(message)); } } /** * warn警告日志 * * @param message 日志信息 * @param isShowLog isShowLog */ public static void w(String message,boolean isShowLog) { if (isShowLog) { String[] output = getTagAndDetailMessage(message); Log.w(output[0], output[1]); } } /** * 得到默认tag【类名】以及信息详情 * * @param message 要显示的信息 * @return 默认tag【类名】以及信息详情,默认信息详情【类名+方法名+行号+message】 */ private static String[] getTagAndDetailMessage(String message) { String output[] = new String[2]; for (StackTraceElement ste : (new Throwable()).getStackTrace()) { //栈顶肯定是LogUtil这个类自己 if (LogUtil.class.getName().equals(ste.getClassName())) { continue; } //栈顶的下一个就是需要调用这个类的地方 else { int b = ste.getClassName().lastIndexOf(".") + 1; output[0] = ste.getClassName().substring(b); output[1] = output[0] + "->" + ste.getMethodName() + "():" + ste.getLineNumber() + "->" + message; break; } } return output; } /** * 得到一个信息的详细的情况【类名+方法名+行号】 * * @param message 要显示的信息 * @return 一个信息的详细的情况【类名+方法名+行号+message】 */ private static String getDetailMessage(String message) { String detailMessage = ""; for (StackTraceElement ste : (new Throwable()).getStackTrace()) { //栈顶肯定是LogUtil这个类自己 if (LogUtil.class.getName().equals(ste.getClassName())) { continue; } //栈顶的下一个就是需要调用这个类的地方[此处取出类名和方法名还有行号] else { int b = ste.getClassName().lastIndexOf(".") + 1; String TAG = ste.getClassName().substring(b); detailMessage = TAG + "->" + ste.getMethodName() + "():" + ste.getLineNumber() + "->" + message; break; } } return detailMessage; } }