Saturday, September 11, 2010

An Android Logging Class That Writes to SD Card

In case anyone's interested... I'm currently trying to work out the cause of a very uncommon lockup that happens with one or two of the wallpapers.  It only seems to happen on HTC phones so I'm honestly guessing it's a driver bug, but the real problem is that it happens with no apparent cause with a frequency of perhaps once or twice per day.

I've got an HTC Incredible here that I have seen it happen on, the problem is actually seeing what's going on.  I'd normally use the system log, but since this problem can lock-up the phone, that log gets wiped out upon a restart.  So, I've tossed together a simple static logging class that can output to an SD card.  The filename is tagged with the date and time upon creation, so it won't overwrite an earlier file, and since it's on the SD card it can run and get plenty gigantic.  I've put calls to LogToSD.write at the top of basically every single method on the wallpaper, so it's going to get big by the time I see it lock up next.  :P

Here's the class, if anyone's looking for something like this.  Don't forget you'll need to set uses-permission WRITE_EXTERNAL_STORAGE.

public class LogToSD
{
    static PrintWriter outFile = null;
  
    private static void initialize()
    {
        try {
            File root = Environment.getExternalStorageDirectory();
            if( root.canWrite() )
            {
                Calendar rightNow = Calendar.getInstance();
                long day = rightNow.get( Calendar.DAY_OF_YEAR );
                long hour = rightNow.get( Calendar.HOUR_OF_DAY );
                long minutes = rightNow.get( Calendar.MINUTE );
                long seconds = rightNow.get( Calendar.SECOND );
              
                String date = day + "-" + hour + "-" + minutes + "-" + seconds;
              
                File gpxfile = new File( root, "log_" + date + ".log" );
                FileWriter gpxwriter = new FileWriter( gpxfile );
                outFile = new PrintWriter( gpxwriter );
                outFile.write( "\n\n----- Initiating LogToSD Session -----\n" );
                outFile.write( "----- Start Time: " + date + " -----\n\n" );
            }
        } catch (IOException e) {
            Log.e( "LogToSD", "Could not write to file: " + e.getMessage());
        }
    }
  
    public static void write( String text1, String text2 )
    {
        if( outFile == null )
            initialize();
      
        Calendar rightNow = Calendar.getInstance();
        long minutes = rightNow.get( Calendar.MINUTE );
        long seconds = rightNow.get( Calendar.SECOND );
        long ms = rightNow.get( Calendar.MILLISECOND );
      
        String time = minutes + ":" + seconds + "." + ms;

        outFile.write( time + "\t" + text1 + " " + text2 + "\n" );
        outFile.flush();
      
        Log.v( "LogToSD", text1 + " " + text2 );
    }
  
    public static void shutdown()
    {
        if( outFile != null )
            outFile.close();
    }
}

4 comments:

  1. Hi there,

    I'm looking for a logging class to log some of the values used in my application for a user testing. I came across this blog and found this interesting and I'm wandering if it's possible to use it for my ends.
    How does this exactly combine with an applications? I should create this class in my project and then call the LogtoSD whenever I need to log some variables? How do I do this? Can you please explain a little bit. I really need this.

    Also, is it possible to Log the time between an action?

    Thank you very very much in advance.

    Pedro

    ReplyDelete
  2. I also would like to know what this variable is :VersionDefinition

    I'm sorry for the newbie questions, I really have to have this working and probably I'm skipping some steps that I should know about Android but I really don't have to learn it, just make it work for user testing.

    Thank you again

    ReplyDelete
  3. Well, I'm a month and a half late here, but the tag in the log print is just whatever you want the 'name' of the print to be. VersionDefinition.TAG is just a static string I use to keep that consistent across a project. You can just set it to "MyProject" or whatever you want.

    ReplyDelete
  4. I had this working .. and now out of nothing I get a:

    09-17 15:12:51.085: ERROR/AndroidRuntime(777): java.lang.NullPointerException

    associated with:

    09-17 15:12:51.085: ERROR/AndroidRuntime(777): at com.pedroteixeira.thennnow.LogToSD.write(LogToSD.java:53)


    This Android is so frustrating sometimes.. I'm taking a life to build an application..

    ReplyDelete