1. 程式人生 > >android開發 獲取logcat日誌並記錄(方便離線除錯)

android開發 獲取logcat日誌並記錄(方便離線除錯)

案例:當我們的軟體安裝在手機上的時候,或許還需要知道整個軟體執行的情況,那麼我們就需要一種把軟體執行的狀況記錄下來,儲存在某個地方(本地檔案,以下就是解決方法

直接上程式碼:

  1. package com.ifeng.fhdt.service;  
  2. import java.io.BufferedReader;  
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.io.InputStream;  
  8. import java.io.InputStreamReader;  
  9. import java.io.OutputStreamWriter;  
  10. import java.text.ParseException;  
  11. import java.text.SimpleDateFormat;  
  12. import java.util.ArrayList;  
  13. import java.util.Arrays;  
  14. import java.util.Calendar;  
  15. import java.util.Comparator;  
  16. import java.util.Date;  
  17. import java.util.List;  
  18. import android.app.AlarmManager;  
  19. import android.app.PendingIntent;  
  20. import android.app.Service;  
  21. import android.content.BroadcastReceiver;  
  22. import android.content.Context;  
  23. import android.content.Intent;  
  24. import android.content.IntentFilter;  
  25. import android.os.Environment;  
  26. import android.os.IBinder;  
  27. import android.os.PowerManager;  
  28. import android.os.PowerManager.WakeLock;  
  29. import android.util.Log;  
  30. /** 
  31.  * 日誌服務,日誌預設會儲存在SDcar裡如果沒有SDcard會儲存在記憶體中的安裝目錄下面。 
  32.  * 1.本服務預設在SDcard中每天生成一個日誌檔案, 
  33.  * 2.如果有SDCard的話會將之前記憶體中的檔案拷貝到SDCard中 
  34.  * 3.如果沒有SDCard,在安裝目錄下只儲存當前在寫日誌 
  35.  * 4.SDcard的裝載解除安裝動作會在步驟2,3中切換 
  36.  * 5.SDcard中的日誌檔案只儲存7天 
  37.  * @author Administrator 
  38.  *  
  39.  */
  40. publicclass LogService extends Service {  
  41.     privatestaticfinal String TAG = "LogService";  
  42.     privatestaticfinalint MEMORY_LOG_FILE_MAX_SIZE = 10 * 1024 * 1024;           //記憶體中日誌檔案最大值,10M
  43.     privatestaticfinalint MEMORY_LOG_FILE_MONITOR_INTERVAL = 10 * 60 * 1000;     //記憶體中的日誌檔案大小監控時間間隔,10分鐘
  44.     privatestaticfinalint SDCARD_LOG_FILE_SAVE_DAYS = 7;                         //sd卡中日誌檔案的最多儲存天數
  45.     private String LOG_PATH_MEMORY_DIR;     //日誌檔案在記憶體中的路徑(日誌檔案在安裝目錄中的路徑)
  46.     private String LOG_PATH_SDCARD_DIR;     //日誌檔案在sdcard中的路徑
  47.     @SuppressWarnings("unused")  
  48.     private String LOG_SERVICE_LOG_PATH;    //本服務產生的日誌,記錄日誌服務開啟失敗資訊
  49.     privatefinalint SDCARD_TYPE = 0;          //當前的日誌記錄型別為儲存在SD卡下面
  50.     privatefinalint MEMORY_TYPE = 1;          //當前的日誌記錄型別為儲存在記憶體中
  51.     privateint CURR_LOG_TYPE = SDCARD_TYPE;    //當前的日誌記錄型別
  52.     private String CURR_INSTALL_LOG_NAME;   //如果當前的日誌寫在記憶體中,記錄當前的日誌檔名稱
  53.     private String logServiceLogName = "Log.log";//本服務輸出的日誌檔名稱
  54.     private SimpleDateFormat myLogSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  55.     private OutputStreamWriter writer;  
  56.     private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HHmmss");//日誌名稱格式
  57.     private Process process;  
  58.     private WakeLock wakeLock;    
  59.     private SDStateMonitorReceiver sdStateReceiver; //SDcard狀態監測
  60.     private LogTaskReceiver logTaskReceiver;   
  61.     /* 是否正在監測日誌檔案大小; 
  62.      * 如果當前日誌記錄在SDcard中則為false 
  63.      * 如果當前日誌記錄在記憶體中則為true*/
  64.     privateboolean logSizeMoniting = false;          
  65.     privatestatic String MONITOR_LOG_SIZE_ACTION = "MONITOR_LOG_SIZE";     //日誌檔案監測action
  66.     privatestatic String SWITCH_LOG_FILE_ACTION = "SWITCH_LOG_FILE_ACTION";    //切換日誌檔案action
  67.     @Override
  68.     public IBinder onBind(Intent intent) {  
  69.         returnnull;  
  70.     }  
  71.     @Override
  72.     publicvoid onCreate() {  
  73.         super.onCreate();  
  74.         init();  
  75.         register();  
  76.         deploySwitchLogFileTask();    
  77.         new LogCollectorThread().start();  
  78.     }  
  79.     privatevoid init(){  
  80.         LOG_PATH_MEMORY_DIR = getFilesDir().getAbsolutePath() + File.separator + "log";  
  81.         LOG_SERVICE_LOG_PATH = LOG_PATH_MEMORY_DIR + File.separator + logServiceLogName;  
  82.         LOG_PATH_SDCARD_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator  
  83.                             +   "MyApp" + File.separator + "log";  
  84.         createLogDir();  
  85.         /* ****************************************************** 
  86.         try { 
  87.             writer = new OutputStreamWriter(new FileOutputStream( 
  88.                     LOG_SERVICE_LOG_PATH, true)); 
  89.         } catch (FileNotFoundException e) { 
  90.             Log.e(TAG, e.getMessage(), e); 
  91.         } 
  92.         * ******************************************************/
  93.         PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);  
  94.         wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);  
  95.         CURR_LOG_TYPE = getCurrLogType();  
  96.         Log.i(TAG, "LogService onCreate");  
  97.     }  
  98.     privatevoid register(){  
  99.         IntentFilter sdCarMonitorFilter = new IntentFilter();  
  100.         sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);  
  101.         sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);  
  102.         sdCarMonitorFilter.addDataScheme("file");  
  103.         sdStateReceiver = new SDStateMonitorReceiver();  
  104.         registerReceiver(sdStateReceiver, sdCarMonitorFilter);  
  105.         IntentFilter logTaskFilter = new IntentFilter();  
  106.         logTaskFilter.addAction(MONITOR_LOG_SIZE_ACTION);  
  107.         logTaskFilter.addAction(SWITCH_LOG_FILE_ACTION);  
  108.         logTaskReceiver = new LogTaskReceiver();  
  109.         registerReceiver(logTaskReceiver,logTaskFilter);  
  110.     }  
  111.     /** 
  112.      * 獲取當前應儲存在記憶體中還是儲存在SDCard中 
  113.      * @return 
  114.      */
  115.     publicint getCurrLogType(){  
  116.         if (!Environment.getExternalStorageState().equals(  
  117.                 Environment.MEDIA_MOUNTED)) {  
  118.             return MEMORY_TYPE;  
  119.         }else{  
  120.             return SDCARD_TYPE;  
  121.         }  
  122.     }  
  123.     /** 
  124.      * 部署日誌切換任務,每天凌晨切換日誌檔案 
  125.      */
  126.     privatevoid deploySwitchLogFileTask() {  
  127.         Intent intent = new Intent(SWITCH_LOG_FILE_ACTION);  
  128.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  
  129.         Calendar calendar = Calendar.getInstance();  
  130.         calendar.add(Calendar.DAY_OF_MONTH, 1);  
  131.         calendar.set(Calendar.HOUR_OF_DAY, 0);  
  132.         calendar.set(Calendar.MINUTE, 0);  
  133.         calendar.set(Calendar.SECOND, 0);  
  134.         // 部署任務
  135.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  
  136.         am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, sender);  
  137.         recordLogServiceLog("deployNextTask succ,next task time is:"+myLogSdf.format(calendar.getTime()));  
  138.     }  
  139.     /** 
  140.      * 日誌收集 
  141.      * 1.清除日誌快取  
  142.      * 2.殺死應用程式已開啟的Logcat程序防止多個程序寫入一個日誌檔案 
  143.      * 3.開啟日誌收集程序  
  144.      * 4.處理日誌檔案 
  145.      *   移動 OR 刪除 
  146.      */
  147.     class LogCollectorThread extends Thread {  
  148.         public LogCollectorThread(){  
  149.             super("LogCollectorThread");  
  150.             Log.d(TAG, "LogCollectorThread is create");  
  151.         }  
  152.         @Override
  153.         publicvoid run() {  
  154.             try {  
  155.                 wakeLock.acquire(); //喚醒手機
  156.                 clearLogCache();  
  157.                 List<String> orgProcessList = getAllProcess();  
  158.                 List<ProcessInfo> processInfoList = getProcessInfoList(orgProcessList);  
  159.                 killLogcatProc(processInfoList);  
  160.                 createLogCollector();  
  161.                 Thread.sleep(1000);//休眠,建立檔案,然後處理檔案,不然該檔案還沒建立,會影響檔案刪除
  162.                 handleLog();  
  163.                 wakeLock.release(); //釋放
  164.             } catch (Exception e) {  
  165.                 e.printStackTrace();  
  166.                 recordLogServiceLog(Log.getStackTraceString(e));  
  167.             }  
  168.         }  
  169.     }  
  170.     /** 
  171.      * 每次記錄日誌之前先清除日誌的快取, 不然會在兩個日誌檔案中記錄重複的日誌 
  172.      */
  173.     privatevoid clearLogCache() {  
  174.         Process proc = null;  
  175.         List<String> commandList = new ArrayList<String>();  
  176.         commandList.add("logcat");  
  177.         commandList.add("-c");  
  178.         try {  
  179.             proc = Runtime.getRuntime().exec(  
  180.                     commandList.toArray(new String[commandList.size()]));  
  181.             StreamConsumer errorGobbler = new StreamConsumer(proc  
  182.                     .getErrorStream());  
  183.             StreamConsumer outputGobbler = new StreamConsumer(proc  
  184.                     .getInputStream());  
  185.             errorGobbler.start();  
  186.             outputGobbler.start();  
  187.             if (proc.waitFor() != 0) {  
  188.                 Log.e(TAG, " clearLogCache proc.waitFor() != 0");  
  189.                 recordLogServiceLog("clearLogCache clearLogCache proc.waitFor() != 0");  
  190.             }  
  191.         } catch (Exception e) {  
  192.             Log.e(TAG, "clearLogCache failed", e);  
  193.             recordLogServiceLog("clearLogCache failed");  
  194.         } finally {  
  195.             try {  
  196.                 proc.destroy();  
  197.             } catch (Exception e) {  
  198.                 Log.e(TAG, "clearLogCache failed", e);  
  199.                 recordLogServiceLog("clearLogCache failed");  
  200.             }  
  201.         }  
  202.     }  
  203.     /** 
  204.      * 關閉由本程式開啟的logcat程序: 
  205.      * 根據使用者名稱稱殺死程序(如果是本程式程序開啟的Logcat收集程序那麼兩者的USER一致) 
  206.      * 如果不關閉會有多個程序讀取logcat日誌快取資訊寫入日誌檔案 
  207.      *  
  208.      * @param allProcList 
  209.      * @return 
  210.      */
  211.     privatevoid killLogcatProc(List<ProcessInfo> allProcList) {  
  212.         if(process != null){  
  213.             process.destroy();  
  214.         }  
  215.         String packName = this.getPackageName();  
  216.         String myUser = getAppUser(packName, allProcList);  
  217.         /* 
  218.         recordLogServiceLog("app user is:"+myUser); 
  219.         recordLogServiceLog("========================"); 
  220.         for (ProcessInfo processInfo : allProcList) { 
  221.             recordLogServiceLog(processInfo.toString()); 
  222.         } 
  223.         recordLogServiceLog("========================"); 
  224.         */
  225.         for (ProcessInfo processInfo : allProcList) {  
  226.             if (processInfo.name.toLowerCase().equals("logcat")  
  227.                     && processInfo.user.equals(myUser)) {  
  228.                 android.os.Process.killProcess(Integer  
  229.                         .parseInt(processInfo.pid));  
  230.                 //recordLogServiceLog("kill another logcat process success,the process info is:"
  231.                 //      + processInfo);
  232.             }  
  233.         }  
  234.     }  
  235.     /** 
  236.      * 獲取本程式的使用者名稱稱 
  237.      *  
  238.      * @param packName 
  239.      * @param allProcList 
  240.      * @return 
  241.      */
  242.     private String getAppUser(String packName, List<ProcessInfo> allProcList) {  
  243.         for (ProcessInfo processInfo : allProcList) {  
  244.             if (processInfo.name.equals(packName)) {  
  245.                 return processInfo.user;  
  246.             }  
  247.         }  
  248.         returnnull;  
  249.     }  
  250.     /** 
  251.      * 根據ps命令得到的內容獲取PID,User,name等資訊 
  252.      *  
  253.      * @param orgProcessList 
  254.      * @return 
  255.      */
  256.     private List<ProcessInfo> getProcessInfoList(List<String> orgProcessList) {  
  257.         List<ProcessInfo> procInfoList = new ArrayList<ProcessInfo>();  
  258.         for (int i = 1; i < orgProcessList.size(); i++) {  
  259.             String processInfo = orgProcessList.get(i);  
  260.             String[] proStr = processInfo.split(" ");  
  261.             // USER PID PPID VSIZE RSS WCHAN PC NAME
  262.             // root 1 0 416 300 c00d4b28 0000cd5c S /init
  263.             List<String> orgInfo = new ArrayList<String>();  
  264.             for (String str : proStr) {  
  265.                 if (!"".equals(str)) {  
  266.                     orgInfo.add(str);  
  267.                 }  
  268.             }  
  269.             if (orgInfo.size() == 9) {  
  270.                 ProcessInfo pInfo = new ProcessInfo();  
  271.                 pInfo.user = orgInfo.get(0);  
  272.                 pInfo.pid = orgInfo.get(1);  
  273.                 pInfo.ppid = orgInfo.get(2);  
  274.                 pInfo.name = orgInfo.get(8);  
  275.                 procInfoList.add(pInfo);  
  276.             }  
  277.         }  
  278.         return procInfoList;  
  279.     }  
  280.     /** 
  281.      * 執行PS命令得到程序資訊 
  282.      *  
  283.      * @return 
  284.      *          USER PID PPID VSIZE RSS WCHAN PC NAME 
  285.      *          root 1 0 416 300 c00d4b28 0000cd5c S /init 
  286.      */
  287.     private List<String> getAllProcess() {  
  288.         List<String> orgProcList = new ArrayList<String>();  
  289.         Process proc = null;  
  290.         try {  
  291.             proc = Runtime.getRuntime().exec("ps");  
  292.             StreamConsumer errorConsumer = new StreamConsumer(proc  
  293.                     .getErrorStream());  
  294.             StreamConsumer outputConsumer = new StreamConsumer(proc  
  295.                     .getInputStream(), orgProcList);  
  296.             errorConsumer.start();  
  297.             outputConsumer.start();  
  298.             if (proc.waitFor() != 0) {  
  299.                 Log.e(TAG, "getAllProcess proc.waitFor() != 0");  
  300.                 recordLogServiceLog("getAllProcess proc.waitFor() != 0");  
  301.             }  
  302.         } catch (Exception e) {  
  303.             Log.e(TAG, "getAllProcess failed", e);  
  304.             recordLogServiceLog("getAllProcess failed");  
  305.         } finally {  
  306.             try {  
  307.                 proc.destroy();  
  308.             } catch (Exception e) {  
  309.                 Log.e(TAG, "getAllProcess failed", e);  
  310.                 recordLogServiceLog("getAllProcess failed");  
  311.             }  
  312.         }  
  313.         return orgProcList;  
  314.     }  
  315.     /** 
  316.      * 開始收集日誌資訊 
  317.      */
  318.     publicvoid createLogCollector() {  
  319.         String logFileName = sdf.format(new Date()) + ".log";// 日誌檔名稱
  320.         List<String> commandList = new ArrayList<String>();  
  321.         commandList.add("logcat");  
  322.         commandList.add("-f");  
  323.         //commandList.add(LOG_PATH_INSTALL_DIR + File.separator + logFileName);
  324.         commandList.add(getLogPath());  
  325.         commandList.add("-v");  
  326.         commandList.add("time");  
  327.         commandList.add("*:w");  
  328.         //commandList.add("*:E");// 過濾所有的錯誤資訊
  329.         // 過濾指定TAG的資訊
  330.         // commandList.add("MyAPP:V");
  331.         // commandList.add("*:S");
  332.         try {  
  333.             process = Runtime.getRuntime().exec(  
  334.                     commandList.toArray(new String[commandList.size()]));  
  335.             recordLogServiceLog("start collecting the log,and log name is:"+logFileName);  
  336.             // process.waitFor();
  337.         } catch (Exception e) {  
  338.             Log.e(TAG, "CollectorThread == >" + e.getMessage(), e);  
  339.             recordLogServiceLog("CollectorThread == >" + e.getMessage());  
  340.         }  
  341.     }  
  342.     /** 
  343.      * 根據當前的儲存位置得到日誌的絕對儲存路徑 
  344.      * @return 
  345.      */
  346.     public String getLogPath(){  
  347.         createLogDir();  
  348.         String logFileName = sdf.format(new Date()) + ".log";// 日誌檔名稱
  349.         if(CURR_LOG_TYPE == MEMORY_TYPE){  
  350.             CURR_INSTALL_LOG_NAME = logFileName;  
  351.             Log.d(TAG, "Log stored in memory, the path is:"+LOG_PATH_MEMORY_DIR + File.separator + logFileName);  
  352.             return LOG_PATH_MEMORY_DIR + File.separator + logFileName;  
  353.         }else{  
  354.             CURR_INSTALL_LOG_NAME = null;  
  355.             Log.d(TAG, "Log stored in SDcard, the path is:"+LOG_PATH_SDCARD_DIR + File.separator + logFileName);  
  356.             return LOG_PATH_SDCARD_DIR + File.separator + logFileName;  
  357.         }  
  358.     }  
  359.     /** 
  360.      * 處理日誌檔案 
  361.      * 1.如果日誌檔案儲存位置切換到記憶體中,刪除除了正在寫的日誌檔案 
  362.      *   並且部署日誌大小監控任務,控制日誌大小不超過規定值 
  363.      * 2.如果日誌檔案儲存位置切換到SDCard中,刪除7天之前的日誌,移 
  364.      *     動所有儲存在記憶體中的日誌到SDCard中,並將之前部署的日誌大小 
  365.      *   監控取消 
  366.      */
  367.     publicvoid handleLog(){  
  368.         if(CURR_LOG_TYPE == MEMORY_TYPE){  
  369.             deployLogSizeMonitorTask();  
  370.             deleteMemoryExpiredLog();  
  371.         }else{  
  372.             moveLogfile();  
  373.             cancelLogSizeMonitorTask();  
  374.             deleteSDcardExpiredLog();  
  375.         }  
  376.     }  
  377.     /** 
  378.      * 部署日誌大小監控任務 
  379.      */
  380.     privatevoid deployLogSizeMonitorTask() {  
  381.         if(logSizeMoniting){    //如果當前正在監控著,則不需要繼續部署
  382.             return;  
  383.         }  
  384.         logSizeMoniting = true;  
  385.         Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);  
  386.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  
  387.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  
  388.         am.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), MEMORY_LOG_FILE_MONITOR_INTERVAL, sender);  
  389.         Log.d(TAG, "deployLogSizeMonitorTask() succ !");  
  390.         //recordLogServiceLog("deployLogSizeMonitorTask() succ ,start time is " + calendar.getTime().toLocaleString());
  391.     }  
  392.     /** 
  393.      * 取消部署日誌大小監控任務 
  394.      */
  395.     privatevoid cancelLogSizeMonitorTask() {  
  396.         logSizeMoniting = false;  
  397.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  
  398.         Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);  
  399.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  
  400.         am.cancel(sender);  
  401.         Log.d(TAG, "canelLogSizeMonitorTask() succ");  
  402.     }  
  403.     /** 
  404.      * 檢查日誌檔案大小是否超過了規定大小 
  405.      * 如果超過了重新開啟一個日誌收集程序 
  406.      */
  407.     privatevoid checkLogSize(){  
  408.         if(CURR_INSTALL_LOG_NAME != null && !"".equals(CURR_INSTALL_LOG_NAME)){  
  409.             String path = LOG_PATH_MEMORY_DIR + File.separator + CURR_INSTALL_LOG_NAME;  
  410.             File file = new File(path);  
  411.             if(!file.exists()){  
  412.                 return;  
  413.             }  
  414.             Log.d(TAG, "checkLog() ==> The size of the log is too big?");  
  415.             if(file.length() >= MEMORY_LOG_FILE_MAX_SIZE){  
  416.                 Log.d(TAG, "The log's size is too big!");  
  417.                 new LogCollectorThread().start();  
  418.             }  
  419.         }  
  420.     }  
  421.     /** 
  422.      * 建立日誌目錄 
  423.      */
  424.     privatevoid createLogDir() {  
  425.         File file = new File(LOG_PATH_MEMORY_DIR);  
  426.         boolean mkOk;  
  427.         if (!file.isDirectory()) {  
  428.             mkOk = file.mkdirs();  
  429.             if (!mkOk) {  
  430.                 mkOk = file.mkdirs();  
  431.             }  
  432.         }  
  433.         /* ************************************ 
  434.         file = new File(LOG_SERVICE_LOG_PATH); 
  435.         if (!file.exists()) { 
  436.             try { 
  437.                 mkOk = file.createNewFile(); 
  438.                 if (!mkOk) { 
  439.                     file.createNewFile(); 
  440.                 } 
  441.             } catch (IOException e) { 
  442.                 Log.e(TAG, e.getMessage(), e); 
  443.             } 
  444.         } 
  445.         * ************************************/
  446.         if (Environment.getExternalStorageState().equals(  
  447.                 Environment.MEDIA_MOUNTED)) {  
  448.             file = new File(LOG_PATH_SDCARD_DIR);  
  449.             if (!file.isDirectory()) {  
  450.                 mkOk = file.mkdirs();  
  451.                 if (!mkOk) {  
  452.                     recordLogServiceLog("move file failed,dir is not created succ");  
  453.                     return;  
  454.                 }  
  455.             }  
  456.         }  
  457.     }  
  458.     /** 
  459.      * 將日誌檔案轉移到SD卡下面 
  460.      */
  461.     privatevoid moveLogfile() {  
  462.         if (!Environment.getExternalStorageState().equals(  
  463.                 Environment.MEDIA_MOUNTED)) {  
  464.             //recordLogServiceLog("move file failed, sd card does not mount");
  465.             return;  
  466.         }  
  467.         File file = new File(LOG_PATH_SDCARD_DIR);  
  468.         if (!file.isDirectory()) {  
  469.             boolean mkOk = file.mkdirs();  
  470.             if (!mkOk) {  
  471.                 //recordLogServiceLog("move file failed,dir is not created succ");
  472.                 return;  
  473.             }  
  474.         }  
  475.         file = new File(LOG_PATH_MEMORY_DIR);  
  476.         if (file.isDirectory()) {  
  477.             File[] allFiles = file.listFiles();  
  478.             for (File logFile : allFiles) {  
  479.                 String fileName = logFile.getName();  
  480.                 if (logServiceLogName.equals(fileName)) {  
  481.                     continue;  
  482.                 }  
  483.                 //String createDateInfo = getFileNameWithoutExtension(fileName);
  484.                 boolean isSucc = copy(logFile, new File(LOG_PATH_SDCARD_DIR  
  485.                             + File.separator + fileName));  
  486.                 if (isSucc) {  
  487.                     logFile.delete();  
  488.                     //recordLogServiceLog("move file success,log name is:"+fileName);
  489.                 }  
  490.             }  
  491.         }  
  492.     }  
  493.     /** 
  494.      * 刪除記憶體下過期的日誌 
  495.      */
  496.     privatevoid deleteSDcardExpiredLog() {  
  497.         File file = new File(LOG_PATH_SDCARD_DIR);  
  498.         if (file.isDirectory()) {  
  499.             File[] allFiles = file.listFiles();  
  500.             for (File logFile : allFiles) {  
  501.                 String fileName = logFile.getName();  
  502.                 if (logServiceLogName.equals(fileName)) {  
  503.                     continue;  
  504.                 }  
  505.                 String createDateInfo = getFileNameWithoutExtension(fileName);  
  506.                 if (canDeleteSDLog(createDateInfo)) {  
  507.                     logFile.delete();  
  508.                     Log.d(TAG, "delete expired log success,the log path is:"
  509.                             + logFile.getAbsolutePath());  
  510.                 }  
  511.             }  
  512.         }  
  513.     }  
  514.     /** 
  515.      * 判斷sdcard上的日誌檔案是否可以刪除 
  516.      * @param createDateStr 
  517.      * @return 
  518.      */
  519.     publicboolean canDeleteSDLog(String createDateStr) {  
  520.         boolean canDel = false;  
  521.         Calendar calendar = Calendar.getInstance();  
  522.         calendar.add(Calendar.DAY_OF_MONTH, -1 * SDCARD_LOG_FILE_SAVE_DAYS);//刪除7天之前日誌
  523.         Date expiredDate = calendar.getTime();  
  524.         try {  
  525.             Date createDate = sdf.parse(createDateStr);  
  526.             canDel = createDate.before(expiredDate);  
  527.         } catch (ParseException e) {  
  528.             Log.e(TAG, e.getMessage(), e);  
  529.             canDel = false;  
  530.         }  
  531.         return canDel;  
  532.     }  
  533.     /** 
  534.      * 刪除記憶體中的過期日誌,刪除規則: 
  535.      * 除了當前的日誌和離當前時間最近的日誌儲存其他的都刪除 
  536.      */
  537.     privatevoid deleteMemoryExpiredLog(){  
  538.         File file = new File(LOG_PATH_MEMORY_DIR);  
  539.         if (file.isDirectory()) {  
  540.             File[] allFiles = file.listFiles();  
  541.             Arrays.sort(allFiles, new FileComparator());  
  542.             for (int i=0;i<allFiles.length-2;i++) {  //"-2"儲存最近的兩個日誌檔案
  543.                 File _file =  allFiles[i];  
  544.                 if (logServiceLogName.equals(_file.getName()) ||  _file.getName().equals(CURR_INSTALL_LOG_NAME)) {  
  545.                     continue;  
  546.                 }  
  547.                 _file.delete();  
  548.                 Log.d(TAG, "delete expired log success,the log path is:"+_file.getAbsolutePath());  
  549.             }  
  550.         }  
  551.     }  
  552.     /** 
  553.      * 拷貝檔案 
  554.      * @param source 
  555.      * @param target 
  556.      * @return 
  557.      */
  558.     privateboolean copy(File source, File target) {  
  559.         FileInputStream in = null;  
  560.         FileOutputStream out = null;  
  561.         try {  
  562.             if(!target.exists()){  
  563.                 boolean createSucc = target.createNewFile();  
  564.                 if(!createSucc){  
  565.                     returnfa