Android的log保存到文件上查看

   

       Android的log保存到文件上查看            

       分类:            Android            2012-07-31 10:59    1905人阅读    评论(0)    收藏    举报    

androidstringfilepathexceptionaction

在调试的时候一般都是在logcat中看日志的信息,以便找出BUG和调试信息,但是如果在真机上的话不可能一直连接电脑查看日志,所以生成日志文件并保存,是一个比较普遍的需求,下面就是最近实现的一个例子。欢迎大家讨论并给出别的思路。

 

  1. import java.io.BufferedReader;  

  2. import java.io.File;  

  3. import java.io.FileInputStream;  

  4. import java.io.FileOutputStream;  

  5. import java.io.IOException;  

  6. import java.io.InputStream;  

  7. import java.io.InputStreamReader;  

  8. import java.io.OutputStreamWriter;  

  9. import java.text.ParseException;  

  10. import java.text.SimpleDateFormat;  

  11. import java.util.ArrayList;  

  12. import java.util.Arrays;  

  13. import java.util.Calendar;  

  14. import java.util.Comparator;  

  15. import java.util.Date;  

  16. import java.util.List;  

  17.   

  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. /** 

  32.  * 日志服务,日志默认会存储在SDcar里如果没有SDcard会存储在内存中的安装目录下面。 1.本服务默认在SDcard中每天生成一个日志文件, 

  33.  * 2.如果有SDCard的话会将之前内存中的文件拷贝到SDCard中 3.如果没有SDCard,在安装目录下只保存当前在写日志 

  34.  * 4.SDcard的装载卸载动作会在步骤2,3中切换 5.SDcard中的日志文件只保存7天 

  35.  *  

  36.  * @author Administrator 

  37.  *  

  38.  */  

  39. public class LogService extends Service {  

  40.     private static final String TAG = "LogService";  

  41.   

  42.     private static final int MEMORY_LOG_FILE_MAX_SIZE = 10 * 1024 * 1024// 内存中日志文件最大值,10M  

  43.     private static final int MEMORY_LOG_FILE_MONITOR_INTERVAL = 10 * 60 * 1000// 内存中的日志文件大小监控时间间隔,10分钟  

  44.     private static final int SDCARD_LOG_FILE_SAVE_DAYS = 7// sd卡中日志文件的最多保存天数  

  45.   

  46.     private String LOG_PATH_MEMORY_DIR; // 日志文件在内存中的路径(日志文件在安装目录中的路径)  

  47.     private String LOG_PATH_SDCARD_DIR; // 日志文件在sdcard中的路径  

  48.     @SuppressWarnings("unused")  

  49.     private String LOG_SERVICE_LOG_PATH; // 本服务产生的日志,记录日志服务开启失败信息  

  50.   

  51.     private final int SDCARD_TYPE = 0// 当前的日志记录类型为存储在SD卡下面  

  52.     private final int MEMORY_TYPE = 1// 当前的日志记录类型为存储在内存中  

  53.     private int CURR_LOG_TYPE = SDCARD_TYPE; // 当前的日志记录类型  

  54.   

  55.     private String CURR_INSTALL_LOG_NAME; // 如果当前的日志写在内存中,记录当前的日志文件名称  

  56.   

  57.     private String logServiceLogName = "Log.log";// 本服务输出的日志文件名称  

  58.     private SimpleDateFormat myLogSdf = new SimpleDateFormat(  

  59.             "yyyy-MM-dd HH:mm:ss");  

  60.     private OutputStreamWriter writer;  

  61.   

  62.     private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HHmmss");// 日志名称格式  

  63.   

  64.     private Process process;  

  65.   

  66.     private WakeLock wakeLock;  

  67.   

  68.     private SDStateMonitorReceiver sdStateReceiver; // SDcard状态监测  

  69.     private LogTaskReceiver logTaskReceiver;  

  70.   

  71.     /* 

  72.      * 是否正在监测日志文件大小; 如果当前日志记录在SDcard中则为false 如果当前日志记录在内存中则为true 

  73.      */  

  74.     private boolean logSizeMoniting = false;  

  75.   

  76.     private static String MONITOR_LOG_SIZE_ACTION = "MONITOR_LOG_SIZE"// 日志文件监测action  

  77.     private static String SWITCH_LOG_FILE_ACTION = "SWITCH_LOG_FILE_ACTION"// 切换日志文件action  

  78.   

  79.     @Override  

  80.     public IBinder onBind(Intent intent)  

  81.     {  

  82.         return null;  

  83.     }  

  84.   

  85.     @Override  

  86.     public void onCreate()  

  87.     {  

  88.         super.onCreate();  

  89.         init();  

  90.         register();  

  91.         deploySwitchLogFileTask();  

  92.         new LogCollectorThread().start();  

  93.     }  

  94.   

  95.     private void init()  

  96.     {  

  97.         LOG_PATH_MEMORY_DIR = getFilesDir().getAbsolutePath() + File.separator  

  98.                 + "log";  

  99.         LOG_SERVICE_LOG_PATH = LOG_PATH_MEMORY_DIR + File.separator  

  100.                 + logServiceLogName;  

  101.         LOG_PATH_SDCARD_DIR = Environment.getExternalStorageDirectory()  

  102.                 .getAbsolutePath()  

  103.                 + File.separator  

  104.                 + "MyApp"  

  105.                 + File.separator  

  106.                 + "log";  

  107.         createLogDir();  

  108.   

  109.         /* ****************************************************** 

  110.          * try { writer = new OutputStreamWriter(new FileOutputStream( 

  111.          * LOG_SERVICE_LOG_PATH, true)); } catch (FileNotFoundException e) { 

  112.          * Log.e(TAG, e.getMessage(), e); } 

  113.          * ***************************************************** 

  114.          */  

  115.         PowerManager pm = (PowerManager) getApplicationContext()  

  116.                 .getSystemService(Context.POWER_SERVICE);  

  117.         wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);  

  118.   

  119.         CURR_LOG_TYPE = getCurrLogType();  

  120.         Log.i(TAG, "LogService onCreate");  

  121.     }  

  122.   

  123.     private void register()  

  124.     {  

  125.         IntentFilter sdCarMonitorFilter = new IntentFilter();  

  126.         sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);  

  127.         sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);  

  128.         sdCarMonitorFilter.addDataScheme("file");  

  129.         sdStateReceiver = new SDStateMonitorReceiver();  

  130.         registerReceiver(sdStateReceiver, sdCarMonitorFilter);  

  131.   

  132.         IntentFilter logTaskFilter = new IntentFilter();  

  133.         logTaskFilter.addAction(MONITOR_LOG_SIZE_ACTION);  

  134.         logTaskFilter.addAction(SWITCH_LOG_FILE_ACTION);  

  135.         logTaskReceiver = new LogTaskReceiver();  

  136.         registerReceiver(logTaskReceiver, logTaskFilter);  

  137.     }  

  138.   

  139.     /** 

  140.      * 获取当前应存储在内存中还是存储在SDCard中 

  141.      *  

  142.      * @return  

  143.      */  

  144.     public int getCurrLogType()  

  145.     {  

  146.         if (!Environment.getExternalStorageState().equals(  

  147.                 Environment.MEDIA_MOUNTED))  

  148.         {  

  149.             return MEMORY_TYPE;  

  150.         } else  

  151.         {  

  152.             return SDCARD_TYPE;  

  153.         }  

  154.     }  

  155.   

  156.     /** 

  157.      * 部署日志切换任务,每天凌晨切换日志文件 

  158.      */  

  159.     private void deploySwitchLogFileTask()  

  160.     {  

  161.         Intent intent = new Intent(SWITCH_LOG_FILE_ACTION);  

  162.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  

  163.         Calendar calendar = Calendar.getInstance();  

  164.         calendar.add(Calendar.DAY_OF_MONTH, 1);  

  165.         calendar.set(Calendar.HOUR_OF_DAY, 0);  

  166.         calendar.set(Calendar.MINUTE, 0);  

  167.         calendar.set(Calendar.SECOND, 0);  

  168.   

  169.         // 部署任务  

  170.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  

  171.         am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),  

  172.                 AlarmManager.INTERVAL_DAY, sender);  

  173.         recordLogServiceLog("deployNextTask succ,next task time is:"  

  174.                 + myLogSdf.format(calendar.getTime()));  

  175.     }  

  176.   

  177.     /** 

  178.      * 日志收集 1.清除日志缓存 2.杀死应用程序已开启的Logcat进程防止多个进程写入一个日志文件 3.开启日志收集进程 4.处理日志文件 移动 

  179.      * OR 删除 

  180.      */  

  181.     class LogCollectorThread extends Thread {  

  182.   

  183.         public LogCollectorThread() {  

  184.             super("LogCollectorThread");  

  185.             Log.d(TAG, "LogCollectorThread is create");  

  186.         }  

  187.   

  188.         @Override  

  189.         public void run()  

  190.         {  

  191.             try  

  192.             {  

  193.                 wakeLock.acquire(); // 唤醒手机  

  194.   

  195.                 clearLogCache();  

  196.   

  197.                 List<String> orgProcessList = getAllProcess();  

  198.                 List<ProcessInfo> processInfoList = getProcessInfoList(orgProcessList);  

  199.                 killLogcatProc(processInfoList);  

  200.   

  201.                 createLogCollector();  

  202.   

  203.                 Thread.sleep(1000);// 休眠,创建文件,然后处理文件,不然该文件还没创建,会影响文件删除  

  204.   

  205.                 handleLog();  

  206.   

  207.                 wakeLock.release(); // 释放  

  208.             } catch (Exception e)  

  209.             {  

  210.                 e.printStackTrace();  

  211.                 recordLogServiceLog(Log.getStackTraceString(e));  

  212.             }  

  213.         }  

  214.     }  

  215.   

  216.     /** 

  217.      * 每次记录日志之前先清除日志的缓存, 不然会在两个日志文件中记录重复的日志 

  218.      */  

  219.     private void clearLogCache()  

  220.     {  

  221.         Process proc = null;  

  222.         List<String> commandList = new ArrayList<String>();  

  223.         commandList.add("logcat");  

  224.         commandList.add("-c");  

  225.         try  

  226.         {  

  227.             proc = Runtime.getRuntime().exec(  

  228.                     commandList.toArray(new String[commandList.size()]));  

  229.             StreamConsumer errorGobbler = new StreamConsumer(  

  230.                     proc.getErrorStream());  

  231.   

  232.             StreamConsumer outputGobbler = new StreamConsumer(  

  233.                     proc.getInputStream());  

  234.   

  235.             errorGobbler.start();  

  236.             outputGobbler.start();  

  237.             if (proc.waitFor() != 0)  

  238.             {  

  239.                 Log.e(TAG, " clearLogCache proc.waitFor() != 0");  

  240.                 recordLogServiceLog("clearLogCache clearLogCache proc.waitFor() != 0");  

  241.             }  

  242.         } catch (Exception e)  

  243.         {  

  244.             Log.e(TAG, "clearLogCache failed", e);  

  245.             recordLogServiceLog("clearLogCache failed");  

  246.         } finally  

  247.         {  

  248.             try  

  249.             {  

  250.                 proc.destroy();  

  251.             } catch (Exception e)  

  252.             {  

  253.                 Log.e(TAG, "clearLogCache failed", e);  

  254.                 recordLogServiceLog("clearLogCache failed");  

  255.             }  

  256.         }  

  257.     }  

  258.   

  259.     /** 

  260.      * 关闭由本程序开启的logcat进程: 根据用户名称杀死进程(如果是本程序进程开启的Logcat收集进程那么两者的USER一致) 

  261.      * 如果不关闭会有多个进程读取logcat日志缓存信息写入日志文件 

  262.      *  

  263.      * @param allProcList 

  264.      * @return  

  265.      */  

  266.     private void killLogcatProc(List<ProcessInfo> allProcList)  

  267.     {  

  268.         if (process != null)  

  269.         {  

  270.             process.destroy();  

  271.         }  

  272.         String packName = this.getPackageName();  

  273.         String myUser = getAppUser(packName, allProcList);  

  274.         /* 

  275.          * recordLogServiceLog("app user is:"+myUser); 

  276.          * recordLogServiceLog("========================"); for (ProcessInfo 

  277.          * processInfo : allProcList) { 

  278.          * recordLogServiceLog(processInfo.toString()); } 

  279.          * recordLogServiceLog("========================"); 

  280.          */  

  281.         for (ProcessInfo processInfo : allProcList)  

  282.         {  

  283.             if (processInfo.name.toLowerCase().equals("logcat")  

  284.                     && processInfo.user.equals(myUser))  

  285.             {  

  286.                 android.os.Process.killProcess(Integer  

  287.                         .parseInt(processInfo.pid));  

  288.                 // recordLogServiceLog("kill another logcat process success,the process info is:"  

  289.                 // + processInfo);  

  290.             }  

  291.         }  

  292.     }  

  293.   

  294.     /** 

  295.      * 获取本程序的用户名称 

  296.      *  

  297.      * @param packName 

  298.      * @param allProcList 

  299.      * @return  

  300.      */  

  301.     private String getAppUser(String packName, List<ProcessInfo> allProcList)  

  302.     {  

  303.         for (ProcessInfo processInfo : allProcList)  

  304.         {  

  305.             if (processInfo.name.equals(packName))  

  306.             {  

  307.                 return processInfo.user;  

  308.             }  

  309.         }  

  310.         return null;  

  311.     }  

  312.   

  313.     /** 

  314.      * 根据ps命令得到的内容获取PID,User,name等信息 

  315.      *  

  316.      * @param orgProcessList 

  317.      * @return  

  318.      */  

  319.     private List<ProcessInfo> getProcessInfoList(List<String> orgProcessList)  

  320.     {  

  321.         List<ProcessInfo> procInfoList = new ArrayList<ProcessInfo>();  

  322.         for (int i = 1; i < orgProcessList.size(); i++)  

  323.         {  

  324.             String processInfo = orgProcessList.get(i);  

  325.             String[] proStr = processInfo.split(" ");  

  326.             // USER PID PPID VSIZE RSS WCHAN PC NAME  

  327.             // root 1 0 416 300 c00d4b28 0000cd5c S /init  

  328.             List<String> orgInfo = new ArrayList<String>();  

  329.             for (String str : proStr)  

  330.             {  

  331.                 if (!"".equals(str))  

  332.                 {  

  333.                     orgInfo.add(str);  

  334.                 }  

  335.             }  

  336.             if (orgInfo.size() == 9)  

  337.             {  

  338.                 ProcessInfo pInfo = new ProcessInfo();  

  339.                 pInfo.user = orgInfo.get(0);  

  340.                 pInfo.pid = orgInfo.get(1);  

  341.                 pInfo.ppid = orgInfo.get(2);  

  342.                 pInfo.name = orgInfo.get(8);  

  343.                 procInfoList.add(pInfo);  

  344.             }  

  345.         }  

  346.         return procInfoList;  

  347.     }  

  348.   

  349.     /** 

  350.      * 运行PS命令得到进程信息 

  351.      *  

  352.      * @return USER PID PPID VSIZE RSS WCHAN PC NAME root 1 0 416 300 c00d4b28 

  353.      *         0000cd5c S /init 

  354.      */  

  355.     private List<String> getAllProcess()  

  356.     {  

  357.         List<String> orgProcList = new ArrayList<String>();  

  358.         Process proc = null;  

  359.         try  

  360.         {  

  361.             proc = Runtime.getRuntime().exec("ps");  

  362.             StreamConsumer errorConsumer = new StreamConsumer(  

  363.                     proc.getErrorStream());  

  364.   

  365.             StreamConsumer outputConsumer = new StreamConsumer(  

  366.                     proc.getInputStream(), orgProcList);  

  367.   

  368.             errorConsumer.start();  

  369.             outputConsumer.start();  

  370.             if (proc.waitFor() != 0)  

  371.             {  

  372.                 Log.e(TAG, "getAllProcess proc.waitFor() != 0");  

  373.                 recordLogServiceLog("getAllProcess proc.waitFor() != 0");  

  374.             }  

  375.         } catch (Exception e)  

  376.         {  

  377.             Log.e(TAG, "getAllProcess failed", e);  

  378.             recordLogServiceLog("getAllProcess failed");  

  379.         } finally  

  380.         {  

  381.             try  

  382.             {  

  383.                 proc.destroy();  

  384.             } catch (Exception e)  

  385.             {  

  386.                 Log.e(TAG, "getAllProcess failed", e);  

  387.                 recordLogServiceLog("getAllProcess failed");  

  388.             }  

  389.         }  

  390.         return orgProcList;  

  391.     }  

  392.   

  393.     /** 

  394.      * 开始收集日志信息 

  395.      */  

  396.     public void createLogCollector()  

  397.     {  

  398.         String logFileName = sdf.format(new Date()) + ".log";// 日志文件名称  

  399.         List<String> commandList = new ArrayList<String>();  

  400.         commandList.add("logcat");  

  401.         commandList.add("-f");  

  402.         // commandList.add(LOG_PATH_INSTALL_DIR + File.separator + logFileName);  

  403.         commandList.add(getLogPath());  

  404.         commandList.add("-v");  

  405.         commandList.add("time");  

  406.         commandList.add("*:I");  

  407.   

  408.         // commandList.add("*:E");// 过滤所有的错误信息  

  409.   

  410.         // 过滤指定TAG的信息  

  411.         // commandList.add("MyAPP:V");  

  412.         // commandList.add("*:S");  

  413.         try  

  414.         {  

  415.             process = Runtime.getRuntime().exec(  

  416.                     commandList.toArray(new String[commandList.size()]));  

  417.             recordLogServiceLog("start collecting the log,and log name is:"  

  418.                     + logFileName);  

  419.             // process.waitFor();  

  420.         } catch (Exception e)  

  421.         {  

  422.             Log.e(TAG, "CollectorThread == >" + e.getMessage(), e);  

  423.             recordLogServiceLog("CollectorThread == >" + e.getMessage());  

  424.         }  

  425.     }  

  426.   

  427.     /** 

  428.      * 根据当前的存储位置得到日志的绝对存储路径 

  429.      *  

  430.      * @return  

  431.      */  

  432.     public String getLogPath()  

  433.     {  

  434.         createLogDir();  

  435.         String logFileName = sdf.format(new Date()) + ".log";// 日志文件名称  

  436.         if (CURR_LOG_TYPE == MEMORY_TYPE)  

  437.         {  

  438.             CURR_INSTALL_LOG_NAME = logFileName;  

  439.             Log.d(TAG, "Log stored in memory, the path is:"  

  440.                     + LOG_PATH_MEMORY_DIR + File.separator + logFileName);  

  441.             return LOG_PATH_MEMORY_DIR + File.separator + logFileName;  

  442.         } else  

  443.         {  

  444.             CURR_INSTALL_LOG_NAME = null;  

  445.             Log.d(TAG, "Log stored in SDcard, the path is:"  

  446.                     + LOG_PATH_SDCARD_DIR + File.separator + logFileName);  

  447.             return LOG_PATH_SDCARD_DIR + File.separator + logFileName;  

  448.         }  

  449.     }  

  450.   

  451.     /** 

  452.      * 处理日志文件 1.如果日志文件存储位置切换到内存中,删除除了正在写的日志文件 并且部署日志大小监控任务,控制日志大小不超过规定值 

  453.      * 2.如果日志文件存储位置切换到SDCard中,删除7天之前的日志,移 动所有存储在内存中的日志到SDCard中,并将之前部署的日志大小 监控取消 

  454.      */  

  455.     public void handleLog()  

  456.     {  

  457.         if (CURR_LOG_TYPE == MEMORY_TYPE)  

  458.         {  

  459.             deployLogSizeMonitorTask();  

  460.             deleteMemoryExpiredLog();  

  461.         } else  

  462.         {  

  463.             moveLogfile();  

  464.             cancelLogSizeMonitorTask();  

  465.             deleteSDcardExpiredLog();  

  466.         }  

  467.     }  

  468.   

  469.     /** 

  470.      * 部署日志大小监控任务 

  471.      */  

  472.     private void deployLogSizeMonitorTask()  

  473.     {  

  474.         if (logSizeMoniting)  

  475.         { // 如果当前正在监控着,则不需要继续部署  

  476.             return;  

  477.         }  

  478.         logSizeMoniting = true;  

  479.         Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);  

  480.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  

  481.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  

  482.         am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),  

  483.                 MEMORY_LOG_FILE_MONITOR_INTERVAL, sender);  

  484.         Log.d(TAG, "deployLogSizeMonitorTask() succ !");  

  485.         // recordLogServiceLog("deployLogSizeMonitorTask() succ ,start time is "  

  486.         // + calendar.getTime().toLocaleString());  

  487.     }  

  488.   

  489.     /** 

  490.      * 取消部署日志大小监控任务 

  491.      */  

  492.     private void cancelLogSizeMonitorTask()  

  493.     {  

  494.         logSizeMoniting = false;  

  495.         AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);  

  496.         Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);  

  497.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  

  498.         am.cancel(sender);  

  499.   

  500.         Log.d(TAG, "canelLogSizeMonitorTask() succ");  

  501.     }  

  502.   

  503.     /** 

  504.      * 检查日志文件大小是否超过了规定大小 如果超过了重新开启一个日志收集进程 

  505.      */  

  506.     private void checkLogSize()  

  507.     {  

  508.         if (CURR_INSTALL_LOG_NAME != null && !"".equals(CURR_INSTALL_LOG_NAME))  

  509.         {  

  510.             String path = LOG_PATH_MEMORY_DIR + File.separator  

  511.                     + CURR_INSTALL_LOG_NAME;  

  512.             File file = new File(path);  

  513.             if (!file.exists())  

  514.             {  

  515.                 return;  

  516.             }  

  517.             Log.d(TAG, "checkLog() ==> The size of the log is too big?");  

  518.             if (file.length() >= MEMORY_LOG_FILE_MAX_SIZE)  

  519.             {  

  520.                 Log.d(TAG, "The log's size is too big!");  

  521.                 new LogCollectorThread().start();  

  522.             }  

  523.         }  

  524.     }  

  525.   

  526.     /** 

  527.      * 创建日志目录 

  528.      */  

  529.     private void createLogDir()  

  530.     {  

  531.         File file = new File(LOG_PATH_MEMORY_DIR);  

  532.         boolean mkOk;  

  533.         if (!file.isDirectory())  

  534.         {  

  535.             mkOk = file.mkdirs();  

  536.             if (!mkOk)  

  537.             {  

  538.                 mkOk = file.mkdirs();  

  539.             }  

  540.         }  

  541.   

  542.         /* ************************************ 

  543.          * file = new File(LOG_SERVICE_LOG_PATH); if (!file.exists()) { try { 

  544.          * mkOk = file.createNewFile(); if (!mkOk) { file.createNewFile(); } } 

  545.          * catch (IOException e) { Log.e(TAG, e.getMessage(), e); } } 

  546.          * *********************************** 

  547.          */  

  548.   

  549.         if (Environment.getExternalStorageState().equals(  

  550.                 Environment.MEDIA_MOUNTED))  

  551.         {  

  552.             file = new File(LOG_PATH_SDCARD_DIR);  

  553.             if (!file.isDirectory())  

  554.             {  

  555.                 mkOk = file.mkdirs();  

  556.                 if (!mkOk)  

  557.                 {  

  558.                     recordLogServiceLog("move file failed,dir is not created succ");  

  559.                     return;  

  560.                 }  

  561.             }  

  562.         }  

  563.     }  

  564.   

  565.     /** 

  566.      * 将日志文件转移到SD卡下面 

  567.      */  

  568.     private void moveLogfile()  

  569.     {  

  570.         if (!Environment.getExternalStorageState().equals(  

  571.                 Environment.MEDIA_MOUNTED))  

  572.         {  

  573.             // recordLogServiceLog("move file failed, sd card does not mount");  

  574.             return;  

  575.         }  

  576.         File file = new File(LOG_PATH_SDCARD_DIR);  

  577.         if (!file.isDirectory())  

  578.         {  

  579.             boolean mkOk = file.mkdirs();  

  580.             if (!mkOk)  

  581.             {  

  582.                 // recordLogServiceLog("move file failed,dir is not created succ");  

  583.                 return;  

  584.             }  

  585.         }  

  586.   

  587.         file = new File(LOG_PATH_MEMORY_DIR);  

  588.         if (file.isDirectory())  

  589.         {  

  590.             File[] allFiles = file.listFiles();  

  591.             for (File logFile : allFiles)  

  592.             {  

  593.                 String fileName = logFile.getName();  

  594.                 if (logServiceLogName.equals(fileName))  

  595.                 {  

  596.                     continue;  

  597.                 }  

  598.                 // String createDateInfo =  

  599.                 // getFileNameWithoutExtension(fileName);  

  600.                 boolean isSucc = copy(logFile, new File(LOG_PATH_SDCARD_DIR  

  601.                         + File.separator + fileName));  

  602.                 if (isSucc)  

  603.                 {  

  604.                     logFile.delete();  

  605.                     // recordLogServiceLog("move file success,log name is:"+fileName);  

  606.                 }  

  607.             }  

  608.         }  

  609.     }  

  610.   

  611.     /** 

  612.      * 删除内存下过期的日志 

  613.      */  

  614.     private void deleteSDcardExpiredLog()  

  615.     {  

  616.         File file = new File(LOG_PATH_SDCARD_DIR);  

  617.         if (file.isDirectory())  

  618.         {  

  619.             File[] allFiles = file.listFiles();  

  620.             for (File logFile : allFiles)  

  621.             {  

  622.                 String fileName = logFile.getName();  

  623.                 if (logServiceLogName.equals(fileName))  

  624.                 {  

  625.                     continue;  

  626.                 }  

  627.                 String createDateInfo = getFileNameWithoutExtension(fileName);  

  628.                 if (canDeleteSDLog(createDateInfo))  

  629.                 {  

  630.                     logFile.delete();  

  631.                     Log.d(TAG, "delete expired log success,the log path is:"  

  632.                             + logFile.getAbsolutePath());  

  633.   

  634.                 }  

  635.             }  

  636.         }  

  637.     }  

  638.   

  639.     /** 

  640.      * 判断sdcard上的日志文件是否可以删除 

  641.      *  

  642.      * @param createDateStr 

  643.      * @return  

  644.      */  

  645.     public boolean canDeleteSDLog(String createDateStr)  

  646.     {  

  647.         boolean canDel = false;  

  648.         Calendar calendar = Calendar.getInstance();  

  649.         calendar.add(Calendar.DAY_OF_MONTH, -1 * SDCARD_LOG_FILE_SAVE_DAYS);// 删除7天之前日志  

  650.         Date expiredDate = calendar.getTime();  

  651.         try  

  652.         {  

  653.             Date createDate = sdf.parse(createDateStr);  

  654.             canDel = createDate.before(expiredDate);  

  655.         } catch (ParseException e)  

  656.         {  

  657.             Log.e(TAG, e.getMessage(), e);  

  658.             canDel = false;  

  659.         }  

  660.         return canDel;  

  661.     }  

  662.   

  663.     /** 

  664.      * 删除内存中的过期日志,删除规则: 除了当前的日志和离当前时间最近的日志保存其他的都删除 

  665.      */  

  666.     private void deleteMemoryExpiredLog()  

  667.     {  

  668.         File file = new File(LOG_PATH_MEMORY_DIR);  

  669.         if (file.isDirectory())  

  670.         {  

  671.             File[] allFiles = file.listFiles();  

  672.             Arrays.sort(allFiles, new FileComparator());  

  673.             for (int i = 0; i < allFiles.length - 2; i++)  

  674.             { // "-2"保存最近的两个日志文件  

  675.                 File _file = allFiles[i];  

  676.                 if (logServiceLogName.equals(_file.getName())  

  677.                         || _file.getName().equals(CURR_INSTALL_LOG_NAME))  

  678.                 {  

  679.                     continue;  

  680.                 }  

  681.                 _file.delete();  

  682.                 Log.d(TAG, "delete expired log success,the log path is:"  

  683.                         + _file.getAbsolutePath());  

  684.             }  

  685.         }  

  686.     }  

  687.   

  688.     /** 

  689.      * 拷贝文件 

  690.      *  

  691.      * @param source 

  692.      * @param target 

  693.      * @return  

  694.      */  

  695.     private boolean copy(File source, File target)  

  696.     {  

  697.         FileInputStream in = null;  

  698.         FileOutputStream out = null;  

  699.         try  

  700.         {  

  701.             if (!target.exists())  

  702.             {  

  703.                 boolean createSucc = target.createNewFile();  

  704.                 if (!createSucc)  

  705.                 {  

  706.                     return false;  

  707.                 }  

  708.             }  

  709.             in = new FileInputStream(source);  

  710.             out = new FileOutputStream(target);  

  711.             byte[] buffer = new byte[8 * 1024];  

  712.             int count;  

  713.             while ((count = in.read(buffer)) != -1)  

  714.             {  

  715.                 out.write(buffer, 0, count);  

  716.             }  

  717.             return true;  

  718.         } catch (Exception e)  

  719.         {  

  720.             e.printStackTrace();  

  721.             Log.e(TAG, e.getMessage(), e);  

  722.             recordLogServiceLog("copy file fail");  

  723.             return false;  

  724.         } finally  

  725.         {  

  726.             try  

  727.             {  

  728.                 if (in != null)  

  729.                 {  

  730.                     in.close();  

  731.                 }  

  732.                 if (out != null)  

  733.                 {  

  734.                     out.close();  

  735.                 }  

  736.             } catch (IOException e)  

  737.             {  

  738.                 e.printStackTrace();  

  739.                 Log.e(TAG, e.getMessage(), e);  

  740.                 recordLogServiceLog("copy file fail");  

  741.                 return false;  

  742.             }  

  743.         }  

  744.   

  745.     }  

  746.   

  747.     /** 

  748.      * 记录日志服务的基本信息 防止日志服务有错,在LogCat日志中无法查找 此日志名称为Log.log 

  749.      *  

  750.      * @param msg 

  751.      */  

  752.     private void recordLogServiceLog(String msg)  

  753.     {  

  754.         if (writer != null)  

  755.         {  

  756.             try  

  757.             {  

  758.                 Date time = new Date();  

  759.                 writer.write(myLogSdf.format(time) + " : " + msg);  

  760.                 writer.write("\n");  

  761.                 writer.flush();  

  762.             } catch (IOException e)  

  763.             {  

  764.                 e.printStackTrace();  

  765.                 Log.e(TAG, e.getMessage(), e);  

  766.             }  

  767.         }  

  768.     }  

  769.   

  770.     /** 

  771.      * 去除文件的扩展类型(.log) 

  772.      *  

  773.      * @param fileName 

  774.      * @return  

  775.      */  

  776.     private String getFileNameWithoutExtension(String fileName)  

  777.     {  

  778.         return fileName.substring(0, fileName.indexOf("."));  

  779.     }  

  780.   

  781.     class ProcessInfo {  

  782.         public String user;  

  783.         public String pid;  

  784.         public String ppid;  

  785.         public String name;  

  786.   

  787.         @Override  

  788.         public String toString()  

  789.         {  

  790.             String str = "user=" + user + " pid=" + pid + " ppid=" + ppid  

  791.                     + " name=" + name;  

  792.             return str;  

  793.         }  

  794.     }  

  795.   

  796.     class StreamConsumer extends Thread {  

  797.         InputStream is;  

  798.         List<String> list;  

  799.   

  800.         StreamConsumer(InputStream is) {  

  801.             this.is = is;  

  802.         }  

  803.   

  804.         StreamConsumer(InputStream is, List<String> list) {  

  805.             this.is = is;  

  806.             this.list = list;  

  807.         }  

  808.   

  809.         public void run()  

  810.         {  

  811.             try  

  812.             {  

  813.                 InputStreamReader isr = new InputStreamReader(is);  

  814.                 BufferedReader br = new BufferedReader(isr);  

  815.                 String line = null;  

  816.                 while ((line = br.readLine()) != null)  

  817.                 {  

  818.                     if (list != null)  

  819.                     {  

  820.                         list.add(line);  

  821.                     }  

  822.                 }  

  823.             } catch (IOException ioe)  

  824.             {  

  825.                 ioe.printStackTrace();  

  826.             }  

  827.         }  

  828.     }  

  829.   

  830.     /** 

  831.      * 监控SD卡状态 

  832.      *  

  833.      * @author Administrator 

  834.      *  

  835.      */  

  836.     class SDStateMonitorReceiver extends BroadcastReceiver {  

  837.         public void onReceive(Context context, Intent intent)  

  838.         {  

  839.   

  840.             if (Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction()))  

  841.             { // 存储卡被卸载  

  842.                 if (CURR_LOG_TYPE == SDCARD_TYPE)  

  843.                 {  

  844.                     Log.d(TAG, "SDcar is UNMOUNTED");  

  845.                     CURR_LOG_TYPE = MEMORY_TYPE;  

  846.                     new LogCollectorThread().start();  

  847.                 }  

  848.             } else  

  849.             { // 存储卡被挂载  

  850.                 if (CURR_LOG_TYPE == MEMORY_TYPE)  

  851.                 {  

  852.                     Log.d(TAG, "SDcar is MOUNTED");  

  853.                     CURR_LOG_TYPE = SDCARD_TYPE;  

  854.                     new LogCollectorThread().start();  

  855.   

  856.                 }  

  857.             }  

  858.         }  

  859.     }  

  860.   

  861.     /** 

  862.      * 日志任务接收 切换日志,监控日志大小 

  863.      *  

  864.      * @author Administrator 

  865.      *  

  866.      */  

  867.     class LogTaskReceiver extends BroadcastReceiver {  

  868.         public void onReceive(Context context, Intent intent)  

  869.         {  

  870.             String action = intent.getAction();  

  871.             if (SWITCH_LOG_FILE_ACTION.equals(action))  

  872.             {  

  873.                 new LogCollectorThread().start();  

  874.             } else if (MONITOR_LOG_SIZE_ACTION.equals(action))  

  875.             {  

  876.                 checkLogSize();  

  877.             }  

  878.         }  

  879.     }  

  880.   

  881.     class FileComparator implements Comparator<File> {  

  882.         public int compare(File file1, File file2)  

  883.         {  

  884.             if (logServiceLogName.equals(file1.getName()))  

  885.             {  

  886.                 return -1;  

  887.             } else if (logServiceLogName.equals(file2.getName()))  

  888.             {  

  889.                 return 1;  

  890.             }  

  891.   

  892.             String createInfo1 = getFileNameWithoutExtension(file1.getName());  

  893.             String createInfo2 = getFileNameWithoutExtension(file2.getName());  

  894.   

  895.             try  

  896.             {  

  897.                 Date create1 = sdf.parse(createInfo1);  

  898.                 Date create2 = sdf.parse(createInfo2);  

  899.                 if (create1.before(create2))  

  900.                 {  

  901.                     return -1;  

  902.                 } else  

  903.                 {  

  904.                     return 1;  

  905.                 }  

  906.             } catch (ParseException e)  

  907.             {  

  908.                 return 0;  

  909.             }  

  910.         }  

  911.     }  

  912.   

  913.     @Override  

  914.     public void onDestroy()  

  915.     {  

  916.         super.onDestroy();  

  917.         recordLogServiceLog("LogService onDestroy");  

  918.         if (writer != null)  

  919.         {  

  920.             try  

  921.             {  

  922.                 writer.close();  

  923.             } catch (IOException e)  

  924.             {  

  925.                 e.printStackTrace();  

  926.             }  

  927.         }  

  928.         if (process != null)  

  929.         {  

  930.             process.destroy();  

  931.         }  

  932.   

  933.         unregisterReceiver(sdStateReceiver);  

  934.         unregisterReceiver(logTaskReceiver);  

  935.     }  

  936.   

  937. }  


最后不要忘记在配置文件中加入
Xml代码 
<uses-permission android:name="android.permission.READ_LOGS" />



你可能感兴趣的:(Android的log保存到文件上查看)