參考鏈接:https://blog.csdn.net/chiman6219/article/details/100646377
在做應用調試的時候,不可能時時通過USB線連着電腦去查看log信息,所以,將應用的log信息保存到手機本地就很有必要了,有助我們從這些log信息中提取有用的部分,以解決一些bug
/**
* 導出文件命令
* adb pull storage/emulated/0/IOVCloudMQTT_Logcat/mqttlogcat-20200515.log C:\Users\lenovo\Desktop
*/
public void getFilePath(View view) {
String logPath = LogcatMqttFileManager.getInstance().getLogPath();
if (!TextUtils.isEmpty(logPath)) {
showMessage("log file path=" + logPath);
} else {
showMessage("log file path is null");
}
}
public void verifyStoragePermissions() {
try {
//檢測是否有寫的權限
int permission = checkSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE");
if (permission != PackageManager.PERMISSION_GRANTED) {
// 沒有寫的權限,去申請寫的權限,會彈出對話框
requestPermissions(PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
} else {
//子線程輸出locat到文件
startLogcatManager();
//刪除三天前的文件
LogcatMqttFileManager.getInstance().removeFileByTime(folderPath);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class LogcatMqttFileManager {
private static LogcatMqttFileManager INSTANCE = null;
private static String PATH_LOGCAT;
// private String[] CMds;
private File logFile;
private LogDumper mLogDumper = null;
private int mPId;
private SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyyMMdd");
private SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final String TAG=LogcatMqttFileManager.class.getSimpleName();
public static LogcatMqttFileManager getInstance() {
if (INSTANCE == null) {
INSTANCE = new LogcatMqttFileManager();
}
return INSTANCE;
}
private LogcatMqttFileManager() {
mPId = android.os.Process.myPid();
}
private void setFolderPath(String folderPath) {
File folder = new File(folderPath);
if (!folder.exists() || !folder.isDirectory()) {
folder.mkdirs();
}
FLog.d(TAG,"folderPath=" + folderPath);
if (!folder.isDirectory())
throw new IllegalArgumentException("The logcat folder path is not a directory: " + folderPath);
PATH_LOGCAT = folderPath.endsWith("/") ? folderPath : folderPath + "/";
}
public void start(String saveDirectoy) {
//創建文件夾
setFolderPath(saveDirectoy);
//開啓子線程 過濾日誌
if (mLogDumper == null)
mLogDumper = new LogDumper(String.valueOf(mPId), PATH_LOGCAT);
mLogDumper.start();
}
public void stop() {
if (mLogDumper != null) {
mLogDumper.stopLogs();
mLogDumper = null;
}
}
public String getLogPath() {
if (logFile != null && logFile.getAbsolutePath() != null) {
return logFile.getAbsolutePath();
} else {
return null;
}
}
//移除文件,獲取文件時間與當前時間對比,我這時間定位3天,刪除3天前的文件
public void removeFileByTime(String dirPath) {
//獲取目錄下所有文件
List<File> allFile = getDirAllFile(new File(dirPath));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//獲取當前時間
Date end = new Date(System.currentTimeMillis());
try {
end = dateFormat.parse(dateFormat.format(new Date(System.currentTimeMillis())));
} catch (Exception e) {
FLog.d(TAG,"dataformat exeption e " + e.toString());
}
FLog.d(TAG,"getNeedRemoveFile dirPath = " + dirPath);
FLog.d(TAG,"getNeedRemoveFile allFile.size = " + allFile.size());
for (File file : allFile) {//ComDef
try {
//文件時間減去當前時間
Date start = dateFormat.parse(dateFormat.format(new Date(file.lastModified())));
long diff = end.getTime() - start.getTime();//這樣得到的差值是微秒級別
long days = diff / (1000 * 60 * 60 * 24);
FLog.d("days=" + days);
if (3 <= days) {
deleteFile(file);
}
} catch (Exception e) {
FLog.d(TAG,"dataformat exeption e " + e.toString());
}
}
}
//刪除文件夾及文件夾下所有文件
public static void deleteFile(File file) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
File f = files[i];
deleteFile(f);
}
file.delete();
} else if (file.exists()) {
file.delete();
}
}
//獲取指定目錄下一級文件
public static List<File> getDirAllFile(File file) {
List<File> fileList = new ArrayList<>();
File[] fileArray = file.listFiles();
if (fileArray == null)
return fileList;
for (File f : fileArray) {
fileList.add(f);
}
fileSortByTime(fileList);
return fileList;
}
//對文件進行時間排序
public static void fileSortByTime(List<File> fileList) {
Collections.sort(fileList, new Comparator<File>() {
public int compare(File p1, File p2) {
if (p1.lastModified() < p2.lastModified()) {
return -1;
}
return 1;
}
});
}
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;
logFile = new File(dir, "mqttlogcat-" + simpleDateFormat1.format(new Date()) + ".log");
FLog.d(TAG,"logFile="+logFile.getPath());
try {
out = new FileOutputStream(logFile, true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/**
*
* log level:*:v , *:d , *:w , *:e , *:f , *:s
*
* Show the current mPID process level of E and W log.
*
* */
// cmds = "logcat *:e *:w | grep \"(" + mPID + ")\"";
// cmds = "logcat | grep \"(" + mPID + ")\"";//show log of all level
// cmds = "logcat -s way";//Print label filtering information
// cmds = "logcat *:e *:i | grep \"(" + mPID + ")\"";
// cmds = "logcat | grep \"^..HttpLog\\|^..CloudSDK\" ";
cmds = "logcat -s IOVCloudMQTT | CloudSDK ";
// cmds = "logcat -s IOVCloudMQTT";
}
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;
FLog.d(TAG,"mRunning="+mRunning+";");
while (mRunning && (line = mReader.readLine()) != null) {
if (!mRunning) {
break;
}
if (line.length() == 0) {
continue;
}
if (out != null && line.contains(mPID)) {
out.write((simpleDateFormat2.format(new Date()) + " " + 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;
}
}
}
}
}