如何使用android在日志文件中编写异常?

时间:2011-07-20 04:55:39

标签: android

我想在sd卡中写文本文件  我的申请中的例外

如何在我的实施中实现这一概念  应用?

2 个答案:

答案 0 :(得分:12)

我会创建自己的记录器类并使用它。事实上,这基本上就是我所做的,但你可以修改它,所以它只写出例外:

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();
    }
}

}

答案 1 :(得分:0)

解决此问题的一般方法,尽管在实践中应尽可能使用缓冲流。

onCreate(Bundle savedInstanceState)回调或您想要执行此操作的任何其他位置:

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();
}

}

请注意,我省略了对SD卡的检查,但您应该始终这样做。见http://developer.android.com/guide/topics/data/data-storage.html#filesExternal

很抱歉这个糟糕的代码格式。这个小文本框与Eclipse完全不同。