4

My program is crashing in device. I want to exactly catch the log of my program while running in my device .i.e I want to write the log to my sd card, up to the point of crashing. How can I achieve this?

Lucifer
  • 29,392
  • 25
  • 90
  • 143
Strawberry
  • 667
  • 2
  • 10
  • 24
  • You can simply connect your device with USB port and run the application, and check the logs in DDMS, why you want to write the logs in file ? – Lucifer Apr 02 '14 at 05:10
  • i dont know what happening in my external device . that only im asking how to write that log to my sdcard or some thing.? – Strawberry Apr 02 '14 at 05:11
  • 3
    I don't now about how to write exception logs in device but I have implemented [ARCA](https://github.com/ACRA/acra) for tracing crashes. – maddy d Apr 02 '14 at 05:14

4 Answers4

8

Try this

Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); // add this to your activity page

public class ExceptionHandler implements
        java.lang.Thread.UncaughtExceptionHandler {
    private final Context myContext;
    private final String LINE_SEPARATOR = "\n";
    UncaughtExceptionHandler defaultUEH;

    public ExceptionHandler(Context con) {
        myContext = con;
        defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    }

    @SuppressWarnings("deprecation")
    public void uncaughtException(Thread thread, Throwable exception) {

        StringWriter stackTrace = new StringWriter();
        exception.printStackTrace(new PrintWriter(stackTrace));
        StringBuilder errorReport = new StringBuilder();
        errorReport.append("************ CAUSE OF ERROR ************\n\n");
        errorReport.append(stackTrace.toString());

        errorReport.append("\n************ DEVICE INFORMATION ***********\n");
        errorReport.append("Brand: ");
        errorReport.append(Build.BRAND);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Device: ");
        errorReport.append(Build.DEVICE);
        errorReport.append(LINE_SEPARATOR);
        errorReport.append("Model: ");
        errorReport.append(Build.MODEL);
        errorReport.append(LINE_SEPARATOR);

        File root = android.os.Environment.getExternalStorageDirectory();
        String currentDateTimeString = DateFormat.getDateTimeInstance().format(
                new Date());

        File dir = new File(root.getAbsolutePath() + "/dir_name/log");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File file = new File(dir, "log.txt");

        try {
            BufferedWriter buf = new BufferedWriter(new FileWriter(file, true));
            buf.append(currentDateTimeString + ":" + errorReport.toString());
            buf.newLine();
            buf.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        defaultUEH.uncaughtException(thread, exception);
        System.exit(0);
    }

}
Jitesh Upadhyay
  • 5,244
  • 2
  • 25
  • 43
Shini
  • 573
  • 4
  • 11
  • 1
    give some explanation with code. – Sohil Desai Apr 02 '14 at 06:07
  • 1
    but million doller question, 'how to use this??' – Shirish Herwade Apr 17 '15 at 06:21
  • Thanks Dude its working – pranavjayadev Jan 21 '16 at 05:38
  • Please guide a bit !! `Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));` This shud be called in 'onCreate()' or 'onResume()'. I mean which is better, i am unable to decide ! If we call it in **`onCreate()`** then ExceptioHandler will be called once, & if called in **`onResume()`** then will be called everytime the Activity comes in foreground. – Pawan Jul 04 '16 at 13:07
5

Once I got this from somewhere in SO. Try this:

public static void printLog(Context context){
    String filename = context.getExternalFilesDir(null).getPath() + File.separator + "my_app.log";
    String command = "logcat -f "+ filename + " -v time *:V";

    Log.d(TAG, "command: " + command);

    try{
        Runtime.getRuntime().exec(command);
    }
    catch(IOException e){
        e.printStackTrace();
    }
}

This prints log continuously until the app exit.

Rashad
  • 11,057
  • 4
  • 45
  • 73
1

Try this :

    public void appendLog(String text) {       
        File logFile = new File("sdcard/log.file");
        if (!logFile.exists()) {
           try {
               logFile.createNewFile();
            } 
           catch (IOException e) {
               Log.e(TAG, e.getMessage(), e);
           }
        }
        try {
           //BufferedWriter for performance, true to set append to file flag
           BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
           buf.append(text);
           buf.newLine();
           buf.close();
        } catch (IOException e) {

           Log.e(TAG, e.getMessage(), e);
        }
    }
Rohit Sharma
  • 13,787
  • 8
  • 57
  • 72
Himanshu Agarwal
  • 4,623
  • 5
  • 35
  • 49
0

If you want to catch only the exception with the stacktrace, which in most cases is enough to get what was wrong, then ACRA is a winning solution.

If you do want to write something to your SD card then take in consideration that you can't assume that any device has external storage that you can write to. Unless you validate this.

To bring another option of writing to external storage you can use this simple library:
android-simple-storage

This is how you use it:

  • Prepare somewhere in your app:

    Storage storage = SimpleStorage.getExternalStorage();
    
    // create your own directory
    storage.createDirectory("MyDir");
    
    // create the file you want to write to inside your new directory
    storage.createFile("MyDir", "MyFile.txt", "");
    
  • Append any string (or byte[]) whenever you want to this file:

    storage.appendFile("MyDir", "MyFile.txt", "your log line");
    

You can create/read/update/delete with this tiny library files on internal and external storages very easy. And, take into consideration that writing to the same file will increase the space it takes. You can use getSize() from the same library to validate.

sromku
  • 4,663
  • 1
  • 36
  • 37