Android 写日志到文本文件

我尝试用我的这个代码写日志到 Android 文件中的自定义 Log.txt 文件,但是这个方法创建文件却什么都不包含。基本上,我想读取文件的先前内容,然后附加我的数据与现有的内容。

守则如下:

public static void write(String str)
{
InputStream fileInputStream = null;
FileOutputStream fileOutpurStream = null;
try
{
fileInputStream = new FileInputStream(file);
fileOutpurStream = new FileOutputStream(file);
if(file.exists())
{
int ch = 0;
int current = 0;
StringBuffer buffer = new StringBuffer();
while((ch = fileInputStream.read()) != -1)
{
buffer.append((char) ch);
current++;
}
byte data[]=new byte[(int)file.length()];
fileInputStream.read(data);
fileOutpurStream.write(data);
fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
fileOutpurStream.flush();
}
else
{
file.createNewFile();
fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
fileOutpurStream.flush();
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
fileInputStream.close();
fileOutpurStream.flush();
fileOutpurStream.close();
fileOutpurStream = null;
fileInputStream = null;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
232783 次浏览

通常,在打开流之前必须有一个文件句柄。Else 块中有一个 fileOutputStream 句柄 之前 createNewFile ()。如果文件不存在,则流不创建该文件。

虽然不是 Android 特有的操作系统,但是对于这个目的来说,这是一个很大的 IO。如果您一个接一个地执行许多“写”操作会怎样?您将阅读整个内容和写整个内容,花费时间,更重要的是,电池寿命。

我建议使用 java.io。随机访问文件,查找()‘ ing 到结尾,然后写入 Chars ()来追加。它将是更清晰的代码,并且可能更快。

警告: 我可能完全误解了你,但是如果你想要的只是一个日志文件,为什么要紧张呢?

将其放入 bat 文件(更改工具目录的路径,yourappname 当然就是应用程序的名称) :

cd "C:\devAndroid\Software\android-sdk-windows-1.6_r1\android-sdk-windows-1.6_r1\tools"
adb logcat -v time   ActivityManager:W  yourappname:D  *:W >"C:\devAndroid\log\yourappname.log"

然后在代码中执行类似的操作:

Log.d("yourappname", "Your message");

要创建日志,请连接 USB 线并运行 bat 文件。

问候

你应该看看 microlog4android,他们有一个可以记录到文件的解决方案。

Http://code.google.com/p/microlog4android/

希望这个能帮上忙。

public void appendLog(String text)
{
File logFile = new File("sdcard/log.file");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
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)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Microlog4android 对我来说很好用,但是文档很差。所有他们需要添加的是一个这是一个快速启动 教程

下面是我找到的一个快速教程。

  1. 在主活动中添加以下静态变量:

    private static final Logger logger = LoggerFactory.getLogger();
    
  2. Add the following to your onCreate() method:

    PropertyConfigurator.getConfigurator(this).configure();
    
  3. Create a file named microlog.properties and store it in assets directory

  4. Edit the microlog.properties file as follows:

    microlog.level=DEBUG
    microlog.appender=LogCatAppender;FileAppender
    microlog.formatter=PatternFormatter
    microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
    
  5. Add logging statements like this:

    logger.debug("M4A");
    

For each class you create a logger object as specified in 1)

6.You may be add the following permission:

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

这里是 来源教程

这可能有点晚了,但希望这能有所帮助。 试试这个。

public void writefile()
{
File externalStorageDir = Environment.getExternalStorageDirectory();
File myFile = new File(externalStorageDir , "yourfilename.txt");


if(myFile.exists())
{
try
{


FileOutputStream fostream = new FileOutputStream(myFile);
OutputStreamWriter oswriter = new OutputStreamWriter(fostream);
BufferedWriter bwriter = new BufferedWriter(oswriter);
bwriter.write("Hi welcome ");
bwriter.newLine();
bwriter.close();
oswriter.close();
fostream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
try {
myFile.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
}

这里 bfwritter.newline把你的文本写入文件。并添加权限

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

在您的清单文件没有失败。

我用以下命令行代码解决了这个问题:

File outputFile = new File("pathToFile");
Runtime.getRuntime().exec("logcat -c");
Runtime.getRuntime().exec("logcat -v time -f " + outputFile.getAbsolutePath())

其中,“ time”选项为发出消息的进程的日期、调用时间、优先级/标记和 PID 添加元数据字段详细信息。

然后在代码中执行类似的操作(使用 android.util. Log) :

Log.d("yourappname", "Your message");

对于那些刚接触 Java 日志和 Android 日志的人来说

  1. Log4j 是通用的 Java 日志记录实现,现在是 Apache软件基金会。它不是安卓特有的,因此 与 Android 的一些不兼容性。
  2. SL4J 不是一个日志实现,它是一个抽象层 有助于避免类似的情况,每个第三方图书馆 试图使用自己的日志记录 类似 Log4j.来源的实现。

下面是在 Android 中登录到 txt 的一些选项

  1. 使用此 回答中的 logcat -f来记录到文件 Android 4.2,READ _ LOGS 权限没有任何影响 应用程序(除非手机被植根)只能读取它自己的日志。 这里的缺点是 logcat buffer 是圆形的,并且有一个大小 您可能不会得到早期的日志。
  2. 使用 Microlog4android(为 Android 等移动设备编写)作为 可能有办法,但我不知道怎么做 使用 microlog4Android 将日志记录到应用程序内部存储。 日志路径的唯一选项是像 sdcard 这样的外部存储器,所以我 用不了。
  3. 使用 日志4jAndroid-log-log4j 它使得 Log4j 在 Android 中更容易使用 通过给出两个函数。

    • 除了日志文件之外,还可以将日志发送到 logcat
    • 通过提供 LogConfigurator 类来设置 Log4j 配置选项(如文件路径、最大文件大小、备份数量等)的简单方法。

    下面是一个简单的例子。请注意,下面示例中的 logger对象是返回的 Log4j 对象,而不是 android-log-Log4j 类。因此,android-log-Log4j 仅用于配置 Log4j。

  4. 然而尝试 日志返回.LogBack 是由同一个人开发的 提供了 Log4J 1.x 和 SL4J 库,与 Log4J 2. x 无关 不过。

在 Android 中使用 Log4j 的步骤。

  1. Log4j-1.2. x. jarAndroid-log-log4j-1.0.3. jar同时添加到 Libs 文件夹

  2. 仅在使用外部存储时添加权限
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  3. 编写 Log4j助手类

    package com.example.logger;
    
    
    import android.os.Environment;
    import de.mindpipe.android.logging.log4j.LogConfigurator;
    
    
    public class Log4jHelper {
    private final static LogConfigurator mLogConfigrator = new LogConfigurator();
    
    
    static {
    configureLog4j();
    }
    
    
    private static void configureLog4j() {
    String fileName = Environment.getExternalStorageDirectory() + "/" + "log4j.log";
    String filePattern = "%d - [%c] - %p : %m%n";
    int maxBackupSize = 10;
    long maxFileSize = 1024 * 1024;
    
    
    configure( fileName, filePattern, maxBackupSize, maxFileSize );
    }
    
    
    private static void configure( String fileName, String filePattern, int maxBackupSize, long maxFileSize ) {
    mLogConfigrator.setFileName( fileName );
    mLogConfigrator.setMaxFileSize( maxFileSize );
    mLogConfigrator.setFilePattern(filePattern);
    mLogConfigrator.setMaxBackupSize(maxBackupSize);
    mLogConfigrator.setUseLogCatAppender(true);
    mLogConfigrator.configure();
    
    
    }
    
    
    public static org.apache.log4j.Logger getLogger( String name ) {
    org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger( name );
    return logger;
    }
    }
    
  4. In Activity class

    org.apache.log4j.Logger log= Log4jHelper.getLogger( "YourActivity" );
    log.error("Error");
    log.info("Info");
    log.warn("Warn");
    

Example Source. Note that, log4j 2.x ( improved functionalities ) rewritten from scratch is not backward comptible with log4j 1.x. So you have to use log4j 1.2.x jar with android-logging-log4j jar. I was able to log to application internal file and later email the file with setReadable(true, false)

使用 Slf4机器人 lib。
这是使用 android java.util.log. * 对 Slf4j api的简单实现。

特点:

  • 将日志记录到文件开箱即用
  • 通过 LoggerConfiguration.configuration().addHandlerToLogger登录到任何其他目的地
  • 摇动你的设备通过电子邮件发送截图日志
  • 非常小,只需要约55kB

Slf4android 主要由 @ miensol维护。

在我们的博客上阅读更多关于 slf4android 的内容:

我已经创建了一个简单的、轻量级的类(大约260个 LoC) ,它扩展了标准的 android.util。基于文件的日志记录实现:
每条日志消息都通过 android.util.Log 记录,并写入设备上的文本文件。

你可以在 github 上找到:
Https://github.com/volkerv/filelog

这种变体要短得多

try {
final File path = new File(
Environment.getExternalStorageDirectory(), "DBO_logs5");
if (!path.exists()) {
path.mkdir();
}
Runtime.getRuntime().exec(
"logcat  -d -f " + path + File.separator
+ "dbo_logcat"
+ ".txt");
} catch (IOException e) {
e.printStackTrace();
}

你可以使用我写的图书馆。 它非常容易使用:

将这个依赖项添加到你的等级文件中:

dependencies {
compile 'com.github.danylovolokh:android-logger:1.0.2'
}

在 Application 类中初始化库:

File logsDirectory = AndroidLogger.getDefaultLogFilesDirectory(this);
int logFileMaxSizeBytes = 2 * 1024 * 1024; // 2Mb
try {
AndroidLogger.initialize(
this,
logsDirectory,
"Log_File_Name",
logFileMaxSizeBytes,
false
);
} catch (IOException e) {
// Some error happened - most likely there is no free space on the system
}

这就是你如何使用图书馆:

AndroidLogger.v("TAG", "Verbose Message");

下面是如何检索日志:

AndroidLogger.processPendingLogsStopAndGetLogFiles(new AndroidLogger.GetFilesCallback() {
@Override
public void onFiles(File[] logFiles) {
// get everything you need from these files
try {
AndroidLogger.reinitAndroidLogger();
} catch (IOException e) {
e.printStackTrace();
}
}
});

下面是链接到 github 页面的更多信息: Https://github.com/danylovolokh/androidlogger

希望能有帮助。

Log4j 上以前的许多版本现在都不能工作了(05/2019)。但是你可以使用 Hyperlog-我可以确认它的工作原理。

  1. 将此行添加到您的依赖项和同步项目

    implementation 'com.hypertrack:hyperlog:0.0.10'
    
  2. Create a new application class (create a new java class and extend Application). Then in the onCreate method add these lines:

    HyperLog.initialize(this);
    HyperLog.setLogLevel(Log.VERBOSE);
    
    
    HyperLog.getDeviceLogsInFile(this);
    
  3. Change manifest file to have application file defined.

    <application
    android:name=".AppClass"
    .....
    
  4. Different ways to log:

    HyperLog.d(TAG,"debug");
    HyperLog.i(TAG,"information");
    HyperLog.e(TAG,"error");
    HyperLog.v(TAG,"verbose");
    HyperLog.w(TAG,"warning");
    HyperLog.a(TAG,"assert");
    HyperLog.exception(TAG,"exception",throwable);
    
  5. Find your log files. Navigate to

    RootFolder/android/data/"appPackageName/LogFiles/
    

经过长时间的调查,我发现:

  • 默认情况下使用 java.util.logging.Logger
  • LogCat 使用名为 ""logger来获取它的实例,使用 LogManager.getLogManager().getLogger("")
  • Android 设备在运行调试应用程序后添加到 com.android.internal.logging.AndroidHandler的 LogCatlogger实例
  • 但是! ! ! com.android.internal.logging.AndroidHandler打印消息到 logcat,只是级别高于 java.util.logging.Level.INFO,比如(Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF)

因此,要将日志写入文件,只需在 rootLogger ""中添加一个 java.util.logging.FileHandler:

  class App : Application{
override fun onCreate() {
super.onCreate()
Log.d(TAG, printLoggers("before setup"))


val rootLogger = java.util.logging.LogManager.getLogManager().getLogger("")
val dirFile = destinationFolder
val file = File(dirFile,"logFile.txt")
val handler = java.util.logging.FileHandler(file.absolutePath, 5* 1024 * 1024/*5Mb*/, 1, true)
handler.formatter = AndroidLogFormatter(filePath = file.absolutePath)


rootLogger?.addHandler(handler)


Log.d(TAG, printLoggers("after setup"))
}
}


val destinationFolder: File
get() {
val parent =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absoluteFile
val destinationFolder = File(parent, "MyApp")
if (!destinationFolder.exists()) {
destinationFolder.mkdirs()
destinationFolder.mkdir()
}
return destinationFolder
}
class AndroidLogFormatter(val filePath: String = "", var tagPrefix: String = "") : Formatter() {


override fun format(record: LogRecord): String {
val tag = record.getTag(tagPrefix)
val date = record.getDate()
val level = record.getLogCatLevel()
val message = record.getLogCatMessage()
return "$date $level$tag: $message\n"
}
}


fun LogRecord.getTag(tagPrefix: String): String {
val name = loggerName
val maxLength = 30
val tag = tagPrefix + (if (name.length > maxLength) name.substring(name.length - maxLength) else name)
return tag
}


fun LogRecord.getDate(): String? {
return Date(millis).formatedBy("yyyy-MM-dd HH:mm:ss.SSS")
}


fun Date?.formatedBy(dateFormat: String): String? {
val date = this
date ?: return null
val writeFormat = SimpleDateFormat(dateFormat, Locale.getDefault()) //MM в HH:mm
return writeFormat.format(date)
}


fun LogRecord.getLogCatMessage(): String {
var message = message


if (thrown != null) {
message += Log.getStackTraceString(thrown)
}
return message
}


fun Int.getAndroidLevel(): Int {
return when {
this >= Level.SEVERE.intValue() -> { // SEVERE
Log.ERROR
}
this >= Level.WARNING.intValue() -> { // WARNING
Log.WARN
}
this >= Level.INFO.intValue() -> { // INFO
Log.INFO
}
else -> {
Log.DEBUG
}
}
}


fun LogRecord.getLogCatLevel(): String {
return when (level.intValue().getAndroidLevel()) {
Log.ERROR -> { // SEVERE
"E/"
}
Log.WARN -> { // WARNING
"W/"
}
Log.INFO -> { // INFO
"I/"
}
Log.DEBUG -> {
"D/"
}
else -> {
"D/"
}
}
}


fun getLoggerLevel(level: Int): Level {
return when (level) {
Log.ERROR -> { // SEVERE
Level.SEVERE
}
Log.WARN -> { // WARNING
Level.WARNING
}
Log.INFO -> { // INFO
Level.INFO
}
Log.DEBUG -> {
Level.FINE
}
else -> {
Level.FINEST
}
}
}

要打印应用程序中的所有记录器,请使用:

Log.e(TAG, printLoggers("before setup"))


private fun printLoggers(caller: String, printIfEmpty: Boolean = true): String {
val builder = StringBuilder()
val loggerNames = LogManager.getLogManager().loggerNames
builder.appendln("--------------------------------------------------------------")
builder.appendln("printLoggers: $caller")
while (loggerNames.hasMoreElements()) {
val element = loggerNames.nextElement()
val logger = LogManager.getLogManager().getLogger(element)
val parentLogger: Logger? = logger.parent
val handlers = logger.handlers
val level = logger?.level
if (!printIfEmpty && handlers.isEmpty()) {
continue
}
val handlersNames = handlers.map {
val handlerName = it.javaClass.simpleName
val formatter: Formatter? = it.formatter
val formatterName = if (formatter is AndroidLogFormatter) {
"${formatter.javaClass.simpleName}(${formatter.filePath})"
} else {
formatter?.javaClass?.simpleName
}
"$handlerName($formatterName)"
}
builder.appendln("level: $level logger: \"$element\" handlers: $handlersNames parentLogger: ${parentLogger?.name}")
}
builder.appendln("--------------------------------------------------------------")
return builder.toString()
}
    File logFile = new File(filename);
try {
Process process = Runtime.getRuntime().exec("logcat AndroidRuntime:E *:S
-f " + logFile);
}
catch ( Exception e )
{ Basic.Logger("Error Basic", "error "+e); }

请尝试使用此代码在文件中写入错误日志