效果:
参考:https://blog.csdn.net/wx_anonymity/article/details/80733158
工具类:
/* * File Name: LogUtils.java * History: * Created by mwqi on 2014-4-4 */ package com.example.mvpfour.utils; import android.os.Environment; import android.text.TextUtils; import android.util.Log; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.text.SimpleDateFormat; import java.util.List; /** * 日志输出控制类 (Description) * * @author huyan */ public class LogUtils { /** * 日志输出级别NONE(不输出) */ public static final int LEVEL_NONE = 0; /** * 日志输出级别V */ public static final int LEVEL_VERBOSE = 1; /** * 日志输出级别D */ public static final int LEVEL_DEBUG = 2; /** * 日志输出级别I */ public static final int LEVEL_INFO = 3; /** * 日志输出级别W */ public static final int LEVEL_WARN = 4; /** * 日志输出级别E */ public static final int LEVEL_ERROR = 5; /** * 日志输出时的TAG */ private static String mTag = "GsonUtils"; /** * 是否允许输出log */ private static int mDebuggable = LEVEL_DEBUG; //开关 /** * 用于记时的变量 */ private static long mTimestamp = 0; /** * 写文件的锁对象 */ private static final Object mLogLock = new Object(); /** * 是否保存日志到本地 */ private static boolean saveLog = false; public static final String LOG_DIR = "log"; private static final String LOG_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + LOG_DIR + File.separator; public static final String LOG_FILE_NAME = LOG_PATH + "log.txt"; public static final long LOG_FILE_SIZE = 50 * 1024 * 1024;//本地日志缓存大小 /** *Android Log打印的统一管理,兼容AndroidStudio的打印过长字符串导致显示不全的问题 */ private static final int STRING_MAXLENGTH = 1000; //Log单行的最大长度 private static int STRING_START = 0; private static int STRING_END = 1000; /** * 以级别为 d 的形式输出LOG */ public static void v(String msg) { if (mDebuggable >= LEVEL_VERBOSE) { Log.v(mTag, msg); } } /** * 以级别为 d 的形式输出LOG */ public static void v(String mTag, String msg) { if (mDebuggable >= LEVEL_VERBOSE) { Log.v(mTag, msg); } } /** * 以级别为 d 的形式输出LOG */ public static void d(String msg) { if (mDebuggable >= LEVEL_DEBUG) { Log.d(mTag, msg); if (saveLog) { //判断SD卡是否挂载 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { return; } /**询问和申请权限*/ //创建文件目录 File file = new File(LOG_PATH); if (!file.exists()) { file.mkdirs(); } //判断文件大小 File logFile = new File(LOG_FILE_NAME); if (logFile.exists()) { long length1 = logFile.length(); if (length1 > 10 * 1024) { logFile.delete(); } } //添加时间 long currentTime = System.currentTimeMillis(); String currentTimeString = formatDateAndSecond(currentTime); log2File(currentTimeString + ":" + msg, LOG_FILE_NAME); } } } /* Android Log打印的统一管理,兼容AndroidStudio的打印过长字符串导致显示不全的问题 */ public static void handleMessage(String message) { STRING_START = 0; STRING_END = 1000; int msg_difference = message.length() - STRING_MAXLENGTH; if (msg_difference > 0) { STRING_END = STRING_MAXLENGTH; for (; ; ) { d(message.substring(STRING_START, STRING_END)); STRING_START = STRING_END; STRING_END += STRING_MAXLENGTH; if (STRING_END >= message.length()) { d(message.substring(STRING_START, message.length())); return; } } }else { d(message); } } /** * 以级别为 d 的形式输出LOG */ public static void d(String mTag, String msg) { if (mDebuggable >= LEVEL_DEBUG) { Log.d(mTag, msg); } } /** * 以级别为 d 的形式输出LOG,并保存日志 */ public static void d(String msg, boolean saveLog) { if (mDebuggable >= LEVEL_DEBUG) { Log.d(mTag, msg); if (saveLog) { //判断SD卡是否挂载 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { return; } //创建文件目录 File file = new File(LOG_PATH); if (!file.exists()) { file.mkdirs(); } //判断文件大小 File logFile = new File(LOG_FILE_NAME); if (logFile.exists()) { long length1 = logFile.length(); if (length1 > 10 * 1024) { logFile.delete(); } } //添加时间 long currentTime = System.currentTimeMillis(); String currentTimeString = formatDateAndSecond(currentTime); log2File(currentTimeString + ":" + msg, LOG_FILE_NAME); } } } /** * 以级别为 d 的形式输出LOG,并保存日志 * saveLog保存日志 hasClassName带类名标记 */ public static void d(String msg, boolean saveLog, boolean hasClassName) { if (mDebuggable >= LEVEL_DEBUG) { if (hasClassName) { msg = getClassName()+">>" + msg; } Log.d(mTag, msg); if (saveLog) { //判断SD卡是否挂载 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { return; } //创建文件目录 File file = new File(LOG_PATH); if (!file.exists()) { file.mkdirs(); } //判断文件大小 File logFile = new File(LOG_FILE_NAME); if (logFile.exists()) { long length1 = logFile.length(); if (length1 > 10 * 1024) { logFile.delete(); } } //添加时间 long currentTime = System.currentTimeMillis(); String currentTimeString = formatDateAndSecond(currentTime); log2File(currentTimeString + ":" + msg, LOG_FILE_NAME); } } } /** * 以级别为 i 的形式输出LOG */ public static void i(String msg) { if (mDebuggable >= LEVEL_INFO) { Log.i(mTag, msg); } } /** * 以级别为 i 的形式输出LOG */ public static void i(String mTag, String msg) { if (mDebuggable >= LEVEL_INFO) { Log.i(mTag, msg); } } /** * 以级别为 w 的形式输出LOG */ public static void w(String msg) { if (mDebuggable >= LEVEL_WARN) { Log.w(mTag, msg); } } /** * 以级别为 w 的形式输出LOG */ public static void w(String mTag, String msg) { if (mDebuggable >= LEVEL_WARN) { Log.w(mTag, msg); } } /** * 以级别为 w 的形式输出Throwable */ public static void w(Throwable tr) { if (mDebuggable >= LEVEL_WARN) { Log.w(mTag, "", tr); } } /** * 以级别为 w 的形式输出LOG信息和Throwable */ public static void w(String msg, Throwable tr) { if (mDebuggable >= LEVEL_WARN && null != msg) { Log.w(mTag, msg, tr); } } /** * 以级别为 e 的形式输出LOG */ public static void e(String msg) { if (mDebuggable >= LEVEL_ERROR) { Log.e(mTag, msg); } } /** * 以级别为 e 的形式输出LOG */ public static void e(String mTag, String msg) { if (mDebuggable >= LEVEL_ERROR) { Log.e(mTag, msg); } } /** * 以级别为 e 的形式输出Throwable */ public static void e(Throwable tr) { if (mDebuggable >= LEVEL_ERROR) { Log.e(mTag, "", tr); } } /** * 以级别为 e 的形式输出LOG信息和Throwable */ public static void e(String msg, Throwable tr) { if (mDebuggable >= LEVEL_ERROR && null != msg) { Log.e(mTag, msg, tr); } } /** * 把Log存储到文件中 * * @param log 需要存储的日志 * @param path 存储路径 */ public static void log2File(String log, String path) { log2File(log, path, true); } public static void log2File(String log, String path, boolean append) { synchronized (mLogLock) { writeFile(log + "\r\n", path, append); } } /** * 以级别为 e 的形式输出msg信息,附带时间戳,用于输出一个时间段起始点 * * @param msg 需要输出的msg */ public static void msgStartTime(String msg) { mTimestamp = System.currentTimeMillis(); if (!TextUtils.isEmpty(msg)) { e("[Started:" + mTimestamp + "]" + msg); } } /** * 以级别为 e 的形式输出msg信息,附带时间戳,用于输出一个时间段结束点* @param msg 需要输出的msg */ public static void elapsed(String msg) { long currentTime = System.currentTimeMillis(); long elapsedTime = currentTime - mTimestamp; mTimestamp = currentTime; e("[Elapsed:" + elapsedTime + "]" + msg); } public static <T> void printList(List<T> list) { if (list == null || list.size() < 1) { return; } int size = list.size(); i("---begin---"); for (int i = 0; i < size; i++) { i(i + ":" + list.get(i).toString()); } i("---end---"); } public static <T> void printArray(T[] array) { if (array == null || array.length < 1) { return; } int length = array.length; i("---begin---"); for (int i = 0; i < length; i++) { i(i + ":" + array[i].toString()); } i("---end---"); } /** * 把字符串数据写入文件 * * @param content 需要写入的字符串 * @param path 文件路径名称 * @param append 是否以添加的模式写入 * @return 是否写入成功 */ public static boolean writeFile(String content, String path, boolean append) { return writeFile(content.getBytes(), path, append); } /** * 把字符串数据写入文件 * * @param content 需要写入的字符串 * @param path 文件路径名称 * @param append 是否以添加的模式写入 * @return 是否写入成功 */ public static boolean writeFile(byte[] content, String path, boolean append) { boolean res = false; File f = new File(path); RandomAccessFile raf = null; try { if (f.exists()) { if (!append) { f.delete(); f.createNewFile(); } } else { f.createNewFile(); } if (f.canWrite()) { raf = new RandomAccessFile(f, "rw"); raf.seek(raf.length()); raf.write(content); res = true; } } catch (Exception e) { System.out.println(mTag + "Exception" + e.toString()); } finally { if (null != raf) { try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } } return res; } /** * 得到: 年-月-日 小时:分钟 * * @param lefttime * @return 年-月-日 小时:分钟 */ public static String formatDateAndSecond(long lefttime) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String sDateTime = sdf.format(lefttime); return sDateTime; } /** * 获取当前Activity类名 * * @return */ private static String getClassName() { // 这里的数组的index,即2,是根据你工具类的层级取的值,可根据需求改变 StackTraceElement thisMethodStack = (new Exception()).getStackTrace()[2]; String result = thisMethodStack.getClassName(); int lastIndex = result.lastIndexOf("."); result = result.substring(lastIndex + 1, result.length()); return result; } }
。。。