开发者

how to write exception in log file using android?

I want to write text file开发者_JAVA百科 in sd card when I get an exception from my application

How to implement this concept in my application?


I'd create my own logger class and use that. In fact here is basically what I do, but you could modify this so it only writes out exceptions:

public class Logger {
private static Logger instance = null;
private static final int MAX_LOGS = 10;

public enum Level { DEBUG, INFO, WARN, ERROR }

private Level level = Level.ERROR;
private String tag;
private SimpleDateFormat format = new SimpleDateFormat("MM/dd/yy hh:mm:ss z");
private File log;
private PrintWriter writer;
private String supportEmail;

public void LoggerSetup(String tag, String logFilename, Level level ) {
    //close previous
    if( writer != null ) {
        writer.flush();
        writer.close();
        writer = null;
    }
    //open new
    this.tag = tag;
    this.log = createWriter( logFilename );
    this.level = level;
}

public Logger(Context context) {
    LoggerSetup(context.getPackageName(), "application.log", Level.INFO);
}

public static Logger getInstance(Context context) {
    if(instance == null) {
        instance = new Logger(context);
    }
    return instance;
}

public Logger() {
    LoggerSetup("", "application.log", Level.INFO);
}

private File createWriter(String logFilename) {
    try {
        String state = Environment.getExternalStorageState();
        if( state.equals(Environment.MEDIA_MOUNTED) ) {
            File dir = new File( Environment.getExternalStorageDirectory(), "com.yourpackage");
            if( !dir.mkdirs() ) {
                Log.w( tag, "Could not create log directory: " + dir.getAbsolutePath() );
            }
            File log = new File(dir, logFilename);
            if( log.exists() ) {
                rotate( log );
            }
            Log.i( tag, "Opening " + log.getAbsolutePath() );
            writer = new PrintWriter( new FileWriter( log ), true );
            return log;
        } else {
            Log.w( tag, "Could not create log file because external storage state was " + state);
        }
    } catch( IOException ioe ) {
        Log.e( tag, "Failed while opening the log file.", ioe );
    }

    return null;
}

private void rotate(File log) {
    int index = log.getName().lastIndexOf('.');
    if( index < 0 ) index = log.getName().length();
    String prefix = log.getName().substring(0, index );
    String extension = log.getName().substring(index);

    int lastLog = MAX_LOGS - 1;
    File lastLogFile = new File( log.getParentFile(), prefix + "-" + lastLog + extension );
    if( lastLogFile.exists() ) lastLogFile.delete();

    for( int i = lastLog; i >= 1; --i ) {
        String filename = prefix + "-" + i + extension;
        File l = new File( log.getParentFile(), filename );
        if( l.exists() ) {
            File newLog = new File( log.getParentFile(), prefix + "-" + (i+1) + extension );
            l.renameTo( newLog );
        }
    }

    log.renameTo( new File( log.getParentFile(), prefix + "-1" + extension ) );
}

public Level getLevel() {
    return level;
}

public void setLevel(Level level) {
    this.level = level;
}

public boolean isLoggable( Level level ) {
    return level.ordinal() >= this.level.ordinal();
}

public void debug( String message, Object... parameters ) {
    if( parameters.length > 0 ) {
        Log.d( tag, MessageFormat.format( message, parameters ) );
    } else {
        Log.d( tag, message );
    }
    log( Level.DEBUG, message, parameters );
}

public void info( String message, Object... parameters ) {
    if( parameters.length > 0 ) {
        Log.i( tag, MessageFormat.format( message, parameters ) );
    } else {
        Log.i( tag, message );
    }
    log( Level.INFO, message, parameters );
}

public void warn( String message, Object... parameters ) {
    if( parameters.length > 0 ) {
        Log.w( tag, MessageFormat.format( message, parameters ) );
    } else {
        Log.w( tag, message );
    }
    log( Level.WARN, message, parameters );
}

public void error( String message, Object... parameters ) {
    if( parameters.length > 0 ) {
        Log.e( tag, MessageFormat.format( message, parameters ) );
    } else {
        Log.e( tag, message );
    }
    log( Level.ERROR, message, parameters );
}

public void error(Throwable throwable) {
    String message = Log.getStackTraceString( throwable );
    Log.e( tag, message, throwable );
    log( Level.ERROR, message );
}

public void close() {
    if( writer != null ) {
        writer.flush();
        writer.close();
        writer = null;
    }
}

private void log( Level level, String message, Object... parameters ) {
    if( writer != null && isLoggable(level) ) {
        Date date = new Date();
        writer.print( format.format(date) );
        writer.print( " " );
        writer.print( level.toString() );
        writer.print( " " );
        writer.print( tag );
        writer.print( " " );
        writer.print( Thread.currentThread().getName() );
        writer.print( " - " );
        if( parameters.length > 0 ) {
            writer.println( MessageFormat.format( message, parameters ) );
        } else {
            writer.println( message );
        }
    }
}

protected void sendEmail(Context context) throws IOException {
    File[] logs = log.getParentFile().listFiles( new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.getName().endsWith(".log");
        }
    });

    File temp = zipLogFiles(logs);
    String[] mailto = { supportEmail };
    Intent sendIntent = new Intent(Intent.ACTION_SEND);
    sendIntent.setType("application/zip");
    sendIntent.putExtra(Intent.EXTRA_EMAIL, mailto);
    sendIntent.putExtra(Intent.EXTRA_SUBJECT, tag + ": Log File Attached");
    sendIntent.putExtra(Intent.EXTRA_TEXT, "A user has requested you look at some logs.");
    sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(temp) );
    sendIntent.setType("text/plain");
    context.startActivity(Intent.createChooser(sendIntent, "Send Logs To Support"));
}

private File zipLogFiles(File[] logs) throws IOException {
    File zipfile = File.createTempFile("brewster", ".zip");
    ZipOutputStream stream = new ZipOutputStream( new FileOutputStream(zipfile) );
    try {
        for( File log : logs ) {
            ZipEntry entry = new ZipEntry( log.getName() );
            stream.putNextEntry( entry );
            copy( stream, log );
            stream.closeEntry();
        }
        stream.finish();
        return zipfile;
    } finally {
        stream.close();
    }
}

private void copy(OutputStream stream, File file) throws IOException {
    InputStream istream = new FileInputStream( file );
    try {
        byte[] buffer = new byte[8096];
        int length = 0;
        while( (length = istream.read( buffer )) >= 0 ) {
            stream.write( buffer, 0, length );
        }
    } finally {
        istream.close();
    }
}

}


A general way to go about this, although in practice you should use buffered streams whenever possible.

In your onCreate(Bundle savedInstanceState) callback or anywhere else you want to do this logging:

try
{
//normal application code

}
//called whenever an Exception is thrown
catch(Exception e)
{
//stream for writing text
FileWriter writer=null;
try
{
    writer = new FileWriter(this.getExternalFilesDir());
    //write to the SD card
} catch(Throwable t) {}
finally
{
    if(writer != null) writer.close();
}

}

Note that I omitted checking for the SD card, but you should always do this. See http://developer.android.com/guide/topics/data/data-storage.html#filesExternal

Sorry for the crappy code formatting. This little text box is nothing like Eclipse.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜