catalogue

  • 1. Business requirements
  • 2. What are the current practices and problems
  • 3. Customize the log tool class to print logs while writing files
  • 4. Enable the thread pool in the application to print logs
  • 5. Write a service to write system logs to a file

About the link

  • 1. Tech blog round-up
  • 2. Open source project summary
  • 3. Life Blog Summary
  • 4. Himalayan audio summary
  • 5. Summary of programmer chat notes
  • 5. Other summaries

1. Business requirements

  • All app system logs are written to files in the specified file directory
  • The written file is automatically switched to the next folder when it reaches a certain size
  • Requires the app to continuously write logs to a file while running
  • You can delete log files generated 7 or n days ago
  • Require sd card, write log to SD card; If not, write to memory card; If you go from no SD card to an SD card, you can switch paths
  • About code address can refer to: https://github.com/yangchong211/YCAudioPlayer

2. What are the current practices and problems

  • 1. Customize the log tool class to write output logs to a folder. However, only priority5 status logs can be logged
  • 2. Open the thread pool in application and call the setPrint method in PrintToFileUtil. Problem: The app cannot print continuously when it is always open. The reason has not been found
  • 3. When you start the app, start the Service service. If the app process is not killed or the service is not destroyed, the service will continue to run in the background and log printing logic can also be processed. And through broadcast can listen to SD status to achieve the purpose of switching log path

3. Customize the log tool class to print logs while writing files

  • 3.1 Direct call code is as follows:
public static void e(String msg) {
    if (isDebug){
        Log.e(TAG, msg);
        PrintToFileUtil.input2File(msg,"path"); }}Copy the code
  • 3.2 The following lists the tools
/** * Write log to file * /** write log to file * /** write log to file * / Avoid turning on thread-wasting performance everywhere * @param Input writes content * @param filePath path * @return
 */
static boolean input2File(final String input, final String filePath) {
    if(sExecutor == null) { sExecutor = Executors.newScheduledThreadPool(5); } Future<Boolean> submit = sExecutor.submit(new Callable<Boolean>() { @Override public Boolean call() throws Exception {  BufferedWriter bw = null; Try {// Constructs the FileWriter object for the given filename, using a Boolean value indicating whether to append the written data. FileWriter fileWriter = new FileWriter(filePath,true);
                bw = new BufferedWriter(fileWriter);
                bw.write(input);
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                try {
                    if(bw ! = null) { bw.close(); } } catch (IOException e) { e.printStackTrace(); }}}}); try {return submit.get();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    return false;
}
Copy the code

4. Enable the thread pool in the application to print logs

* 1. When to call this method? * 2. Why does calling this method cause the program to have no response? * 3. How to avoid thread blocking * 4. How to switch to the next.txt file after a certain log is printed? * @paramlogPath
 */
public static void setPrint(String logPath){
    if(sExecutor == null) { sExecutor = Executors.newScheduledThreadPool(5); Date now = new Date(system.currentTimemillis ()); String format = FORMAT.format(now); String date = format.substring(0, 5); final String newLogPath =logPath +date; Future<Boolean> submit = sExecutor.submit(new Callable<Boolean>() { @Override public Boolean call() throws Exception { /* Core code */while(captureLogThreadOpen){/ / ArrayList<String> getLog = new ArrayList<>(); getLog.add("logcat");
                getLog.add("-d");
                getLog.add("-v");
                getLog.add("time");
                ArrayList<String> clearLog = new ArrayList<>();
                clearLog.add("logcat");
                clearLog.add("-c"); Process Process = Runtime.geTruntime ().exec(getLog.toarray (new String[getlog.size ()]))); BufferedReader buffRead = new InputStreamReader(process.getinputStream ())); Runtime.getruntime ().exec(clearlog.toarray (new String[clearlog.size ()]))); String str = null; // Open the File FilelogFile = new File(newLogPath + "log.txt");
                    //trueFileOutputStream fos = new FileOutputStream(logFile, true); // NewLine String newLine = system.getProperty ("line.separator");
                    //Date date = new Date(System.currentTimeMillis());
                    //String time = format.format(date);

                    //Log.i(TAG, "thread"); // Print device information fos.write(printDeviceInfo().getBytes());

                    while((str=buffRead.readLine())! =null){// loop read each row // Runtime.geTruntime ().exec(clearlog.toarray (new String[clearlog.size ()])); //Log.i(TAG, str); @SuppressLint("SimpleDateFormat") Date date = new Date(System.currentTimeMillis()); String time = FORMAT.format(date); // Add year fos.write((time + STR).getbytes ()); / / a newline fos. Write (newline. GetBytes ());logCount++; Exit with more than 100000 linesif(logCount>100000){
                            captureLogThreadOpen = false;
                            fos.close();
                            break;
                        }
                    }
                    fos.close();
                    String[] strings = clearLog.toArray(new String[clearLog.size()]);
                    Runtime.getRuntime().exec(strings);
                    return true;
                }catch(Exception e){
                    e.printStackTrace();
                    return false; }}return true; }}); try { submit.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }}Copy the code

5. Write a service to write system logs to a file

  • 5.1 Document Key Points

    • 1. You can customize log writing paths and file names.
    • 2. If there is an SD card, record it in the SD card. Otherwise, records to the memory card;
    • 3. If the previous logs are recorded in a memory card and an SD card is available later, the files in the memory are copied to the SDCard
    • 4. You can listen to sd card loading and unloading broadcasts to change the path for saving logs
    • 5. You can set the maximum period for storing logs on the SD card. The current period is 7 days
    • 6. If the number of log files exceeds the maximum value (currently 10 MB), the system automatically switches to the next folder
    • 7. Clear the log cache. Clear the log cache before recording a log
    • 8. Collected logs include D, V, E, W, and C
    • 9. Supports automatic deletion of files after the maximum saving time is exceeded. The deletion logic is: compare the file name named by the date with the current time
    • 10. Open the service service when the app is started. The service will log and write to the file until the service is killed
    • 11. You are advised to name logs by date to facilitate the deletion logic
  • 5.2 Specific implementation code

    • 5.2.1 Register in manifest file
     <service android:name=".service.LogService"/ > <! -- System log permission --> <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    Copy the code
    • 5.2.2 The logService code is as follows
Public class LogService extends Service {// Private static final String TAG ="LogService"; // Maximum number of log files in memory, 10M private static final int MEMORY_LOG_FILE_MAX_SIZE = 10 * 1024 * 1024; Private static final int MEMORY_LOG_FILE_MONITOR_INTERVAL = 10 * 60 * 1000; private static final int MEMORY_LOG_FILE_MONITOR_INTERVAL = 10 * 60 * 1000; Private static final int SDCARD_LOG_FILE_SAVE_DAYS = 7; // Maximum number of days for saving log files on the SD card private static final int SDCARD_LOG_FILE_SAVE_DAYS = 7; // Path of log files in memory (path of log files in installation directory) private String LOG_PATH_MEMORY_DIR; Private String LOG_PATH_SDCARD_DIR; private String LOG_PATH_SDCARD_DIR; // The current log type is stored under the SD card. Private final int SDCARD_TYPE = 0; // The current logging type is stored in memory. Private final int MEMORY_TYPE = 1; Private int CURR_LOG_TYPE = SDCARD_TYPE; private int CURR_LOG_TYPE = SDCARD_TYPE; If the current log file is written to the memory, the current log file name is recorded. Private String CURR_INSTALL_LOG_NAME; // The name of the log file output by the service can be TXT or. Log private StringlogServiceLogName = "Log.log";

    @SuppressLint("SimpleDateFormat")
    private SimpleDateFormat myLogSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // Log name format @suppresslint ("SimpleDateFormat")
    private SimpleDateFormat sdf = new SimpleDateFormat("Yyyy-mm-dd HH MM minute ss second"); private OutputStreamWriter writer ; private Process process; // Wake up private powerManager. WakeLock WakeLock; //SDCard status monitoring, broadcast to monitor the SD card dynamic, such as the user to remove the SD card private SDStateMonitorReceiver sdStateReceiver; private LogTaskReceiverlogTaskReceiver; /* Whether the log file size is being monitored; * if the current log is logged in SDardfalse* If the current log is recorded in memorytrue*/
    private boolean logSizeMoniting = false; // Log file monitor action Private static String MONITOR_LOG_SIZE_ACTION ="MONITOR_LOG_SIZE"; Action Private static String SWITCH_LOG_FILE_ACTION ="SWITCH_LOG_FILE_ACTION"; @param intent intent * @returnIBinder object */ @override public IBinder onBind(Intent Intent) {returnnull; } /** * call this method */ @override public voidonDestroy() {
        super.onDestroy();
        recordLogServiceLog("LogService onDestroy");
        if (writer != null) {
            try {
                writer.close();
                writer = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(process ! = null) { process.destroy(); } // Notice that the broadcast needs to be unregisteredif(sdStateReceiver! =null){ unregisterReceiver(sdStateReceiver); }if(logTaskReceiver! =null){ unregisterReceiver(logTaskReceiver); }} /** * This method is called every time a service is started, and is used to initialize */ @override public voidonCreate() {
        super.onCreate();
        init();
        register();
        deploySwitchLogFileTask();
        new LogCollectorThread().start();
    }

    private void init(){// Path of log files in memory (path of log files in installation directory) LOG_PATH_MEMORY_DIR = getFilesDir().getabsolutePath () + file.separator +"log"; String LOG_SERVICE_LOG_PATH = LOG_PATH_MEMORY_DIR + file. separator +logServiceLogName; / / log file path in the sdcard LOG_PATH_SDCARD_DIR = FileUtils. GetLocalRootSavePathDir ("logger")+ File.separator + "log"; / / createlogFolder createLogDir (); try { //trueFileOutputStream fos = new FileOutputStream(LOG_SERVICE_LOG_PATH,true); writer = new OutputStreamWriter(fos); } catch (FileNotFoundException e) { Log.e(TAG, e.getMessage(), e); } PowerManager PM = (PowerManager) getApplicationContext().getSystemService(context.power_service);if(pm ! = null) { wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); } // The current log type CURR_LOG_TYPE = getCurrLogType(); Log.i(TAG,"LogService onCreate");
    }


    private void register(){
        IntentFilter sdCarMonitorFilter = new IntentFilter();
        sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
        sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
        sdCarMonitorFilter.addDataScheme("file");
        sdStateReceiver = new SDStateMonitorReceiver();
        registerReceiver(sdStateReceiver, sdCarMonitorFilter);

        IntentFilter logTaskFilter = new IntentFilter();
        logTaskFilter.addAction(MONITOR_LOG_SIZE_ACTION);
        logTaskFilter.addAction(SWITCH_LOG_FILE_ACTION);
        logTaskReceiver = new LogTaskReceiver();
        registerReceiver(logTaskReceiver,logTaskFilter); } /** * gets whether it should be stored in memory or in SDCard * @returnIf you have an SD card, put it in the SD card. If not, put it in memory card */ public intgetCurrLogType() {if(! Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {return MEMORY_TYPE;
        }else{
            returnSDCARD_TYPE; }} /** * Switches log files at dawn every day */ private voiddeploySwitchLogFileTask() { Intent intent = new Intent(SWITCH_LOG_FILE_ACTION); PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); // Deployment task AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);if(am ! = null) { am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, sender); } recordLogServiceLog("deployNextTask success,next task time is:"+myLogSdf.format(calendar.getTime())); } /** * log collection * 1. Clear the log cache * 2. Kill the Logcat process that the application has started to prevent multiple processes from writing to a log file * 3. Start the log collection process * 4. Process log files, move OR delete */ class LogCollectorThread extends Thread {LogCollectorThread(){
            super("LogCollectorThread");
            Log.d(TAG, "LogCollectorThread is create");
        }

        @SuppressLint("WakelockTimeout")
        @Override
        public void run() {try {// Wake up mobile wakelock.acquire (); ClearLogCache (); // Clear the log cache before each log. Otherwise, duplicate logs will be recorded in the two log files. List<String> orgProcessList = getAllProcess(); List<ProcessInfo> processInfoList = getProcessInfoList(orgProcessList); // Close the logcat process started by this programkillLogcatPro(processInfoList); CreateLogCollector (); Thread.sleep(1000); thread.sleep (1000); Loglog_handlelog (); // Loglog_handlelog (); / / release wakeLock. Release (); } catch (Exception e) { e.printStackTrace(); recordLogServiceLog(Log.getStackTraceString(e)); }}} /** * Clear the log cache before recording a log. Otherwise, duplicate logs will be recorded in two log files */ private voidclearLogCache() {
        Process pro = null;
        List<String> commandList = new ArrayList<>();
        commandList.add("logcat");
        commandList.add("-c");
        try {
            pro = Runtime.getRuntime().exec(commandList.toArray(new String[commandList.size()]));
            StreamConsumer errorGobbler = new StreamConsumer(pro.getErrorStream());
            StreamConsumer outputGobbler = new StreamConsumer(pro.getInputStream());
            errorGobbler.start();
            outputGobbler.start();
            if(pro.waitFor() ! = 0) { Log.e(TAG," clearLogCache proc.waitFor() ! = 0");
                recordLogServiceLog("clearLogCache clearLogCache proc.waitFor() ! = 0");
            }
        } catch (Exception e) {
            Log.e(TAG, "clearLogCache failed", e);
            recordLogServiceLog("clearLogCache failed");
        } finally {
            try {
                if(pro ! = null) { pro.destroy(); } } catch (Exception e) { Log.e(TAG,"clearLogCache failed", e);
                recordLogServiceLog("clearLogCache failed"); }}} /** * Close the logcat process started by this program: * If the Logcat log cache is not closed, multiple processes will read the Logcat log cache information and write it to the log file * @param allPro allPro */ private voidkillLogcatPro(List<ProcessInfo> allPro) {
        if(process ! = null){ process.destroy(); } String packName = this.getPackageName(); String myUser = getAppUser(packName, allPro);for (ProcessInfo processInfo : allPro) {
            if (processInfo.name.toLowerCase().equals("logcat") && processInfo.user.equals(myUser)) {
                android.os.Process.killProcess(Integer.parseInt(processInfo.pid));
                //recordLogServiceLog("kill another logcat process success,the process info is:"// + processInfo); }} /** * Get the user name of this program * @param packName packName * @param allProList allProList * @returnPrivate String getAppUser(String packName, List<ProcessInfo> allProList) {private String getAppUser(String packName, List<ProcessInfo> allProList) {for (ProcessInfo processInfo : allProList) {
            if (processInfo.name.equals(packName)) {
                returnprocessInfo.user; }}returnnull; @param orgProcessList orgProcessList * @param orgProcessList * @param orgProcessListreturnCollection */ private List<ProcessInfo> getProcessInfoList(List<String> orgProcessList) {List<ProcessInfo> proInfoList = new ArrayList<>();for (int i = 1; i < orgProcessList.size(); i++) {
            String processInfo = orgProcessList.get(i);
            String[] proStr = processInfo.split("");
            // USER PID PPID VSIZE RSS WCHAN PC NAME
            // root 1 0 416 300 c00d4b28 0000cd5c S /init
            List<String> orgInfo = new ArrayList<>();
            for (String str : proStr) {
                if (!"".equals(str)) { orgInfo.add(str); }}if(orgInfo.size() == 9) { ProcessInfo pInfo = new ProcessInfo(); pInfo.user = orgInfo.get(0); pInfo.pid = orgInfo.get(1); pInfo.ppid = orgInfo.get(2); pInfo.name = orgInfo.get(8); proInfoList.add(pInfo); }}returnproInfoList; } /** * Run the PS command to get the process information * @return
     *          USER PID PPID VSIZE RSS WCHAN PC NAME
     *          root 1 0 416 300 c00d4b28 0000cd5c S /init
     */
    private List<String> getAllProcess() {
        List<String> orgProList = new ArrayList<>();
        Process pro = null;
        try {
            pro = Runtime.getRuntime().exec("ps");
            StreamConsumer errorConsumer = new StreamConsumer(pro.getErrorStream());
            StreamConsumer outputConsumer = new StreamConsumer(pro.getInputStream(), orgProList);
            errorConsumer.start();
            outputConsumer.start();
            if(pro.waitFor() ! = 0) { Log.e(TAG,"getAllProcess pro.waitFor() ! = 0");
                recordLogServiceLog("getAllProcess pro.waitFor() ! = 0");
            }
        } catch (Exception e) {
            Log.e(TAG, "getAllProcess failed", e);
            recordLogServiceLog("getAllProcess failed");
        } finally {
            try {
                if(pro ! = null) { pro.destroy(); } } catch (Exception e) { Log.e(TAG,"getAllProcess failed", e);
                recordLogServiceLog("getAllProcess failed"); }}returnorgProList; } /** * Start collecting logs * Logs include, f, d, v, time, */ public voidcreateLogCollector() {// Log file name StringlogFileName = sdf.format(new Date()) + ".log";
        List<String> commandList = new ArrayList<>();
        commandList.add("logcat");
        commandList.add("-f");
        commandList.add("-d");
        //commandList.add(LOG_PATH_INSTALL_DIR + File.separator + logFileName);
        commandList.add(getLogPath());
        commandList.add("-v");
        commandList.add("time"); // Filter all I informationcommandList.add("*:I"); // Filter all error messages //commandList.add("*:E"); // Filter the information of the specified TAGcommandList.add("MyAPP:V");
        // commandList.add("*:S");
        try {
            process = Runtime.getRuntime().exec(commandList.toArray(new String[commandList.size()]));
            recordLogServiceLog("start collecting the log,and log name is:"+logFileName);
            // process.waitFor();
        } catch (Exception e) {
            Log.e(TAG, "CollectorThread == >" + e.getMessage(), e);
            recordLogServiceLog("CollectorThread == >"+ e.getMessage()); }} /** * Obtain the absolute log storage path * @ based on the current storage locationreturnPath */ public StringgetLogPath(){ createLogDir(); // Log file name StringlogFileName = sdf.format(new Date()) + ".log";
        if(CURR_LOG_TYPE == MEMORY_TYPE){
            CURR_INSTALL_LOG_NAME = logFileName;
            Log.d(TAG, "Log stored in memory, the path is:"+LOG_PATH_MEMORY_DIR + File.separator + logFileName);
            return LOG_PATH_MEMORY_DIR + File.separator + logFileName;
        }else{
            CURR_INSTALL_LOG_NAME = null;
            Log.d(TAG, "Log stored in SDcard, the path is:"+LOG_PATH_SDCARD_DIR + File.separator + logFileName);
            return LOG_PATH_SDCARD_DIR + File.separator + logFileName; If the storage location of the log file is switched to the memory, delete the log file being written * and deploy a task to monitor the log size to ensure that the log size does not exceed the specified value * 2. If the storage location of log files is switched to the SDCard, delete logs generated 7 days ago, move all logs stored in the memory to the SDCard, and cancel the previously deployed log size */ public voidhandleLog(){// The current logging type is stored in memoryif(CURR_LOG_TYPE == MEMORY_TYPE){// Deploy log size monitoring task deployLogSizeMonitorTask(); DeleteMemoryExpiredLog (); }else{// Move the log file to moveLogfile(); CancelLogSizeMonitorTask (); DeleteSDCardExpiredLog (); }} /** * Deploy a log size monitoring task */ private voiddeployLogSizeMonitorTask() {// If you are currently monitoring, you do not need to continue deploymentif(logSizeMoniting){
            return;
        }
        logSizeMoniting = true;
        Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);
        PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
        AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
        if(am ! = null) { am.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), MEMORY_LOG_FILE_MONITOR_INTERVAL, sender);  } Log.d(TAG,"deployLogSizeMonitorTask() suc !");
        //recordLogServiceLog("deployLogSizeMonitorTask() succ ,start time is "+ calendar.getTime().toLocaleString()); } /** * Cancel the deployment log size monitoring task */ private voidcancelLogSizeMonitorTask() {
        logSizeMoniting = false;
        AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);
        PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
        if(am ! = null) { am.cancel(sender); } Log.d(TAG,"canelLogSizeMonitorTask() suc"); } /** * Check whether the log file size exceeds the specified size * if so, restart a log collection process */ private voidcheckLogSize(){// When the file is not emptyif(CURR_INSTALL_LOG_NAME ! = null && curr_install_log_name.length ()>0){// Log file path in memory + If the current log file is written in memory, Separator + CURR_INSTALL_LOG_NAME; String PATH = LOG_PATH_MEMORY_DIR + file. separator + CURR_INSTALL_LOG_NAME; File file = new File(path);if(! file.exists()){return;
            }
            Log.d(TAG, "checkLog() ==> The size of the log is too big?"); // If the file length is greater than or equal to 10M, create a new folderif(file.length() >= MEMORY_LOG_FILE_MAX_SIZE){
                Log.d(TAG, "The log's size is too big!"); new LogCollectorThread().start(); }}} /** * Create log directory */ private voidcreateLogDir() {// Log files in memory path folder File File = new File(LOG_PATH_MEMORY_DIR); boolean mkOk;if(! file.isDirectory() && file.exists()) { mkOk = file.mkdirs();if(! mkOk) { //noinspection ResultOfMethodCallIgnored file.mkdirs(); }} // Check whether the SD card exists and has read and write permissions. // Create a folder in the SD card pathif (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            file = new File(LOG_PATH_SDCARD_DIR);
            if(! file.isDirectory()) { mkOk = file.mkdirs();if(! mkOk) { recordLogServiceLog("move file failed,dir is not created succ"); }}}} /** * Transfer the log file to the SD card */ private voidmoveLogfile() {// First check the SD card statusif(! Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //recordLogServiceLog("move file failed, sd card does not mount");
            return;
        }
        File file = new File(LOG_PATH_SDCARD_DIR);
        if(! file.isDirectory()) { boolean mkOk = file.mkdirs();if(! mkOk) { //recordLogServiceLog("move file failed,dir is not created succ");
                return;
            }
        }

        file = new File(LOG_PATH_MEMORY_DIR);
        if (file.isDirectory()) {
            File[] allFiles = file.listFiles();
            for (File logFile : allFiles) {
                String fileName = logFile.getName();
                if (logServiceLogName.equals(fileName)) {
                    continue;
                }
                //String createDateInfo = getFileNameWithoutExtension(fileName);
                File beforeFile = new File(LOG_PATH_SDCARD_DIR + File.separator + fileName);
                boolean isSuccess = copy(logFile,beforeFile);
                if (isSuccess) {
                    //noinspection ResultOfMethodCallIgnored
                    logFile.delete();
                    //recordLogServiceLog("move file success,log name is:"+fileName); }}}} /** * Delete expired logs */ private voiddeleteSDCardExpiredLog() {
        File file = new File(LOG_PATH_SDCARD_DIR);
        if (file.isDirectory()) {
            File[] allFiles = file.listFiles();
            for (File logFile : allFiles) {
                String fileName = logFile.getName();
                if (logServiceLogName.equals(fileName)) {
                    continue; } / / remove the file extension type String createDateInfo = getFileNameWithoutExtension (fileName); // Check whether the log file on sdcard can be deletedif (canDeleteSDLog(createDateInfo)) {
                    //noinspection ResultOfMethodCallIgnored
                    logFile.delete();
                    Log.d(TAG, "delete expired log success,the log path is:" + logFile.getAbsolutePath()); }}}} /** * Check whether the log file on sdcard can be deleted * @param createDateStr createDateStr * @return*/ public Boolean canDeleteSDLog(String createDateStr) {Boolean canDel; Calendar = calendar.getInstance (); DAY_OF_MONTH, -1 * SDCARD_LOG_FILE_SAVE_DAYS); // Delete calendar.add(calendar. DAY_OF_MONTH, -1 * SDCARD_LOG_FILE_SAVE_DAYS); Date expiredDate = calendar.getTime(); try { Date createDate = sdf.parse(createDateStr); canDel = createDate.before(expiredDate); } catch (ParseException e) { Log.e(TAG, e.getMessage(), e); canDel =false;
        }
        returncanDel; } /** * Delete expired logs in memory. Delete all logs except the current log and the latest log. */ private voiddeleteMemoryExpiredLog(){
        File file = new File(LOG_PATH_MEMORY_DIR);
        if (file.isDirectory()) {
            File[] allFiles = file.listFiles();
            Arrays.sort(allFiles, new FileComparator());
            for(int i=0; i<allFiles.length-2; i++) { //"- 2"File _file = allFiles[I];if (logServiceLogName.equals(_file.getName()) ||  _file.getName().equals(CURR_INSTALL_LOG_NAME)) {
                    continue;
                }
                //noinspection ResultOfMethodCallIgnored
                _file.delete();
                Log.d(TAG, "delete expired log success,the log path is:"+_file.getAbsolutePath()); }}} /** * Copy the file * @paramsource                    file
     * @param target                    file
     * @return*/ private Boolean Copy (File)source, File target) {
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            if(! target.exists()){ boolean createSuccess = target.createNewFile();if(! createSuccess){return false; }}in = new FileInputStream(source);
            out = new FileOutputStream(target);
            byte[] buffer = new byte[8*1024];
            int count;
            while((count = in.read(buffer)) ! = -1) { out.write(buffer, 0, count); }return true;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, e.getMessage(), e);
            recordLogServiceLog("copy file fail");
            return false;
        } finally{
            try {
                if(in! = null){ in.close(); }if(out ! = null){ out.close(); } } catch (IOException e) { e.printStackTrace(); Log.e(TAG, e.getMessage(), e); recordLogServiceLog("copy file fail"); }}} /** * This note is to record the error of the log service * log basic information to prevent errors in the log service, Log.log * @param MSG MSG */ private void recordLogServiceLog(String MSG) {if(writer ! = null) { try { Date time = new Date(); writer.write(myLogSdf.format(time) +":" + msg);
                writer.write("\n"); writer.flush(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, e.getMessage(), e); }}} /** * Remove the file extension type (.log) * @param fileName fileName * @return* / private String String getFileNameWithoutExtension (String fileName) {return fileName.substring(0, fileName.indexOf("."));
    }

    class ProcessInfo {
        public String user;
        private String pid;
        private String ppid;
        public String name;

        @Override
        public String toString() {
            return "ProcessInfo{" +
                    "user='" + user + '\'' + ", pid='" + pid + '\'' + ", ppid='" + ppid + '\' ' +
                    ", name='" + name + '\''+'}'; } } class StreamConsumer extends Thread { InputStream is; List
      
        list; StreamConsumer(InputStream is) { this.is = is; } StreamConsumer(InputStream is, List
       
         list) { this.is = is; this.list = list; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line ; while ((line = br.readLine()) ! = null) { if (list ! = null) { list.add(line); } } } catch (IOException ioe) { ioe.printStackTrace(); }} /** * Monitor SD card status * @author Administrator ** / private class SDStateMonitorReceiver extends BroadcastReceiver {public  void onReceive(Context context, Intent.action_media_unmounted. Equals (intent.getAction())){if(intent.action_media_unmounted SDCARD_TYPE){ Log.d(TAG, "SDCard is UNMOUNTED"); CURR_LOG_TYPE = MEMORY_TYPE; new LogCollectorThread().start(); If (CURR_LOG_TYPE == MEMORY_TYPE){log. d(TAG, "SDCard is MOUNTED"); // If (CURR_LOG_TYPE == MEMORY_TYPE){log. d(TAG, "SDCard is MOUNTED"); CURR_LOG_TYPE = SDCARD_TYPE; new LogCollectorThread().start(); }}}} /** * Log task Receives broadcast * Switch log, Monitor log size * @author Administrator * */ class LogTaskReceiver extends BroadcastReceiver{public void onReceive(Context) context, Intent intent) { String action = intent.getAction(); Action if(switch_log_file_action.equals (action)){new LogCollectorThread().start(); }else if(monitor_log_size_action.equals (action)){// The log file monitors action checkLogSize(); } } } class FileComparator implements Comparator
        
          { public int compare(File file1, File file2) { if(logServiceLogName.equals(file1.getName())){ return -1; }else if(logServiceLogName.equals(file2.getName())){ return 1; } String createInfo1 = getFileNameWithoutExtension(file1.getName()); String createInfo2 = getFileNameWithoutExtension(file2.getName()); try { Date create1 = sdf.parse(createInfo1); Date create2 = sdf.parse(createInfo2); if(create1.before(create2)){ return -1; }else{ return 1; } } catch (ParseException e) { return 0; }}}}
        
       
      Copy the code