Android的log保存到文件上查看

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

androidstringfilepathexceptionaction

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

  1. importjava.io.BufferedReader;

  2. importjava.io.File;

  3. importjava.io.FileInputStream;

  4. importjava.io.FileOutputStream;

  5. importjava.io.IOException;

  6. importjava.io.InputStream;

  7. importjava.io.InputStreamReader;

  8. importjava.io.OutputStreamWriter;

  9. importjava.text.ParseException;

  10. importjava.text.SimpleDateFormat;

  11. importjava.util.ArrayList;

  12. importjava.util.Arrays;

  13. importjava.util.Calendar;

  14. importjava.util.Comparator;

  15. importjava.util.Date;

  16. importjava.util.List;

  17. importandroid.app.AlarmManager;

  18. importandroid.app.PendingIntent;

  19. importandroid.app.Service;

  20. importandroid.content.BroadcastReceiver;

  21. importandroid.content.Context;

  22. importandroid.content.Intent;

  23. importandroid.content.IntentFilter;

  24. importandroid.os.Environment;

  25. importandroid.os.IBinder;

  26. importandroid.os.PowerManager;

  27. importandroid.os.PowerManager.WakeLock;

  28. importandroid.util.Log;

  29. /**

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

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

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

  33. *

  34. *@authorAdministrator

  35. *

  36. */

  37. publicclassLogServiceextendsService{

  38. privatestaticfinalStringTAG="LogService";

  39. privatestaticfinalintMEMORY_LOG_FILE_MAX_SIZE=10*1024*1024;//内存中日志文件最大值,10M

  40. privatestaticfinalintMEMORY_LOG_FILE_MONITOR_INTERVAL=10*60*1000;//内存中的日志文件大小监控时间间隔,10分钟

  41. privatestaticfinalintSDCARD_LOG_FILE_SAVE_DAYS=7;//sd卡中日志文件的最多保存天数

  42. privateStringLOG_PATH_MEMORY_DIR;//日志文件在内存中的路径(日志文件在安装目录中的路径)

  43. privateStringLOG_PATH_SDCARD_DIR;//日志文件在sdcard中的路径

  44. @SuppressWarnings("unused")

  45. privateStringLOG_SERVICE_LOG_PATH;//本服务产生的日志,记录日志服务开启失败信息

  46. privatefinalintSDCARD_TYPE=0;//当前的日志记录类型为存储在SD卡下面

  47. privatefinalintMEMORY_TYPE=1;//当前的日志记录类型为存储在内存中

  48. privateintCURR_LOG_TYPE=SDCARD_TYPE;//当前的日志记录类型

  49. privateStringCURR_INSTALL_LOG_NAME;//如果当前的日志写在内存中,记录当前的日志文件名称

  50. privateStringlogServiceLogName="Log.log";//本服务输出的日志文件名称

  51. privateSimpleDateFormatmyLogSdf=newSimpleDateFormat(

  52. "yyyy-MM-ddHH:mm:ss");

  53. privateOutputStreamWriterwriter;

  54. privateSimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHHmmss");//日志名称格式

  55. privateProcessprocess;

  56. privateWakeLockwakeLock;

  57. privateSDStateMonitorReceiversdStateReceiver;//SDcard状态监测

  58. privateLogTaskReceiverlogTaskReceiver;

  59. /*

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

  61. */

  62. privatebooleanlogSizeMoniting=false;

  63. privatestaticStringMONITOR_LOG_SIZE_ACTION="MONITOR_LOG_SIZE";//日志文件监测action

  64. privatestaticStringSWITCH_LOG_FILE_ACTION="SWITCH_LOG_FILE_ACTION";//切换日志文件action

  65. @Override

  66. publicIBinderonBind(Intentintent)

  67. {

  68. returnnull;

  69. }

  70. @Override

  71. publicvoidonCreate()

  72. {

  73. super.onCreate();

  74. init();

  75. register();

  76. deploySwitchLogFileTask();

  77. newLogCollectorThread().start();

  78. }

  79. privatevoidinit()

  80. {

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

  82. +"log";

  83. LOG_SERVICE_LOG_PATH=LOG_PATH_MEMORY_DIR+File.separator

  84. +logServiceLogName;

  85. LOG_PATH_SDCARD_DIR=Environment.getExternalStorageDirectory()

  86. .getAbsolutePath()

  87. +File.separator

  88. +"MyApp"

  89. +File.separator

  90. +"log";

  91. createLogDir();

  92. /*******************************************************

  93. *try{writer=newOutputStreamWriter(newFileOutputStream(

  94. *LOG_SERVICE_LOG_PATH,true));}catch(FileNotFoundExceptione){

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

  96. ******************************************************

  97. */

  98. PowerManagerpm=(PowerManager)getApplicationContext()

  99. .getSystemService(Context.POWER_SERVICE);

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

  101. CURR_LOG_TYPE=getCurrLogType();

  102. Log.i(TAG,"LogServiceonCreate");

  103. }

  104. privatevoidregister()

  105. {

  106. IntentFiltersdCarMonitorFilter=newIntentFilter();

  107. sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);

  108. sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);

  109. sdCarMonitorFilter.addDataScheme("file");

  110. sdStateReceiver=newSDStateMonitorReceiver();

  111. registerReceiver(sdStateReceiver,sdCarMonitorFilter);

  112. IntentFilterlogTaskFilter=newIntentFilter();

  113. logTaskFilter.addAction(MONITOR_LOG_SIZE_ACTION);

  114. logTaskFilter.addAction(SWITCH_LOG_FILE_ACTION);

  115. logTaskReceiver=newLogTaskReceiver();

  116. registerReceiver(logTaskReceiver,logTaskFilter);

  117. }

  118. /**

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

  120. *

  121. *@return

  122. */

  123. publicintgetCurrLogType()

  124. {

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

  126. Environment.MEDIA_MOUNTED))

  127. {

  128. returnMEMORY_TYPE;

  129. }else

  130. {

  131. returnSDCARD_TYPE;

  132. }

  133. }

  134. /**

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

  136. */

  137. privatevoiddeploySwitchLogFileTask()

  138. {

  139. Intentintent=newIntent(SWITCH_LOG_FILE_ACTION);

  140. PendingIntentsender=PendingIntent.getBroadcast(this,0,intent,0);

  141. Calendarcalendar=Calendar.getInstance();

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

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

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

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

  146. //部署任务

  147. AlarmManageram=(AlarmManager)getSystemService(ALARM_SERVICE);

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

  149. AlarmManager.INTERVAL_DAY,sender);

  150. recordLogServiceLog("deployNextTasksucc,nexttasktimeis:"

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

  152. }

  153. /**

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

  155. *OR删除

  156. */

  157. classLogCollectorThreadextendsThread{

  158. publicLogCollectorThread(){

  159. super("LogCollectorThread");

  160. Log.d(TAG,"LogCollectorThreadiscreate");

  161. }

  162. @Override

  163. publicvoidrun()

  164. {

  165. try

  166. {

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

  168. clearLogCache();

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

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

  171. killLogcatProc(processInfoList);

  172. createLogCollector();

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

  174. handleLog();

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

  176. }catch(Exceptione)

  177. {

  178. e.printStackTrace();

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

  180. }

  181. }

  182. }

  183. /**

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

  185. */

  186. privatevoidclearLogCache()

  187. {

  188. Processproc=null;

  189. List<String>commandList=newArrayList<String>();

  190. commandList.add("logcat");

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

  192. try

  193. {

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

  195. commandList.toArray(newString[commandList.size()]));

  196. StreamConsumererrorGobbler=newStreamConsumer(

  197. proc.getErrorStream());

  198. StreamConsumeroutputGobbler=newStreamConsumer(

  199. proc.getInputStream());

  200. errorGobbler.start();

  201. outputGobbler.start();

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

  203. {

  204. Log.e(TAG,"clearLogCacheproc.waitFor()!=0");

  205. recordLogServiceLog("clearLogCacheclearLogCacheproc.waitFor()!=0");

  206. }

  207. }catch(Exceptione)

  208. {

  209. Log.e(TAG,"clearLogCachefailed",e);

  210. recordLogServiceLog("clearLogCachefailed");

  211. }finally

  212. {

  213. try

  214. {

  215. proc.destroy();

  216. }catch(Exceptione)

  217. {

  218. Log.e(TAG,"clearLogCachefailed",e);

  219. recordLogServiceLog("clearLogCachefailed");

  220. }

  221. }

  222. }

  223. /**

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

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

  226. *

  227. *@paramallProcList

  228. *@return

  229. */

  230. privatevoidkillLogcatProc(List<ProcessInfo>allProcList)

  231. {

  232. if(process!=null)

  233. {

  234. process.destroy();

  235. }

  236. StringpackName=this.getPackageName();

  237. StringmyUser=getAppUser(packName,allProcList);

  238. /*

  239. *recordLogServiceLog("appuseris:"+myUser);

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

  241. *processInfo:allProcList){

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

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

  244. */

  245. for(ProcessInfoprocessInfo:allProcList)

  246. {

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

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

  249. {

  250. android.os.Process.killProcess(Integer

  251. .parseInt(processInfo.pid));

  252. //recordLogServiceLog("killanotherlogcatprocesssuccess,theprocessinfois:"

  253. //+processInfo);

  254. }

  255. }

  256. }

  257. /**

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

  259. *

  260. *@parampackName

  261. *@paramallProcList

  262. *@return

  263. */

  264. privateStringgetAppUser(StringpackName,List<ProcessInfo>allProcList)

  265. {

  266. for(ProcessInfoprocessInfo:allProcList)

  267. {

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

  269. {

  270. returnprocessInfo.user;

  271. }

  272. }

  273. returnnull;

  274. }

  275. /**

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

  277. *

  278. *@paramorgProcessList

  279. *@return

  280. */

  281. privateList<ProcessInfo>getProcessInfoList(List<String>orgProcessList)

  282. {

  283. List<ProcessInfo>procInfoList=newArrayList<ProcessInfo>();

  284. for(inti=1;i<orgProcessList.size();i++)

  285. {

  286. StringprocessInfo=orgProcessList.get(i);

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

  288. //USERPIDPPIDVSIZERSSWCHANPCNAME

  289. //root10416300c00d4b280000cd5cS/init

  290. List<String>orgInfo=newArrayList<String>();

  291. for(Stringstr:proStr)

  292. {

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

  294. {

  295. orgInfo.add(str);

  296. }

  297. }

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

  299. {

  300. ProcessInfopInfo=newProcessInfo();

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

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

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

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

  305. procInfoList.add(pInfo);

  306. }

  307. }

  308. returnprocInfoList;

  309. }

  310. /**

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

  312. *

  313. *@returnUSERPIDPPIDVSIZERSSWCHANPCNAMEroot10416300c00d4b28

  314. *0000cd5cS/init

  315. */

  316. privateList<String>getAllProcess()

  317. {

  318. List<String>orgProcList=newArrayList<String>();

  319. Processproc=null;

  320. try

  321. {

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

  323. StreamConsumererrorConsumer=newStreamConsumer(

  324. proc.getErrorStream());

  325. StreamConsumeroutputConsumer=newStreamConsumer(

  326. proc.getInputStream(),orgProcList);

  327. errorConsumer.start();

  328. outputConsumer.start();

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

  330. {

  331. Log.e(TAG,"getAllProcessproc.waitFor()!=0");

  332. recordLogServiceLog("getAllProcessproc.waitFor()!=0");

  333. }

  334. }catch(Exceptione)

  335. {

  336. Log.e(TAG,"getAllProcessfailed",e);

  337. recordLogServiceLog("getAllProcessfailed");

  338. }finally

  339. {

  340. try

  341. {

  342. proc.destroy();

  343. }catch(Exceptione)

  344. {

  345. Log.e(TAG,"getAllProcessfailed",e);

  346. recordLogServiceLog("getAllProcessfailed");

  347. }

  348. }

  349. returnorgProcList;

  350. }

  351. /**

  352. *开始收集日志信息

  353. */

  354. publicvoidcreateLogCollector()

  355. {

  356. StringlogFileName=sdf.format(newDate())+".log";//日志文件名称

  357. List<String>commandList=newArrayList<String>();

  358. commandList.add("logcat");

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

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

  361. commandList.add(getLogPath());

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

  363. commandList.add("time");

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

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

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

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

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

  369. try

  370. {

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

  372. commandList.toArray(newString[commandList.size()]));

  373. recordLogServiceLog("startcollectingthelog,andlognameis:"

  374. +logFileName);

  375. //process.waitFor();

  376. }catch(Exceptione)

  377. {

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

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

  380. }

  381. }

  382. /**

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

  384. *

  385. *@return

  386. */

  387. publicStringgetLogPath()

  388. {

  389. createLogDir();

  390. StringlogFileName=sdf.format(newDate())+".log";//日志文件名称

  391. if(CURR_LOG_TYPE==MEMORY_TYPE)

  392. {

  393. CURR_INSTALL_LOG_NAME=logFileName;

  394. Log.d(TAG,"Logstoredinmemory,thepathis:"

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

  396. returnLOG_PATH_MEMORY_DIR+File.separator+logFileName;

  397. }else

  398. {

  399. CURR_INSTALL_LOG_NAME=null;

  400. Log.d(TAG,"LogstoredinSDcard,thepathis:"

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

  402. returnLOG_PATH_SDCARD_DIR+File.separator+logFileName;

  403. }

  404. }

  405. /**

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

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

  408. */

  409. publicvoidhandleLog()

  410. {

  411. if(CURR_LOG_TYPE==MEMORY_TYPE)

  412. {

  413. deployLogSizeMonitorTask();

  414. deleteMemoryExpiredLog();

  415. }else

  416. {

  417. moveLogfile();

  418. cancelLogSizeMonitorTask();

  419. deleteSDcardExpiredLog();

  420. }

  421. }

  422. /**

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

  424. */

  425. privatevoiddeployLogSizeMonitorTask()

  426. {

  427. if(logSizeMoniting)

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

  429. return;

  430. }

  431. logSizeMoniting=true;

  432. Intentintent=newIntent(MONITOR_LOG_SIZE_ACTION);

  433. PendingIntentsender=PendingIntent.getBroadcast(this,0,intent,0);

  434. AlarmManageram=(AlarmManager)getSystemService(ALARM_SERVICE);

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

  436. MEMORY_LOG_FILE_MONITOR_INTERVAL,sender);

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

  438. //recordLogServiceLog("deployLogSizeMonitorTask()succ,starttimeis"

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

  440. }

  441. /**

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

  443. */

  444. privatevoidcancelLogSizeMonitorTask()

  445. {

  446. logSizeMoniting=false;

  447. AlarmManageram=(AlarmManager)getSystemService(ALARM_SERVICE);

  448. Intentintent=newIntent(MONITOR_LOG_SIZE_ACTION);

  449. PendingIntentsender=PendingIntent.getBroadcast(this,0,intent,0);

  450. am.cancel(sender);

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

  452. }

  453. /**

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

  455. */

  456. privatevoidcheckLogSize()

  457. {

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

  459. {

  460. Stringpath=LOG_PATH_MEMORY_DIR+File.separator

  461. +CURR_INSTALL_LOG_NAME;

  462. Filefile=newFile(path);

  463. if(!file.exists())

  464. {

  465. return;

  466. }

  467. Log.d(TAG,"checkLog()==>Thesizeofthelogistoobig?");

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

  469. {

  470. Log.d(TAG,"Thelog'ssizeistoobig!");

  471. newLogCollectorThread().start();

  472. }

  473. }

  474. }

  475. /**

  476. *创建日志目录

  477. */

  478. privatevoidcreateLogDir()

  479. {

  480. Filefile=newFile(LOG_PATH_MEMORY_DIR);

  481. booleanmkOk;

  482. if(!file.isDirectory())

  483. {

  484. mkOk=file.mkdirs();

  485. if(!mkOk)

  486. {

  487. mkOk=file.mkdirs();

  488. }

  489. }

  490. /*************************************

  491. *file=newFile(LOG_SERVICE_LOG_PATH);if(!file.exists()){try{

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

  493. *catch(IOExceptione){Log.e(TAG,e.getMessage(),e);}}

  494. ************************************

  495. */

  496. if(Environment.getExternalStorageState().equals(

  497. Environment.MEDIA_MOUNTED))

  498. {

  499. file=newFile(LOG_PATH_SDCARD_DIR);

  500. if(!file.isDirectory())

  501. {

  502. mkOk=file.mkdirs();

  503. if(!mkOk)

  504. {

  505. recordLogServiceLog("movefilefailed,dirisnotcreatedsucc");

  506. return;

  507. }

  508. }

  509. }

  510. }

  511. /**

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

  513. */

  514. privatevoidmoveLogfile()

  515. {

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

  517. Environment.MEDIA_MOUNTED))

  518. {

  519. //recordLogServiceLog("movefilefailed,sdcarddoesnotmount");

  520. return;

  521. }

  522. Filefile=newFile(LOG_PATH_SDCARD_DIR);

  523. if(!file.isDirectory())

  524. {

  525. booleanmkOk=file.mkdirs();

  526. if(!mkOk)

  527. {

  528. //recordLogServiceLog("movefilefailed,dirisnotcreatedsucc");

  529. return;

  530. }

  531. }

  532. file=newFile(LOG_PATH_MEMORY_DIR);

  533. if(file.isDirectory())

  534. {

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

  536. for(FilelogFile:allFiles)

  537. {

  538. StringfileName=logFile.getName();

  539. if(logServiceLogName.equals(fileName))

  540. {

  541. continue;

  542. }

  543. //StringcreateDateInfo=

  544. //getFileNameWithoutExtension(fileName);

  545. booleanisSucc=copy(logFile,newFile(LOG_PATH_SDCARD_DIR

  546. +File.separator+fileName));

  547. if(isSucc)

  548. {

  549. logFile.delete();

  550. //recordLogServiceLog("movefilesuccess,lognameis:"+fileName);

  551. }

  552. }

  553. }

  554. }

  555. /**

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

  557. */

  558. privatevoiddeleteSDcardExpiredLog()

  559. {

  560. Filefile=newFile(LOG_PATH_SDCARD_DIR);

  561. if(file.isDirectory())

  562. {

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

  564. for(FilelogFile:allFiles)

  565. {

  566. StringfileName=logFile.getName();

  567. if(logServiceLogName.equals(fileName))

  568. {

  569. continue;

  570. }

  571. StringcreateDateInfo=getFileNameWithoutExtension(fileName);

  572. if(canDeleteSDLog(createDateInfo))

  573. {

  574. logFile.delete();

  575. Log.d(TAG,"deleteexpiredlogsuccess,thelogpathis:"

  576. +logFile.getAbsolutePath());

  577. }

  578. }

  579. }

  580. }

  581. /**

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

  583. *

  584. *@paramcreateDateStr

  585. *@return

  586. */

  587. publicbooleancanDeleteSDLog(StringcreateDateStr)

  588. {

  589. booleancanDel=false;

  590. Calendarcalendar=Calendar.getInstance();

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

  592. DateexpiredDate=calendar.getTime();

  593. try

  594. {

  595. DatecreateDate=sdf.parse(createDateStr);

  596. canDel=createDate.before(expiredDate);

  597. }catch(ParseExceptione)

  598. {

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

  600. canDel=false;

  601. }

  602. returncanDel;

  603. }

  604. /**

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

  606. */

  607. privatevoiddeleteMemoryExpiredLog()

  608. {

  609. Filefile=newFile(LOG_PATH_MEMORY_DIR);

  610. if(file.isDirectory())

  611. {

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

  613. Arrays.sort(allFiles,newFileComparator());

  614. for(inti=0;i<allFiles.length-2;i++)

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

  616. File_file=allFiles[i];

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

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

  619. {

  620. continue;

  621. }

  622. _file.delete();

  623. Log.d(TAG,"deleteexpiredlogsuccess,thelogpathis:"

  624. +_file.getAbsolutePath());

  625. }

  626. }

  627. }

  628. /**

  629. *拷贝文件

  630. *

  631. *@paramsource

  632. *@paramtarget

  633. *@return

  634. */

  635. privatebooleancopy(Filesource,Filetarget)

  636. {

  637. FileInputStreamin=null;

  638. FileOutputStreamout=null;

  639. try

  640. {

  641. if(!target.exists())

  642. {

  643. booleancreateSucc=target.createNewFile();

  644. if(!createSucc)

  645. {

  646. returnfalse;

  647. }

  648. }

  649. in=newFileInputStream(source);

  650. out=newFileOutputStream(target);

  651. byte[]buffer=newbyte[8*1024];

  652. intcount;

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

  654. {

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

  656. }

  657. returntrue;

  658. }catch(Exceptione)

  659. {

  660. e.printStackTrace();

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

  662. recordLogServiceLog("copyfilefail");

  663. returnfalse;

  664. }finally

  665. {

  666. try

  667. {

  668. if(in!=null)

  669. {

  670. in.close();

  671. }

  672. if(out!=null)

  673. {

  674. out.close();

  675. }

  676. }catch(IOExceptione)

  677. {

  678. e.printStackTrace();

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

  680. recordLogServiceLog("copyfilefail");

  681. returnfalse;

  682. }

  683. }

  684. }

  685. /**

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

  687. *

  688. *@parammsg

  689. */

  690. privatevoidrecordLogServiceLog(Stringmsg)

  691. {

  692. if(writer!=null)

  693. {

  694. try

  695. {

  696. Datetime=newDate();

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

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

  699. writer.flush();

  700. }catch(IOExceptione)

  701. {

  702. e.printStackTrace();

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

  704. }

  705. }

  706. }

  707. /**

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

  709. *

  710. *@paramfileName

  711. *@return

  712. */

  713. privateStringgetFileNameWithoutExtension(StringfileName)

  714. {

  715. returnfileName.substring(0,fileName.indexOf("."));

  716. }

  717. classProcessInfo{

  718. publicStringuser;

  719. publicStringpid;

  720. publicStringppid;

  721. publicStringname;

  722. @Override

  723. publicStringtoString()

  724. {

  725. Stringstr="user="+user+"pid="+pid+"ppid="+ppid

  726. +"name="+name;

  727. returnstr;

  728. }

  729. }

  730. classStreamConsumerextendsThread{

  731. InputStreamis;

  732. List<String>list;

  733. StreamConsumer(InputStreamis){

  734. this.is=is;

  735. }

  736. StreamConsumer(InputStreamis,List<String>list){

  737. this.is=is;

  738. this.list=list;

  739. }

  740. publicvoidrun()

  741. {

  742. try

  743. {

  744. InputStreamReaderisr=newInputStreamReader(is);

  745. BufferedReaderbr=newBufferedReader(isr);

  746. Stringline=null;

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

  748. {

  749. if(list!=null)

  750. {

  751. list.add(line);

  752. }

  753. }

  754. }catch(IOExceptionioe)

  755. {

  756. ioe.printStackTrace();

  757. }

  758. }

  759. }

  760. /**

  761. *监控SD卡状态

  762. *

  763. *@authorAdministrator

  764. *

  765. */

  766. classSDStateMonitorReceiverextendsBroadcastReceiver{

  767. publicvoidonReceive(Contextcontext,Intentintent)

  768. {

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

  770. {//存储卡被卸载

  771. if(CURR_LOG_TYPE==SDCARD_TYPE)

  772. {

  773. Log.d(TAG,"SDcarisUNMOUNTED");

  774. CURR_LOG_TYPE=MEMORY_TYPE;

  775. newLogCollectorThread().start();

  776. }

  777. }else

  778. {//存储卡被挂载

  779. if(CURR_LOG_TYPE==MEMORY_TYPE)

  780. {

  781. Log.d(TAG,"SDcarisMOUNTED");

  782. CURR_LOG_TYPE=SDCARD_TYPE;

  783. newLogCollectorThread().start();

  784. }

  785. }

  786. }

  787. }

  788. /**

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

  790. *

  791. *@authorAdministrator

  792. *

  793. */

  794. classLogTaskReceiverextendsBroadcastReceiver{

  795. publicvoidonReceive(Contextcontext,Intentintent)

  796. {

  797. Stringaction=intent.getAction();

  798. if(SWITCH_LOG_FILE_ACTION.equals(action))

  799. {

  800. newLogCollectorThread().start();

  801. }elseif(MONITOR_LOG_SIZE_ACTION.equals(action))

  802. {

  803. checkLogSize();

  804. }

  805. }

  806. }

  807. classFileComparatorimplementsComparator<File>{

  808. publicintcompare(Filefile1,Filefile2)

  809. {

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

  811. {

  812. return-1;

  813. }elseif(logServiceLogName.equals(file2.getName()))

  814. {

  815. return1;

  816. }

  817. StringcreateInfo1=getFileNameWithoutExtension(file1.getName());

  818. StringcreateInfo2=getFileNameWithoutExtension(file2.getName());

  819. try

  820. {

  821. Datecreate1=sdf.parse(createInfo1);

  822. Datecreate2=sdf.parse(createInfo2);

  823. if(create1.before(create2))

  824. {

  825. return-1;

  826. }else

  827. {

  828. return1;

  829. }

  830. }catch(ParseExceptione)

  831. {

  832. return0;

  833. }

  834. }

  835. }

  836. @Override

  837. publicvoidonDestroy()

  838. {

  839. super.onDestroy();

  840. recordLogServiceLog("LogServiceonDestroy");

  841. if(writer!=null)

  842. {

  843. try

  844. {

  845. writer.close();

  846. }catch(IOExceptione)

  847. {

  848. e.printStackTrace();

  849. }

  850. }

  851. if(process!=null)

  852. {

  853. process.destroy();

  854. }

  855. unregisterReceiver(sdStateReceiver);

  856. unregisterReceiver(logTaskReceiver);

  857. }

  858. }


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



更多相关文章

  1. Android应用程序中Manifest.java文件的介绍
  2. Android多文件断点续传(三)——实现文件断点续传
  3. Android中内存占用的含义:(VSS,PSS,RSS,USS)
  4. Android 导入android源码有错,R.java文件不能自动生成解决方法
  5. Android 开发日志之仿三星Launcher
  6. Android App 内存泄露之资源

随机推荐

  1. Layout 笔记
  2. MQTT的学习研究(十五) MQTT 和android整合
  3. ANDROID 编译源码6.0 问题记录
  4. Android之MediaCodec使用经验分享
  5. android 实现代码关机
  6. 图片缓存优化
  7. Android8.0 页面崩溃问题
  8. android之知识点小结二
  9. android中intent的作用
  10. android 截屏