Android app record run log captures crash exception, store log to file

Source: Internet
Author: User
Tags dateformat thread stop

logging is a great way to keep the app running, and for later maintenance upgrades.

In order to read the log to the app runtime, it is common practice to open a thread separately, to run the app on the startup thread, and then to deactivate the thread when the app exits.

However, the better way is to open a service and then log in, the code is as follows:

Package Com.hai.logcat;import Java.io.bufferedreader;import Java.io.datainputstream;import java.io.File;import Java.io.filenotfoundexception;import Java.io.fileoutputstream;import Java.io.ioexception;import Java.io.inputstream;import Java.io.inputstreamreader;import Java.util.list;import Android.app.ActivityManager; Import Android.app.activitymanager.runningappprocessinfo;import Android.app.service;import android.content.Intent ; Import Android.os.environment;import Android.os.ibinder;import android.os.looper;import Android.util.Log;import Android.widget.toast;public class Mylogcat extends Service {Thread Thread;boolean readlog = true; @Overridepublic IBinder Onbind (Intent Intent) {return null;} @Overridepublic void OnCreate () {super.oncreate (); LOG.D ("HHP", "onCreate"), thread = new Thread (new Runnable () {@Overridepublic void run () {log2 ();//Personal feel this method more practical});} @Overridepublic void OnStart (Intent Intent, int startid) {Thread.Start (); LOG.D ("HHP", "OnStart"); Super.onstart (Intent, Startid);} /** * SquareMethod 1 */private void log2 () {log.d ("hhp", "log2 start"); String[] Cmds = {"Logcat", "-C"}; String shellcmd = "Logcat-v time-s *:w"; ADB logcat-v time *:wprocess process = null; Runtime runtime = Runtime.getruntime (); BufferedReader reader = null;try {runtime.exec (CMDS). WaitFor ();p rocess = Runtime.exec (shellcmd); reader = new BufferedReader (New InputStreamReader (Process.getinputstream ())); String line = null;while (line = Reader.readline ()) = null) {if (Line.contains (string.valueof (android.os.Process.myPid ())) {//Line = new String (line.getbytes ("iso-8859-1"), "Utf-8"); WriteToFile (line);}}} catch (Exception e) {e.printstacktrace ();} LOG.D ("HHP", "Log2 finished");} /** * Method 2 */private void log () {LOG.D ("hhp", "Log Start"); String[] Cmds = {"Logcat", "-C"}; String shellcmd = "Logcat-v time-s *:w";////ADB logcat-v time *:wprocess process = Null;inputstream is = NULL;DATAINP Utstream dis = null; String line = ""; Runtime runtime = Runtime.getruntime (); try {runtime.exec (cmds);p rocess = ruNtime.exec (shellcmd); is = Process.getinputstream ();d are = new DataInputStream (IS);//String filter = Getpid (); String filter = Android.os.Process.myPid () + "" while (line = Dis.readline ()) = null) {//here if the input stream is not broken, it will continue to loop. line = new String (line.getbytes ("iso-8859-1"), "Utf-8"), if (Line.contains (filter)) {int pos = Line.indexof (":"); LOG.D ("Hhp2", Line + ""); WriteToFile (line);}}} catch (Exception e) {}log.d ("hhp", "Log finished");} private void WriteToFile (string line) {string content = line + "\ r \ n"; File File = new file (Environment.getexternalstoragedirectory (). GetAbsolutePath () + "/logcat/mylog.txt"); File.exists ()) {try {file.createnewfile ();} catch (Exception e) {e.printstacktrace ()}} FileOutputStream fos;try {fos = new FileOutputStream (file, True); Fos.write (Content.getbytes ()); Fos.flush (); fos.close ();} catch (Exception e) {e.printstacktrace ();}} @Overridepublic void OnDestroy () {Super.ondestroy (); Stopself ();}}
The code is relatively simple, so I don't have much of a stare. The next idea: When the service is turned on, the thread keeps reading the input stream from the Logcat.

Put the read information into the file, the service stopped when the thread stop, it is so simple.

Of course, to read into the system log you also need to add permissions:

<uses-permission android:name= "Android.permission.READ_LOGS"/>

Here is my record of the test log, the information record a bit more, in practice can use the regular filter out some information.


The above code basically can be recorded in the app running logs, but if there is an uncaught exception in the middle of the app crash, then this uncaught exception caused by the crash above the code is not logged.

because this exception causes the app to crash and the virtual machine hangs, the thread that logs the log also stops. So how do we catch such an uncaught exception (run-time exception), fortunately Android

An interface Uncaughtexceptionhandler, when the app crashes, it notifies the interface first, so we can do something we want to do before the app crashes.

about how to catch the crash, I think this buddy's blog is a good piece of writing http://blog.csdn.net/liuhe688/article/details/6584143#, I borrowed from the following:

Package Com.hai.logcat;import Java.io.file;import Java.io.fileoutputstream;import java.io.printwriter;import Java.io.stringwriter;import Java.io.writer;import Java.lang.thread.uncaughtexceptionhandler;import Java.lang.reflect.field;import Java.text.dateformat;import Java.text.simpledateformat;import java.util.Date; Import Java.util.hashmap;import java.util.map;import Android.content.context;import android.content.pm.PackageInfo ; Import Android.content.pm.packagemanager;import Android.content.pm.packagemanager.namenotfoundexception;import Android.os.build;import Android.os.environment;import Android.os.looper;import Android.util.Log;import Android.widget.toast;public class Crashhandler implements Uncaughtexceptionhandler {public static final String TAG = "Cra Shhandler ";//system default Uncaughtexception processing class private Thread.uncaughtexceptionhandler mdefaulthandler;// Crashhandler instance private static Crashhandler INSTANCE = new Crashhandler ();//Program Context object private Context mcontext;// Used to store device information and exception information privatemap<string, string> infos = new hashmap<string, string> ();//For formatting dates, as part of the log file name private DateFormat Formatter = new SimpleDateFormat ("Yyyy-mm-dd HH:mm:ss");/** guarantee only one Crashhandler instance */private Crashhandler () {}/** get crash Handler instance, singleton mode */public static Crashhandler getinstance () {return INSTANCE;} /** * Initialize * * @param context */public void init (context context) {Mcontext = context;//get system default Uncaughtexception processor Mdefau Lthandler = Thread.getdefaultuncaughtexceptionhandler ();// Set the Crashhandler as the program's default processor Thread.setdefaultuncaughtexceptionhandler (this);} /** * When uncaughtexception occurs, it is transferred to the function to process */@Overridepublic void uncaughtexception (thread thread, Throwable ex) {if (! HandleException (ex) && Mdefaulthandler! = null) {//If the user does not handle it, let the system default exception handler handle the Mdefaulthandler.uncaughtexception (thread, ex);} else {try {thread.sleep,} catch (Interruptedexception e) {log.e (TAG, "error:", e);} Exit Program Android.os.Process.killProcess (Android.os.Process.myPid ()); System.exit (1);}} /** * Custom error handling, collecting error lettersSend error reports, and so on. * * @param ex * @return true: Returns False if the exception information is processed; */private Boolean handleexception (Final Throwable ex) {if (ex = = null) {return false;} Use Toast to display exception information new Thread () {@Overridepublic void run () {looper.prepare (); Ex.printstacktrace (); Toast.maketext (Mcontext, "Sorry, the program has an exception and is about to exit.", Toast.length_long). Show (); Looper.loop ();}}. Start ();//Collect equipment parameter information collectdeviceinfo (mcontext);//Save log file Savecrashinfo2file (ex); return true;} /** * Collect device parameter information * * @param ctx */public void Collectdeviceinfo (Context ctx) {try {packagemanager pm = ctx.getpackagemanage R (); PackageInfo pi = pm.getpackageinfo (Ctx.getpackagename (), packagemanager.get_activities); if (pi! = null) {String Versionname = Pi.versionname = = null? "NULL": Pi.versionname; String Versioncode = Pi.versioncode + ""; Infos.put ("Versionname", Versionname); Infos.put ("Versioncode", VersionCode);}} catch (Namenotfoundexception e) {log.e (TAG, "An error occured if collect package info", e);} field[] fields = Build.class.getDeclaredFields (); (Field field:fields) {try {field.setaccessible (true); Infos.put (Field.getname (), Field.get (null). ToString ()); LOG.D (TAG, Field.getname () + ":" + field.get (null));} catch (Exception e) {log.e (TAG, "An error occured when collect crash info", e);}} /** * Save error message to file * * @param ex * @return return file name for easy Transfer of file to server */private String Savecrashinfo2file (Throwable ex) {Stringbuff ER sb = new StringBuffer (); for (map.entry<string, string> entry:infos.entrySet ()) {String key = Entry.getkey (); String value = Entry.getvalue (); Sb.append (key + "=" + value + "\ n");} Writer writer = new StringWriter (); PrintWriter printwriter = new PrintWriter (writer); Ex.printstacktrace (PrintWriter); Throwable cause = Ex.getcause (); while (cause! = null) {cause.printstacktrace (printwriter); cause = Cause.getcause ();} Printwriter.close (); String result = Writer.tostring (); String time = Formatter.format (new Date ()), Sb.append (time + result), try {long timestamp = System.currenttimemillis (); String fileName = "Crash.log"; if (ENVIronment.getexternalstoragestate (). Equals (environment.media_mounted)) {String Path = Environment.getexternalstoragedirectory (). GetAbsolutePath () + "/logcat/"; File dir = new file (path), if (!dir.exists ()) {dir.mkdirs ();} FileOutputStream fos = new FileOutputStream (path + FileName, True), Fos.write ((Sb.tostring ()). GetBytes ()); Fos.close (); return fileName;} catch (Exception e) {log.e (TAG, "An error occured while writing file ...", e);} return null;}}

Above we implemented this interface, and then before the crash did some friendly processing, such as storage of the crash log, actively kill the process, do not let the system to force close the dialog box.

And then we can do that in application.

Package Com.hai;import Android.app.application;import Com.hai.logcat.crashhandler;public class MyApplication extends application {Crashhandler handler = null, @Overridepublic void OnCreate () {super.oncreate (); handler = Crashhandler.getinstance (); Handler.init (Getapplicationcontext ());}}







Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Android app record run log captures crash exception, store log to file

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.