簡體   English   中英

Android 將日志寫入文本文件

[英]Android Writing Logs to text File

我正在嘗試使用我的此代碼將日志寫入 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();
            }
        }

希望這可以幫助...

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

對於一般 Java 日志記錄和 Android 日志記錄的新手

  1. Log4j是通用的 java 日志實現,現在是 Apache 軟件基金會的一個項目。 它不是 Android 特定的,因此與 Android 有一些不兼容。
  2. SL4J 不是日志記錄實現,它是一個抽象層。 它有助於避免諸如每個 3rd 方庫依賴於項目的情況,嘗試使用自己的日志記錄實現,如 Log4j。 來源

在 Android 中登錄到 txt 的一些選項如下

  1. 在此答案中使用logcat -f登錄到文件。 請注意,從 Android 4.2 開始,READ_LOGS 權限沒有任何影響,每個應用程序(除非手機已 root)只能讀取自己的日志。 這里的缺點是 logcat 緩沖區是循環的並且有大小限制。 您可能無法獲得較早的日志。
  2. 使用microlog4android (為 Android 等移動設備編寫),如前面的答案 可能有一種方法,但我想不通,如何使用 microlog4Android 登錄到應用程序內部存儲。 日志路徑的唯一選項是像 sdcard 這樣的外部存儲,所以我無法使用它。
  3. Log4jandroid-logging-log4j 一起使用 android-logging-log4j 有什么作用? 它通過提供兩個功能使 Log4j 在 Android 中更易於使用。

    • 除了日志文件之外,還可以選擇將日志發送到 logcat
    • 通過提供 LogConfigurator 類來設置 Log4j 配置選項(如文件路徑、最大文件大小、備份數量等)的簡單方法。

    下面的簡單例子。 請注意,下面示例中的logger對象是返回的 Log4j 對象,而不是 android-logging-log4j 類。 所以android-logging-log4j只用於配置Log4j。

  4. 尚未嘗試LogBack LogBack 是由提出 Log4J 1.x 和 SL4J 庫的同一個人開發的。 雖然與 Log4j 2.x 無關。

在 Android 中使用 Log4j 的步驟。

  1. log4j-1.2.x.jarandroid-logging-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. 在活動類

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

示例源 請注意,從頭開始重寫的 log4j 2.x(改進的功能)不能與 log4j 1.x 向后兼容。 因此,您必須將 log4j 1.2.x jar 與 android-logging-log4j jar 一起使用。 我能夠登錄到應用程序內部文件,然后使用setReadable(true, false)通過電子郵件發送文件

microlog4android 對我有用,但文檔很差。 他們需要添加的只是一個快速入門教程

這是我找到的快速教程。

  1. 在主活動中添加以下靜態變量:

     private static final Logger logger = LoggerFactory.getLogger();
  2. 將以下內容添加到您的onCreate()方法中:

     PropertyConfigurator.getConfigurator(this).configure();
  3. 創建一個名為microlog.properties的文件並將microlog.properties存儲在assets目錄中

  4. 編輯microlog.properties文件如下:

     microlog.level=DEBUG microlog.appender=LogCatAppender;FileAppender microlog.formatter=PatternFormatter microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
  5. 添加這樣的日志語句:

     logger.debug("M4A");

為每個類創建一個記錄器對象,如 1) 中指定的那樣

6.您可以添加以下權限:

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

這是教程的來源

警告:我可能完全誤解了你,但如果你想要的只是一個日志文件,為什么要出汗呢?

把它放在一個 bat 文件中(改變你的工具目錄的路徑,你的appname當然是你的應用程序的名字):

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 文件。

問候

使用slf4android庫。
這是使用 android java.util.logging.* 的slf4j api的簡單實現。

特征:

  • 開箱即用地登錄到文件
  • 通過LoggerConfiguration.configuration().addHandlerToLogger記錄到任何其他目的地
  • 搖動您的設備以通過電子郵件發送帶有屏幕截圖的日志
  • 真的很小,只需要~55kB

slf4android 主要由@miensol維護。

在我們的博客上閱讀有關 slf4android 的更多信息:

這可能會晚,但希望這可能會有所幫助..試試這個....

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"/>

在您的清單文件中沒有失敗。

你應該看看microlog4android。 他們有一個解決方案可以記錄到文件中。

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

我以命令行方式使用以下代碼解決了這個問題:

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

其中“時間”選項為日期、調用時間、優先級/標簽和發出消息的進程的 PID 添加元數據字段詳細信息。

然后在您的代碼中執行與此類似的操作(使用 android.util.Log):

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

我創建了一個簡單的輕量級類(大約 260 LoC),它使用基於文件的日志記錄擴展了標准的 android.util.Log 實現:
每條日志消息都通過 android.util.Log 記錄並寫入設備上的文本文件。

你可以在github上找到它:
https://github.com/volkerv/FileLog

通常,在打開流之前您必須有一個文件句柄。 在 else 塊中的 createNewFile()之前,您有一個 fileOutputStream 句柄。 如果文件不存在,則流不會創建文件。

不是真正的android特定的,但是為此目的有很多IO。 如果您一個接一個地執行許多“寫入”操作怎么辦? 您將閱讀全部內容並編寫全部內容,這需要時間,更重要的是電池壽命。

我建議使用 java.io.RandomAccessFile,seek()'ing 到最后,然后 writeChars() 追加。 這將是更干凈的代碼,並且可能會更快。

經過長時間的調查,我發現:

  • android.util.Log默認使用java.util.logging.Logger
  • LogCat 使用名稱為"" logger ,使用LogManager.getLogManager().getLogger("")獲取它的實例
  • 運行調試應用程序后,Android 設備將添加到com.android.internal.logging.AndroidHandler LogCat logger實例
  • 但是!!! 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()
    }

這個變體要短得多

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

你可以使用我寫的庫。 它非常易於使用:

將此依賴項添加到您的 gradle 文件中:

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. 創建一個新的應用程序類(創建一個新的 java 類並擴展應用程序)。 然后在 onCreate 方法中添加以下幾行:

     HyperLog.initialize(this); HyperLog.setLogLevel(Log.VERBOSE); HyperLog.getDeviceLogsInFile(this);
  3. 更改清單文件以定義應用程序文件。

     <application android:name=".AppClass" .....
  4. 不同的登錄方式:

     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. 找到您的日志文件。 導航到

    RootFolder/android/data/"appPackageName/LogFiles/
    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); }

試試這個在文件中寫入錯誤日志的代碼

public void appendLog(String text)
{       
   File logFile = new File("sdcard/log.file.txt");
   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();
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM