获取logcat日志

案例:当我们的软件安装在手机上的时候,或许还需要知道整个软件运行的情况,那么我们就需要一种把软件运行的状况记录下来,保存在某个地方(本地文件,以下就是解决方法

直接上代码:

[java]  view plain copy
  1. package com.ifeng.fhdt.service;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.io.InputStreamReader;  
  10. import java.io.OutputStreamWriter;  
  11. import java.text.ParseException;  
  12. import java.text.SimpleDateFormat;  
  13. import java.util.ArrayList;  
  14. import java.util.Arrays;  
  15. import java.util.Calendar;  
  16. import java.util.Comparator;  
  17. import java.util.Date;  
  18. import java.util.List;  
  19.   
  20. import android.app.AlarmManager;  
  21. import android.app.PendingIntent;  
  22. import android.app.Service;  
  23. import android.content.BroadcastReceiver;  
  24. import android.content.Context;  
  25. import android.content.Intent;  
  26. import android.content.IntentFilter;  
  27. import android.os.Environment;  
  28. import android.os.IBinder;  
  29. import android.os.PowerManager;  
  30. import android.os.PowerManager.WakeLock;  
  31. import android.util.Log;  
  32.   
  33. /** 
  34.  * 日志服务,日志默认会存储在SDcar里如果没有SDcard会存储在内存中的安装目录下面。 
  35.  * 1.本服务默认在SDcard中每天生成一个日志文件, 
  36.  * 2.如果有SDCard的话会将之前内存中的文件拷贝到SDCard中 
  37.  * 3.如果没有SDCard,在安装目录下只保存当前在写日志 
  38.  * 4.SDcard的装载卸载动作会在步骤2,3中切换 
  39.  * 5.SDcard中的日志文件只保存7天 
  40.  * @author Administrator 
  41.  *  
  42.  */  
  43. public class LogService extends Service {  
  44.     private static final String TAG = "LogService";  
  45.   
  46.     private static final int MEMORY_LOG_FILE_MAX_SIZE = 10 * 1024 * 1024;           //内存中日志文件最大值,10M  
  47.     private static final int MEMORY_LOG_FILE_MONITOR_INTERVAL = 10 * 60 * 1000;     //内存中的日志文件大小监控时间间隔,10分钟  
  48.     private static final int SDCARD_LOG_FILE_SAVE_DAYS = 7;                         //sd卡中日志文件的最多保存天数  
  49.       
  50.     private String LOG_PATH_MEMORY_DIR;     //日志文件在内存中的路径(日志文件在安装目录中的路径)  
  51.     private String LOG_PATH_SDCARD_DIR;     //日志文件在sdcard中的路径  
  52.     @SuppressWarnings("unused")  
  53.     private String LOG_SERVICE_LOG_PATH;    //本服务产生的日志,记录日志服务开启失败信息  
  54.       
  55.     private final int SDCARD_TYPE = 0;          //当前的日志记录类型为存储在SD卡下面  
  56.     private final int MEMORY_TYPE = 1;          //当前的日志记录类型为存储在内存中  
  57.     private int CURR_LOG_TYPE = SDCARD_TYPE;    //当前的日志记录类型  
  58.       
  59.     private String CURR_INSTALL_LOG_NAME;   //如果当前的日志写在内存中,记录当前的日志文件名称  
  60.       
  61.     private String logServiceLogName = "Log.log";//本服务输出的日志文件名称  
  62.     private SimpleDateFormat myLogSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  63.     private OutputStreamWriter writer;  
  64.       
  65.     private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HHmmss");//日志名称格式  
  66.       
  67.     private Process process;  
  68.       
  69.     private WakeLock wakeLock;    
  70.       
  71.     private SDStateMonitorReceiver sdStateReceiver; //SDcard状态监测  
  72.     private LogTaskReceiver logTaskReceiver;   
  73.       
  74.     /* 是否正在监测日志文件大小; 
  75.      * 如果当前日志记录在SDcard中则为false 
  76.      * 如果当前日志记录在内存中则为true*/  
  77.     private boolean logSizeMoniting = false;          
  78.       
  79.     private static String MONITOR_LOG_SIZE_ACTION = "MONITOR_LOG_SIZE";     //日志文件监测action  
  80.     private static String SWITCH_LOG_FILE_ACTION = "SWITCH_LOG_FILE_ACTION";    //切换日志文件action  
  81.       
  82.     @Override  
  83.     public IBinder onBind(Intent intent) {  
  84.         return null;  
  85.     }  
  86.   
  87.     @Override  
  88.     public void onCreate() {  
  89.         super.onCreate();  
  90.         init();  
  91.         register();  
  92.         deploySwitchLogFileTask();    
  93.         new LogCollectorThread().start();  
  94.     }  
  95.       
  96.     private void init(){  
  97.         LOG_PATH_MEMORY_DIR = getFilesDir().getAbsolutePath() + File.separator + "log";  
  98.         LOG_SERVICE_LOG_PATH = LOG_PATH_MEMORY_DIR + File.separator + logServiceLogName;  
  99.         LOG_PATH_SDCARD_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator  
  100.                             +   "MyApp" + File.separator + "log";  
  101.         createLogDir();  
  102.           
  103.         /* ****************************************************** 
  104.         try { 
  105.             writer = new OutputStreamWriter(new FileOutputStream( 
  106.                     LOG_SERVICE_LOG_PATH, true)); 
  107.         } catch (FileNotFoundException e) { 
  108.             Log.e(TAG, e.getMessage(), e); 
  109.         } 
  110.         * ******************************************************/  
  111.         PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);  
  112.         wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);  
  113.           
  114.         CURR_LOG_TYPE = getCurrLogType();  
  115.         Log.i(TAG, "LogService onCreate");  
  116.     }  
  117.       
  118.     private void register(){  
  119.         IntentFilter sdCarMonitorFilter = new IntentFilter();  
  120.         sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);  
  121.         sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);  
  122.         sdCarMonitorFilter.addDataScheme("file");  
  123.         sdStateReceiver = new SDStateMonitorReceiver();  
  124.         registerReceiver(sdStateReceiver, sdCarMonitorFilter);  
  125.           
  126.         IntentFilter logTaskFilter = new IntentFilter();  
  127.         logTaskFilter.addAction(MONITOR_LOG_SIZE_ACTION);  
  128.         logTaskFilter.addAction(SWITCH_LOG_FILE_ACTION);  
  129.         logTaskReceiver = new LogTaskReceiver();  
  130.         registerReceiver(logTaskReceiver,logTaskFilter);  
  131.     }  
  132.       
  133.       
  134.       
  135.     /** 
  136.      * 获取当前应存储在内存中还是存储在SDCard中 
  137.      * @return 
  138.      */  
  139.     public int getCurrLogType(){  
  140.         if (!Environment.getExternalStorageState().equals(  
  141.                 Environment.MEDIA_MOUNTED)) {  
  142.             return MEMORY_TYPE;  
  143.         }else{  
  144.             return SDCARD_TYPE;  
  145.         }  
  146.     }  
  147.   
  148.     /** 
  149.      * 部署日志切换任务,每天凌晨切换日志文件 
  150.      */  
  151.     private void deploySwitchLogFileTask() {  
  152.         Intent intent = new Intent(SWITCH_LOG_FILE_ACTION);  
  153.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  
  154.         Calendar calendar = Calendar.getInstance();  
  155.         calendar.add(Calendar.DAY_OF_MONTH, 1);  
  156.         calendar.set(Calendar.HOUR_OF_DAY, 0);  
  157.         calendar.set(Calendar.MINUTE, 0);  
  158.         calendar.set(Calendar.SECOND, 0);  
  159.   
  160.         // 部署任务  
  161.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  
  162.         am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, sender);  
  163.         recordLogServiceLog("deployNextTask succ,next task time is:"+myLogSdf.format(calendar.getTime()));  
  164.     }  
  165.   
  166.     /** 
  167.      * 日志收集 
  168.      * 1.清除日志缓存  
  169.      * 2.杀死应用程序已开启的Logcat进程防止多个进程写入一个日志文件 
  170.      * 3.开启日志收集进程  
  171.      * 4.处理日志文件 
  172.      *   移动 OR 删除 
  173.      */  
  174.     class LogCollectorThread extends Thread {  
  175.           
  176.         public LogCollectorThread(){  
  177.             super("LogCollectorThread");  
  178.             Log.d(TAG, "LogCollectorThread is create");  
  179.         }  
  180.           
  181.         @Override  
  182.         public void run() {  
  183.             try {  
  184.                 wakeLock.acquire(); //唤醒手机  
  185.                   
  186.                 clearLogCache();  
  187.                   
  188.                 List<String> orgProcessList = getAllProcess();  
  189.                 List<ProcessInfo> processInfoList = getProcessInfoList(orgProcessList);  
  190.                 killLogcatProc(processInfoList);  
  191.                   
  192.                 createLogCollector();  
  193.                   
  194.                 Thread.sleep(1000);//休眠,创建文件,然后处理文件,不然该文件还没创建,会影响文件删除  
  195.                   
  196.                 handleLog();  
  197.                   
  198.                 wakeLock.release(); //释放  
  199.             } catch (Exception e) {  
  200.                 e.printStackTrace();  
  201.                 recordLogServiceLog(Log.getStackTraceString(e));  
  202.             }  
  203.         }  
  204.     }  
  205.       
  206.     /** 
  207.      * 每次记录日志之前先清除日志的缓存, 不然会在两个日志文件中记录重复的日志 
  208.      */  
  209.     private void clearLogCache() {  
  210.         Process proc = null;  
  211.         List<String> commandList = new ArrayList<String>();  
  212.         commandList.add("logcat");  
  213.         commandList.add("-c");  
  214.         try {  
  215.             proc = Runtime.getRuntime().exec(  
  216.                     commandList.toArray(new String[commandList.size()]));  
  217.             StreamConsumer errorGobbler = new StreamConsumer(proc  
  218.                     .getErrorStream());  
  219.   
  220.             StreamConsumer outputGobbler = new StreamConsumer(proc  
  221.                     .getInputStream());  
  222.   
  223.             errorGobbler.start();  
  224.             outputGobbler.start();  
  225.             if (proc.waitFor() != 0) {  
  226.                 Log.e(TAG, " clearLogCache proc.waitFor() != 0");  
  227.                 recordLogServiceLog("clearLogCache clearLogCache proc.waitFor() != 0");  
  228.             }  
  229.         } catch (Exception e) {  
  230.             Log.e(TAG, "clearLogCache failed", e);  
  231.             recordLogServiceLog("clearLogCache failed");  
  232.         } finally {  
  233.             try {  
  234.                 proc.destroy();  
  235.             } catch (Exception e) {  
  236.                 Log.e(TAG, "clearLogCache failed", e);  
  237.                 recordLogServiceLog("clearLogCache failed");  
  238.             }  
  239.         }  
  240.     }  
  241.   
  242.     /** 
  243.      * 关闭由本程序开启的logcat进程: 
  244.      * 根据用户名称杀死进程(如果是本程序进程开启的Logcat收集进程那么两者的USER一致) 
  245.      * 如果不关闭会有多个进程读取logcat日志缓存信息写入日志文件 
  246.      *  
  247.      * @param allProcList 
  248.      * @return 
  249.      */  
  250.     private void killLogcatProc(List<ProcessInfo> allProcList) {  
  251.         if(process != null){  
  252.             process.destroy();  
  253.         }  
  254.         String packName = this.getPackageName();  
  255.         String myUser = getAppUser(packName, allProcList);  
  256.         /* 
  257.         recordLogServiceLog("app user is:"+myUser); 
  258.         recordLogServiceLog("========================"); 
  259.         for (ProcessInfo processInfo : allProcList) { 
  260.             recordLogServiceLog(processInfo.toString()); 
  261.         } 
  262.         recordLogServiceLog("========================"); 
  263.         */  
  264.         for (ProcessInfo processInfo : allProcList) {  
  265.             if (processInfo.name.toLowerCase().equals("logcat")  
  266.                     && processInfo.user.equals(myUser)) {  
  267.                 android.os.Process.killProcess(Integer  
  268.                         .parseInt(processInfo.pid));  
  269.                 //recordLogServiceLog("kill another logcat process success,the process info is:"  
  270.                 //      + processInfo);  
  271.             }  
  272.         }  
  273.     }  
  274.   
  275.     /** 
  276.      * 获取本程序的用户名称 
  277.      *  
  278.      * @param packName 
  279.      * @param allProcList 
  280.      * @return 
  281.      */  
  282.     private String getAppUser(String packName, List<ProcessInfo> allProcList) {  
  283.         for (ProcessInfo processInfo : allProcList) {  
  284.             if (processInfo.name.equals(packName)) {  
  285.                 return processInfo.user;  
  286.             }  
  287.         }  
  288.         return null;  
  289.     }  
  290.   
  291.     /** 
  292.      * 根据ps命令得到的内容获取PID,User,name等信息 
  293.      *  
  294.      * @param orgProcessList 
  295.      * @return 
  296.      */  
  297.     private List<ProcessInfo> getProcessInfoList(List<String> orgProcessList) {  
  298.         List<ProcessInfo> procInfoList = new ArrayList<ProcessInfo>();  
  299.         for (int i = 1; i < orgProcessList.size(); i++) {  
  300.             String processInfo = orgProcessList.get(i);  
  301.             String[] proStr = processInfo.split(" ");  
  302.             // USER PID PPID VSIZE RSS WCHAN PC NAME  
  303.             // root 1 0 416 300 c00d4b28 0000cd5c S /init  
  304.             List<String> orgInfo = new ArrayList<String>();  
  305.             for (String str : proStr) {  
  306.                 if (!"".equals(str)) {  
  307.                     orgInfo.add(str);  
  308.                 }  
  309.             }  
  310.             if (orgInfo.size() == 9) {  
  311.                 ProcessInfo pInfo = new ProcessInfo();  
  312.                 pInfo.user = orgInfo.get(0);  
  313.                 pInfo.pid = orgInfo.get(1);  
  314.                 pInfo.ppid = orgInfo.get(2);  
  315.                 pInfo.name = orgInfo.get(8);  
  316.                 procInfoList.add(pInfo);  
  317.             }  
  318.         }  
  319.         return procInfoList;  
  320.     }  
  321.   
  322.     /** 
  323.      * 运行PS命令得到进程信息 
  324.      *  
  325.      * @return 
  326.      *          USER PID PPID VSIZE RSS WCHAN PC NAME 
  327.      *          root 1 0 416 300 c00d4b28 0000cd5c S /init 
  328.      */  
  329.     private List<String> getAllProcess() {  
  330.         List<String> orgProcList = new ArrayList<String>();  
  331.         Process proc = null;  
  332.         try {  
  333.             proc = Runtime.getRuntime().exec("ps");  
  334.             StreamConsumer errorConsumer = new StreamConsumer(proc  
  335.                     .getErrorStream());  
  336.   
  337.             StreamConsumer outputConsumer = new StreamConsumer(proc  
  338.                     .getInputStream(), orgProcList);  
  339.   
  340.             errorConsumer.start();  
  341.             outputConsumer.start();  
  342.             if (proc.waitFor() != 0) {  
  343.                 Log.e(TAG, "getAllProcess proc.waitFor() != 0");  
  344.                 recordLogServiceLog("getAllProcess proc.waitFor() != 0");  
  345.             }  
  346.         } catch (Exception e) {  
  347.             Log.e(TAG, "getAllProcess failed", e);  
  348.             recordLogServiceLog("getAllProcess failed");  
  349.         } finally {  
  350.             try {  
  351.                 proc.destroy();  
  352.             } catch (Exception e) {  
  353.                 Log.e(TAG, "getAllProcess failed", e);  
  354.                 recordLogServiceLog("getAllProcess failed");  
  355.             }  
  356.         }  
  357.         return orgProcList;  
  358.     }  
  359.       
  360.     /** 
  361.      * 开始收集日志信息 
  362.      */  
  363.     public void createLogCollector() {  
  364.         String logFileName = sdf.format(new Date()) + ".log";// 日志文件名称  
  365.         List<String> commandList = new ArrayList<String>();  
  366.         commandList.add("logcat");  
  367.         commandList.add("-f");  
  368.         //commandList.add(LOG_PATH_INSTALL_DIR + File.separator + logFileName);  
  369.         commandList.add(getLogPath());  
  370.         commandList.add("-v");  
  371.         commandList.add("time");  
  372.         commandList.add("*:w");  
  373.           
  374.         //commandList.add("*:E");// 过滤所有的错误信息  
  375.   
  376.         // 过滤指定TAG的信息  
  377.         // commandList.add("MyAPP:V");  
  378.         // commandList.add("*:S");  
  379.         try {  
  380.             process = Runtime.getRuntime().exec(  
  381.                     commandList.toArray(new String[commandList.size()]));  
  382.             recordLogServiceLog("start collecting the log,and log name is:"+logFileName);  
  383.             // process.waitFor();  
  384.         } catch (Exception e) {  
  385.             Log.e(TAG, "CollectorThread == >" + e.getMessage(), e);  
  386.             recordLogServiceLog("CollectorThread == >" + e.getMessage());  
  387.         }  
  388.     }  
  389.       
  390.     /** 
  391.      * 根据当前的存储位置得到日志的绝对存储路径 
  392.      * @return 
  393.      */  
  394.     public String getLogPath(){  
  395.         createLogDir();  
  396.         String logFileName = sdf.format(new Date()) + ".log";// 日志文件名称  
  397.         if(CURR_LOG_TYPE == MEMORY_TYPE){  
  398.             CURR_INSTALL_LOG_NAME = logFileName;  
  399.             Log.d(TAG, "Log stored in memory, the path is:"+LOG_PATH_MEMORY_DIR + File.separator + logFileName);  
  400.             return LOG_PATH_MEMORY_DIR + File.separator + logFileName;  
  401.         }else{  
  402.             CURR_INSTALL_LOG_NAME = null;  
  403.             Log.d(TAG, "Log stored in SDcard, the path is:"+LOG_PATH_SDCARD_DIR + File.separator + logFileName);  
  404.             return LOG_PATH_SDCARD_DIR + File.separator + logFileName;  
  405.         }  
  406.     }  
  407.       
  408.     /** 
  409.      * 处理日志文件 
  410.      * 1.如果日志文件存储位置切换到内存中,删除除了正在写的日志文件 
  411.      *   并且部署日志大小监控任务,控制日志大小不超过规定值 
  412.      * 2.如果日志文件存储位置切换到SDCard中,删除7天之前的日志,移 
  413.      *     动所有存储在内存中的日志到SDCard中,并将之前部署的日志大小 
  414.      *   监控取消 
  415.      */  
  416.     public void handleLog(){  
  417.         if(CURR_LOG_TYPE == MEMORY_TYPE){  
  418.             deployLogSizeMonitorTask();  
  419.             deleteMemoryExpiredLog();  
  420.         }else{  
  421.             moveLogfile();  
  422.             cancelLogSizeMonitorTask();  
  423.             deleteSDcardExpiredLog();  
  424.         }  
  425.     }  
  426.       
  427.     /** 
  428.      * 部署日志大小监控任务 
  429.      */  
  430.     private void deployLogSizeMonitorTask() {  
  431.         if(logSizeMoniting){    //如果当前正在监控着,则不需要继续部署  
  432.             return;  
  433.         }  
  434.         logSizeMoniting = true;  
  435.         Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);  
  436.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  
  437.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  
  438.         am.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), MEMORY_LOG_FILE_MONITOR_INTERVAL, sender);  
  439.         Log.d(TAG, "deployLogSizeMonitorTask() succ !");  
  440.         //recordLogServiceLog("deployLogSizeMonitorTask() succ ,start time is " + calendar.getTime().toLocaleString());  
  441.     }  
  442.       
  443.     /** 
  444.      * 取消部署日志大小监控任务 
  445.      */    
  446.     private void cancelLogSizeMonitorTask() {  
  447.         logSizeMoniting = false;  
  448.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  
  449.         Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);  
  450.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  
  451.         am.cancel(sender);  
  452.           
  453.         Log.d(TAG, "canelLogSizeMonitorTask() succ");  
  454.     }  
  455.       
  456.     /** 
  457.      * 检查日志文件大小是否超过了规定大小 
  458.      * 如果超过了重新开启一个日志收集进程 
  459.      */  
  460.     private void checkLogSize(){  
  461.         if(CURR_INSTALL_LOG_NAME != null && !"".equals(CURR_INSTALL_LOG_NAME)){  
  462.             String path = LOG_PATH_MEMORY_DIR + File.separator + CURR_INSTALL_LOG_NAME;  
  463.             File file = new File(path);  
  464.             if(!file.exists()){  
  465.                 return;  
  466.             }  
  467.             Log.d(TAG, "checkLog() ==> The size of the log is too big?");  
  468.             if(file.length() >= MEMORY_LOG_FILE_MAX_SIZE){  
  469.                 Log.d(TAG, "The log's size is too big!");  
  470.                 new LogCollectorThread().start();  
  471.             }  
  472.         }  
  473.     }  
  474.       
  475.     /** 
  476.      * 创建日志目录 
  477.      */  
  478.     private void createLogDir() {  
  479.         File file = new File(LOG_PATH_MEMORY_DIR);  
  480.         boolean mkOk;  
  481.         if (!file.isDirectory()) {  
  482.             mkOk = file.mkdirs();  
  483.             if (!mkOk) {  
  484.                 mkOk = file.mkdirs();  
  485.             }  
  486.         }  
  487.   
  488.         /* ************************************ 
  489.         file = new File(LOG_SERVICE_LOG_PATH); 
  490.         if (!file.exists()) { 
  491.             try { 
  492.                 mkOk = file.createNewFile(); 
  493.                 if (!mkOk) { 
  494.                     file.createNewFile(); 
  495.                 } 
  496.             } catch (IOException e) { 
  497.                 Log.e(TAG, e.getMessage(), e); 
  498.             } 
  499.         } 
  500.         * ************************************/  
  501.           
  502.         if (Environment.getExternalStorageState().equals(  
  503.                 Environment.MEDIA_MOUNTED)) {  
  504.             file = new File(LOG_PATH_SDCARD_DIR);  
  505.             if (!file.isDirectory()) {  
  506.                 mkOk = file.mkdirs();  
  507.                 if (!mkOk) {  
  508.                     recordLogServiceLog("move file failed,dir is not created succ");  
  509.                     return;  
  510.                 }  
  511.             }  
  512.         }  
  513.     }  
  514.       
  515.     /** 
  516.      * 将日志文件转移到SD卡下面 
  517.      */  
  518.     private void moveLogfile() {  
  519.         if (!Environment.getExternalStorageState().equals(  
  520.                 Environment.MEDIA_MOUNTED)) {  
  521.             //recordLogServiceLog("move file failed, sd card does not mount");  
  522.             return;  
  523.         }  
  524.         File file = new File(LOG_PATH_SDCARD_DIR);  
  525.         if (!file.isDirectory()) {  
  526.             boolean mkOk = file.mkdirs();  
  527.             if (!mkOk) {  
  528.                 //recordLogServiceLog("move file failed,dir is not created succ");  
  529.                 return;  
  530.             }  
  531.         }  
  532.   
  533.         file = new File(LOG_PATH_MEMORY_DIR);  
  534.         if (file.isDirectory()) {  
  535.             File[] allFiles = file.listFiles();  
  536.             for (File logFile : allFiles) {  
  537.                 String fileName = logFile.getName();  
  538.                 if (logServiceLogName.equals(fileName)) {  
  539.                     continue;  
  540.                 }  
  541.                 //String createDateInfo = getFileNameWithoutExtension(fileName);  
  542.                 boolean isSucc = copy(logFile, new File(LOG_PATH_SDCARD_DIR  
  543.                             + File.separator + fileName));  
  544.                 if (isSucc) {  
  545.                     logFile.delete();  
  546.                     //recordLogServiceLog("move file success,log name is:"+fileName);  
  547.                 }  
  548.             }  
  549.         }  
  550.     }  
  551.   
  552.     /** 
  553.      * 删除内存下过期的日志 
  554.      */  
  555.     private void deleteSDcardExpiredLog() {  
  556.         File file = new File(LOG_PATH_SDCARD_DIR);  
  557.         if (file.isDirectory()) {  
  558.             File[] allFiles = file.listFiles();  
  559.             for (File logFile : allFiles) {  
  560.                 String fileName = logFile.getName();  
  561.                 if (logServiceLogName.equals(fileName)) {  
  562.                     continue;  
  563.                 }  
  564.                 String createDateInfo = getFileNameWithoutExtension(fileName);  
  565.                 if (canDeleteSDLog(createDateInfo)) {  
  566.                     logFile.delete();  
  567.                     Log.d(TAG, "delete expired log success,the log path is:"  
  568.                             + logFile.getAbsolutePath());  
  569.   
  570.                 }  
  571.             }  
  572.         }  
  573.     }  
  574.       
  575.     /** 
  576.      * 判断sdcard上的日志文件是否可以删除 
  577.      * @param createDateStr 
  578.      * @return 
  579.      */  
  580.     public boolean canDeleteSDLog(String createDateStr) {  
  581.         boolean canDel = false;  
  582.         Calendar calendar = Calendar.getInstance();  
  583.         calendar.add(Calendar.DAY_OF_MONTH, -1 * SDCARD_LOG_FILE_SAVE_DAYS);//删除7天之前日志  
  584.         Date expiredDate = calendar.getTime();  
  585.         try {  
  586.             Date createDate = sdf.parse(createDateStr);  
  587.             canDel = createDate.before(expiredDate);  
  588.         } catch (ParseException e) {  
  589.             Log.e(TAG, e.getMessage(), e);  
  590.             canDel = false;  
  591.         }  
  592.         return canDel;  
  593.     }  
  594.   
  595.       
  596.     /** 
  597.      * 删除内存中的过期日志,删除规则: 
  598.      * 除了当前的日志和离当前时间最近的日志保存其他的都删除 
  599.      */  
  600.     private void deleteMemoryExpiredLog(){  
  601.         File file = new File(LOG_PATH_MEMORY_DIR);  
  602.         if (file.isDirectory()) {  
  603.             File[] allFiles = file.listFiles();  
  604.             Arrays.sort(allFiles, new FileComparator());  
  605.             for (int i=0;i<allFiles.length-2;i++) {  //"-2"保存最近的两个日志文件  
  606.                 File _file =  allFiles[i];  
  607.                 if (logServiceLogName.equals(_file.getName()) ||  _file.getName().equals(CURR_INSTALL_LOG_NAME)) {  
  608.                     continue;  
  609.                 }  
  610.                 _file.delete();  
  611.                 Log.d(TAG, "delete expired log success,the log path is:"+_file.getAbsolutePath());  
  612.             }  
  613.         }  
  614.     }  
  615.       
  616.     /** 
  617.      * 拷贝文件 
  618.      * @param source 
  619.      * @param target 
  620.      * @return 
  621.      */  
  622.     private boolean copy(File source, File target) {  
  623.         FileInputStream in = null;  
  624.         FileOutputStream out = null;  
  625.         try {  
  626.             if(!target.exists()){  
  627.                 boolean createSucc = target.createNewFile();  
  628.                 if(!createSucc){  
  629.                     return false;  
  630.                 }  
  631.             }  
  632.             in = new FileInputStream(source);  
  633.             out = new FileOutputStream(target);  
  634.             byte[] buffer = new byte[8*1024];  
  635.             int count;  
  636.             while ((count = in.read(buffer)) != -1) {  
  637.                 out.write(buffer, 0, count);  
  638.             }  
  639.             return true;  
  640.         } catch (Exception e) {  
  641.             e.printStackTrace();  
  642.             Log.e(TAG, e.getMessage(), e);  
  643.             recordLogServiceLog("copy file fail");  
  644.             return false;  
  645.         } finally{  
  646.             try {  
  647.                 if(in != null){  
  648.                     in.close();  
  649.                 }  
  650.                 if(out != null){  
  651.                     out.close();  
  652.                 }  
  653.             } catch (IOException e) {  
  654.                 e.printStackTrace();  
  655.                 Log.e(TAG, e.getMessage(), e);  
  656.                 recordLogServiceLog("copy file fail");  
  657.                 return false;  
  658.             }  
  659.         }  
  660.           
  661.     }  
  662.   
  663.     /** 
  664.      * 记录日志服务的基本信息 防止日志服务有错,在LogCat日志中无法查找  
  665.      * 此日志名称为Log.log 
  666.      *  
  667.      * @param msg 
  668.      */  
  669.     private void recordLogServiceLog(String msg) {  
  670.         if (writer != null) {  
  671.             try {  
  672.                 Date time = new Date();  
  673.                 writer.write(myLogSdf.format(time) + " : " + msg);  
  674.                 writer.write("\n");  
  675.                 writer.flush();  
  676.             } catch (IOException e) {  
  677.                 e.printStackTrace();  
  678.                 Log.e(TAG, e.getMessage(), e);  
  679.             }  
  680.         }  
  681.     }  
  682.       
  683.     /** 
  684.      * 去除文件的扩展类型(.log) 
  685.      * @param fileName 
  686.      * @return 
  687.      */  
  688.     private String getFileNameWithoutExtension(String fileName){  
  689.         return fileName.substring(0, fileName.indexOf("."));  
  690.     }  
  691.   
  692.     class ProcessInfo {  
  693.         public String user;  
  694.         public String pid;  
  695.         public String ppid;  
  696.         public String name;  
  697.   
  698.         @Override  
  699.         public String toString() {  
  700.             String str = "user=" + user + " pid=" + pid + " ppid=" + ppid  
  701.                     + " name=" + name;  
  702.             return str;  
  703.         }  
  704.     }  
  705.     class StreamConsumer extends Thread {  
  706.         InputStream is;  
  707.         List<String> list;  
  708.   
  709.         StreamConsumer(InputStream is) {  
  710.             this.is = is;  
  711.         }  
  712.   
  713.         StreamConsumer(InputStream is, List<String> list) {  
  714.             this.is = is;  
  715.             this.list = list;  
  716.         }  
  717.   
  718.         public void run() {  
  719.             try {  
  720.                 InputStreamReader isr = new InputStreamReader(is);  
  721.                 BufferedReader br = new BufferedReader(isr);  
  722.                   
  723.                 String line = null;  
  724.                 while ((line = br.readLine()) != null&&line.contains(getPackageName())) {  
  725.                     if (list != null) {  
  726.                         list.add(line);  
  727.                     }  
  728.                 }  
  729.             } catch (IOException ioe) {  
  730.                 ioe.printStackTrace();  
  731.             }  
  732.         }  
  733.     }  
  734.       
  735.     /** 
  736.      * 监控SD卡状态 
  737.      * @author Administrator 
  738.      * 
  739.      */  
  740.     class SDStateMonitorReceiver extends BroadcastReceiver{  
  741.         public void onReceive(Context context, Intent intent) {  
  742.               
  743.             if(Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction())){   //存储卡被卸载  
  744.                 if(CURR_LOG_TYPE == SDCARD_TYPE){  
  745.                     Log.d(TAG, "SDcar is UNMOUNTED");  
  746.                     CURR_LOG_TYPE = MEMORY_TYPE;  
  747.                     new LogCollectorThread().start();  
  748.                 }  
  749.             }else{                                                          //存储卡被挂载  
  750.                 if(CURR_LOG_TYPE == MEMORY_TYPE){  
  751.                     Log.d(TAG, "SDcar is MOUNTED");  
  752.                     CURR_LOG_TYPE = SDCARD_TYPE;  
  753.                     new LogCollectorThread().start();  
  754.                       
  755.                 }  
  756.             }  
  757.         }  
  758.     }  
  759.       
  760.     /** 
  761.      * 日志任务接收 
  762.      * 切换日志,监控日志大小 
  763.      * @author Administrator 
  764.      * 
  765.      */  
  766.     class LogTaskReceiver extends BroadcastReceiver{  
  767.         public void onReceive(Context context, Intent intent) {  
  768.             String action = intent.getAction();  
  769.             if(SWITCH_LOG_FILE_ACTION.equals(action)){  
  770.                 new LogCollectorThread().start();  
  771.             }else if(MONITOR_LOG_SIZE_ACTION.equals(action)){  
  772.                 checkLogSize();  
  773.             }  
  774.         }  
  775.     }  
  776.       
  777.     class FileComparator implements Comparator<File>{  
  778.         public int compare(File file1, File file2) {  
  779.             if(logServiceLogName.equals(file1.getName())){  
  780.                 return -1;  
  781.             }else if(logServiceLogName.equals(file2.getName())){  
  782.                 return 1;  
  783.             }  
  784.               
  785.             String createInfo1 = getFileNameWithoutExtension(file1.getName());  
  786.             String createInfo2 = getFileNameWithoutExtension(file2.getName());  
  787.               
  788.             try {  
  789.                 Date create1 = sdf.parse(createInfo1);  
  790.                 Date create2 = sdf.parse(createInfo2);  
  791.                 if(create1.before(create2)){  
  792.                     return -1;  
  793.                 }else{  
  794.                     return 1;  
  795.                 }  
  796.             } catch (ParseException e) {  
  797.                 return 0;  
  798.             }  
  799.         }  
  800.     }  
  801.       
  802.     @Override  
  803.     public void onDestroy() {  
  804.         super.onDestroy();  
  805.         recordLogServiceLog("LogService onDestroy");  
  806.         if (writer != null) {  
  807.             try {  
  808.                 writer.close();  
  809.             } catch (IOException e) {  
  810.                 e.printStackTrace();  
  811.             }  
  812.         }  
  813.         if (process != null) {  
  814.             process.destroy();  
  815.         }  
  816.           
  817.         unregisterReceiver(sdStateReceiver);  
  818.         unregisterReceiver(logTaskReceiver);  
  819.     }  
  820.   
  821. }  


 

此外还要加上权限:

[java]  view plain copy
  1. <uses-permission android:name="android.permission.READ_LOGS" />  
  2.    <uses-permission android:name="android.permission.WAKE_LOCK" />  
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值