123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- package com.bgy.autosale.utils;
- import android.content.Context;
- import android.os.Environment;
- import android.os.SystemClock;
- import android.text.TextUtils;
- import android.util.Log;
- import java.io.File;
- import java.io.FileDescriptor;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Locale;
- import java.util.TimeZone;
- import java.util.concurrent.TimeUnit;
- import io.reactivex.disposables.Disposable;
- import io.reactivex.schedulers.Schedulers;
- /**
- * Created by cjx on 2019/8/7
- * 说明:保存日志到本地文件
- */
- public class PlcLog {
- private static PlcLog plcLog;
- private boolean open = true;
- private final ClickHelper checkFileHelper = new ClickHelper(1000 * 60 * 30);//半小时允许检查一次
- private HashMap<String, String> logPaths;
- private String defaultFile = "";
- ArrayList<String> retFilePaths = new ArrayList<>();
- private Context appContext;
- private int count = 0;
- Disposable disposable;
- public static PlcLog getInstance() {
- if (plcLog == null) {
- synchronized (PlcLog.class) {
- if (plcLog == null) {
- plcLog = new PlcLog();
- }
- }
- }
- return plcLog;
- }
- public void initLogFile(Context context) {
- initLogFile(context, "", null, new Date());
- }
- public void initLogFile(Context context, String file) {
- initLogFile(context, file, null, new Date());
- }
- public void initLogFile(Context context, String file, String dir) {
- initLogFile(context, file, dir, new Date());
- }
- public void initLogFile(Context context, String file, String dir, Date newDate) {
- appContext = context.getApplicationContext();
- defaultFile = file;
- SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd", Locale.CHINA);
- String fileName = sdf.format(newDate) + file;
- String logFilePath;
- synchronized (PlcLog.class) {
- if (dir == null) {
- dir = getDiskCacheDir(context) + "/log/";
- } else {
- dir = dir + "/log/";
- }
- mkDir(dir);
- logFilePath = dir + fileName + ".txt";
- File logFile = new File(logFilePath);
- if (!logFile.exists()) {
- try {
- logFile.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- logPaths.remove(file);
- logPaths.put(file, logFilePath);
- System.out.println("初始化日志 " + logFilePath);
- File logFileParent = logFile.getParentFile();
- retFilePaths.clear();
- if (logFileParent.listFiles()!=null) {
- for (File log : logFileParent.listFiles()) {
- String name = log.getName();
- if (name.length() > 2) {
- retFilePaths.add(log.getAbsolutePath());
- }
- }
- }
- }
- //考虑到网络时间没校准的时候
- checkAndDelLog(logFilePath);
- }
- private void checkAndDelLog(final String logFilePath) {
- if (disposable != null) {//销毁多余的延时
- disposable.dispose();
- disposable = null;
- }
- File logFile = (new File(logFilePath)).getParentFile();
- long current = System.currentTimeMillis();
- long checkTime = getEffectiveTime();
- //这么做是为了确保一下时间是准的网络时间
- if (current > checkTime) {
- if (logFile.listFiles()!=null) {
- for (File log : logFile.listFiles()) {
- String name = log.getName();
- if (name.startsWith("PLC_")) {
- try {
- if (current - log.lastModified() > 2592000000L) { // 30天前的日志, 要删除
- // if (current - log.lastModified() > 172800000) { // 2天前的日志, 要删除
- e("CJX", "删除 " + name + " = " + log.delete());
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- } else {
- disposable = Schedulers.io().scheduleDirect(new Runnable() {
- @Override
- public void run() {
- checkAndDelLog(logFilePath);
- }
- }, 30, TimeUnit.SECONDS);
- }
- }
- public void setLogSwitch(boolean open) {
- this.open = open;
- }
- private PlcLog() {
- logPaths = new HashMap<>(2);
- }
- public String getLogFilePath() {
- return getLogFilePath("");
- }
- public String getLogFilePath(String file) {
- return logPaths.get(file);
- }
- private void internalSaveLog(String file, String tag, String msg) {
- if (!open) {
- return;
- }
- if (checkFileHelper.canClick() && appContext != null) {
- initLogFile(appContext);
- }
- String filePath = logPaths.get(file);
- if (TextUtils.isEmpty(filePath)) {
- filePath = logPaths.get(defaultFile);
- }
- if (!TextUtils.isEmpty(filePath)) {
- try {
- // 2021-09-26 15:05:39.714 6218-6251/
- FileOutputStream fileOutputStream = new FileOutputStream(filePath, true);
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA);
- byte[] bytes = (sdf.format(new Date()) + " " + android.os.Process.myPid() + "-" + android.os.Process.myTid() + "/" + tag + ":" + msg + "\n").getBytes();
- fileOutputStream.write(bytes);
- fileOutputStream.flush();
- if (count++ > 8) {
- //将数据同步到达物理存储设备
- try {
- FileDescriptor fd = fileOutputStream.getFD();
- fd.sync();
- } catch (Exception e) {
- }
- count = 0;
- }
- fileOutputStream.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- e(tag, msg);
- }
- public void ui(String tag, String msg) {
- ui("", tag, msg);
- }
- public void ui(String file, String tag, String msg) {
- e_s(file, tag, msg); //也要保持
- }
- /**
- * 打印日志并保存到文件,需要先调用{@link #initLogFile(Context)}初始化日志路径才生效
- *
- * @param tag 日志标签
- * @param msg 日志内容
- */
- public void e_s(String tag, String msg) {
- e_s("", tag, msg);
- }
- public void e_s(String file, String tag, String msg) {
- if (msg.length() > 4000) {
- for (int i = 0; i < msg.length(); i += 4000) {
- if (i + 4000 < msg.length())
- internalSaveLog(file, tag, msg.substring(i, i + 4000));
- else
- internalSaveLog(file, tag, msg.substring(i, msg.length()));
- }
- } else {
- //直接打印
- internalSaveLog(file, tag, msg);
- }
- }
- /**
- * 打印日志并保存到文件,需要先调用{@link #initLogFile(Context)}初始化日志路径才生效
- *
- * @param tag 日志标签
- * @param msg 日志内容
- */
- public void d_s(String tag, String msg) {
- d_s("", tag, msg);
- }
- public void d_s(String file, String tag, String msg) {
- //直接打印
- e_s(file, tag, msg);
- }
- public void e(String tag, String msg) {
- Log.e(tag, msg);
- }
- public void d(String tag, String msg) {
- if (!open) {
- return;
- }
- Log.d(tag, msg);
- }
- /**
- * 获取程序缓存路径
- */
- public static String getDiskCacheDir(Context context) {
- boolean hasExternal = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
- File cacheDir = hasExternal ? context.getExternalCacheDir() : context.getCacheDir();
- return cacheDir.getAbsolutePath();
- }
- /**
- * 创建当前目录的文件夹
- */
- private void mkDir(String filePath) {
- File file = new File(filePath);
- if (!file.exists()) {
- file.mkdirs();
- }
- }
- /**
- * 删除当前日志
- */
- public void delectLogFile() {
- delectLogFile("");
- }
- public void delectLogFile(String file) {
- String logFilePath = logPaths.get(file);
- if (logFilePath != null) {
- synchronized (PlcLog.class) {
- File f = new File(logFilePath);
- f.delete();
- }
- }
- }
- public String e_s(String tag, Exception ex) {
- try {
- StringBuilder stringBuilder = new StringBuilder();
- StackTraceElement[] stackTraceElements = ex.getStackTrace();
- for (StackTraceElement element : stackTraceElements) {
- stringBuilder.append("\n" + element.toString());
- }
- e_s(tag, stringBuilder.toString());
- return stringBuilder.toString();
- } catch (Exception e) {
- }
- return "";
- }
- public String e_s(String tag, Throwable ex) {
- try {
- StringBuilder stringBuilder = new StringBuilder();
- StackTraceElement[] stackTraceElements = ex.getStackTrace();
- for (StackTraceElement element : stackTraceElements) {
- stringBuilder.append("\n" + element.toString());
- }
- e_s(tag, stringBuilder.toString());
- return stringBuilder.toString();
- } catch (Exception e) {
- }
- return "";
- }
- public void printCallerStracks() {
- e_s("Stack", getCallers());
- }
- public static String getCallers() {
- final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
- StringBuilder stringBuilder = new StringBuilder();
- try {
- for (int i = 4; i < 10; i++) {
- stringBuilder.append("\n" + "class:" + callStack[i].getClassName() + " line:" + callStack[i].getLineNumber() + ":" + callStack[i].getMethodName());
- }
- } catch (Exception e) {
- }
- return stringBuilder.toString();
- }
- public static long getEffectiveTime() {
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");// HH:mm:ss
- simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
- try {
- return simpleDateFormat.parse("2021-01-01").getTime();
- } catch (ParseException e) {
- e.printStackTrace();
- }
- return 0;
- }
- public ArrayList<String> getLogFilePaths() {
- return retFilePaths;
- }
- class ClickHelper {
- private long currentTime;
- private int timeOut;
- private volatile boolean lock = false;
- public ClickHelper(int timeOut) {
- this.timeOut = timeOut;
- }
- public boolean canClick() {
- if (lock) {
- currentTime = SystemClock.elapsedRealtime();
- //直接返回 false
- return false;
- }
- long time = SystemClock.elapsedRealtime();
- if ((time - currentTime) >= timeOut) {
- currentTime = time;
- return true;
- }
- return false;
- }
- public void setClickLock(boolean lock) {
- this.lock = lock;
- }
- }
- }
|