Android Scrierea jurnalelor în fișier text (Programare, Android)

y ramesh rao a intrebat.

Încerc să scriu jurnalele în fișierul Log.txt personalizat pe Android File folosind acest cod al meu, dar apoi această metodă creează fișierul, dar nu conține nimic. Practic, vreau să citesc conținutul anterior al fișierului și apoi să adaug datele mele cu conținutul existent.

Codul este după cum urmează :

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

15 răspunsuri
outkkast

Sper că acest lucru vă poate ajuta…

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

Comentarii

    84

  • Nu uitați să adăugați permisiunea pentru writing_external_storage în Manifest! –  > Por virusss8.
  • Aveam nevoie să adaug buf.flush(); beforebuf.close(); dar această funcție a fost exact ceea ce aveam nevoie. mulțumesc –  > Por Csabi.
  • de unde ar trebui să chem această funcție astfel încât să scrie toate jurnalele aplicației în fișier????? –  > Por uniruddh.
  • V-aș recomanda să restructurați codul astfel încât buf.close() se află în interiorul unui finally bloc. –  > Por William Price.
  • <uses-permission android_name="android.permission.WRITE_EXTERNAL_STORAGE" /> a fost ceea ce a vrut să spună @virusss8, bineînțeles. –  > Por Bengt.
kiranpradeep

Pentru cei noi în logarea Java în general și în logarea Android

  1. Log4j este o implementare generică de logare java și este acum un proiect alApache software foundation. Nu este specific Android și, prin urmare, are unele incompatibilități cu Android.
  2. SL4J nu este o implementare de logare, ci un strat de abstractizare. Acesta ajută la evitarea situațiilor în care, de exemplu, fiecare bibliotecă terță parte depinde de un proiect, încercând să utilizeze propria implementare de logare, cum ar fi Log4j. Sursă.

Mai jos sunt prezentate câteva opțiuni pentru logarea în txt în Android

  1. Utilizați logcat -f ca în acest răspuns pentru a înregistra în fișier. Rețineți că, începând cu Android 4.2, permisiunea READ_LOGS nu mai are niciun impact și fiecare aplicație (cu excepția cazului în care telefonul este înrădăcinat) poate citi doar propriile jurnale.Dezavantajul aici este că bufferul logcat este circular și are o limită de dimensiune. Este posibil să nu primiți jurnalele anterioare.
  2. Utilizați microlog4android (scris pentru dispozitive mobile precum Android), ca în răspunsul anterior. Ar putea exista o modalitate, dar nu am putut să-mi dau seama cum să folosesc microlog4Android pentru înregistrarea în memoria internă a aplicației.Singura opțiune pentru calea jurnalelor a fost memoria externă, cum ar fi sdcard, așa că nu am putut să o folosesc.
  3. Utilizați Log4j cu android-logging-log4j. Ce face android-logging-log4j ? Face Log4j mai ușor de utilizat în Android prin oferirea a două funcții.

    • opțiunea de a trimite jurnalele la logcat în plus față de fișierul de jurnalizare
    • o modalitate simplă de a seta opțiunile de configurare Log4j, cum ar fi calea fișierului, dimensiunea maximă a fișierului, numărul de copii de rezervă etc., prin furnizarea clasei LogConfigurator.

    Exemplu simplu mai jos. Observați că logger din exemplul de mai jos este un obiect Log4j returnat și nu o clasă android-logging-log4j. Astfel, android-logging-log4j este utilizat numai pentru configurarea Log4j.

  4. Încă nu ați încercat LogBack. LogBack este dezvoltat de aceeași persoană care a creat bibliotecile Log4J 1.x și SL4J. Nu are legătură cu Log4j 2.x, deși.

Pași pentru utilizarea Log4j în Android.

  1. Adăugați ambele log4j-1.2.x.jar și android-logging-log4j-1.0.3.jar la dosarul libs.

  2. Adăugați permisiuni numai dacă utilizați o memorie externă
    <uses-permission android_name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  3. Scrieți Log4j clasa helper

    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. În clasa Activity

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

Exemplu Sursa. Rețineți că, log4j 2.x (funcționalități îmbunătățite) rescris de la zero nu este compatibil cu log4j 1.x. Deci, trebuie să utilizați jar log4j 1.2.x cu jar android-logging-log4j. Am reușit să înregistrez în fișierul intern al aplicației și mai târziu să trimit fișierul prin e-mail cu setReadable(true, false)

Henry Bennett

microlog4android funcționează pentru mine, dar documentația este destul de săracă. Tot ceea ce trebuie să adauge este un acest lucru este un început rapid tutorial.

Iată un tutorial rapid pe care l-am găsit.

  1. Adăugați următoarea variabilă statică în activitatea dvs. principală:

    private static final Logger logger = LoggerFactory.getLogger();
    
  2. Adăugați următoarele în activitatea dvs. onCreate() metoda:

    PropertyConfigurator.getConfigurator(this).configure();
    
  3. Creați un fișier numit microlog.properties și stocați-l în assets directorul

  4. Modificați fișierul microlog.properties după cum urmează:

    microlog.level=DEBUG
    microlog.appender=LogCatAppender;FileAppender
    microlog.formatter=PatternFormatter
    microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
    
  5. Adăugați declarații de logare de genul următor:

    logger.debug("M4A");
    

Pentru fiecare clasă creați un obiect logger așa cum se specifică la punctul 1)

6.Se poate adăuga următoarea permisiune:

    <uses-permission android_name="android.permission.WRITE_EXTERNAL_STORAGE" />

Aici este sursa pentru tutorial

Comentarii

  • FileAppender va crea un fișier „microlog.txt” pe sdcard-ul dvs. (calea completă în cazul meu este „/sdcard/microlog.txt). –  > Por Ruslan Yanchyshyn.
  • Acest tutorial rapid ar trebui să facă parte din documentația oficială Microlog4Android. –  > Por Johan Karlsson.
  • Eroare: Android Dex: [proiect] com.android.dex.DexException: Mai multe fișiere dex define Lcom/google/code/microlog4android/Level; ? – user2660852
BeMeCollective

Avertizare: S-ar putea să vă înțeleg total greșit, dar dacă tot ce doriți este un fișier jurnal, de ce să transpirați?

Puneți acest lucru într-un fișier bat (schimbați calea către directorul de instrumente, iar yourappname este, bineînțeles, numele aplicației dumneavoastră):

cd "C:devAndroidSoftwareandroid-sdk-windows-1.6_r1android-sdk-windows-1.6_r1tools"
adb logcat -v time   ActivityManager:W  yourappname:D  *:W >"C:devAndroidlogyourappname.log"

Apoi, în codul tău, fă ceva similar cu acest lucru:

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

Pentru a crea jurnalul, conectați cablul USB și rulați fișierul bat.

Salutări

Comentarii

  • Nu uitați să importați android.util.Log. –  > Por Spidey.
  • Acesta returnează „error: more than one device and emulator – waiting for device -” și nimic mai mult. Aveți ceva în neregulă? –  > Por eros.
  • 21

  • Cum funcționează dacă nu sunteți în apropierea unui PC în timp ce rulați aplicația? –  > Por DDSports.
  • @DDSports nu este așa. Dar el nu a înțeles esența întrebării –  > Por Ewoks.
  • @DDSports poți folosi adb prin wifi. –  > Por Daniel F.
klimat

Utilizați slf4android lib.
Este o implementare simplă a slf4j api utilizând android java.util.logging.*.

Caracteristici:

  • logare în fișier din start
  • logare către orice altă destinație prin LoggerConfiguration.configuration().addHandlerToLogger
  • scuturarea dispozitivului pentru a trimite jurnalele cu captură de ecran prin e-mail
  • foarte mic, ocupă doar ~55kB

slf4android este întreținut în principal de @miensol.

Citiți mai multe despre slf4android pe blogul nostru:

darius

Ar trebui să aruncați o privire la microlog4android. Ei au o soluție pregătită pentru a înregistra într-un fișier.

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

Comentarii

  • Aceasta pare a fi o bibliotecă bună, dar documentația este teribilă. Pur și simplu nu am putut să-mi dau seama cum să o fac să funcționeze și am ajuns să pun ceva împreună eu însumi. –  > Por Paul Lammertsma.
  • @PaulLammertsma: Cred că ar fi frumos ca tu să contribui la Microlog4Android în schimb. FYI: are același API ca și Log4j. Îmi pare rău pentru documentația proastă. –  > Por Johan Karlsson.
  • @Paul Lammertsma Cum ar putea fi ceva bun dacă documentația este atât de proastă încât nu o poți folosi? Dacă nu poți să-l faci să funcționeze, este un rahat. –  > Por Incredibilul Jan.
AndroidOptimist

Acest lucru poate fi târziu, dar sper că acest lucru poate ajuta..Încercați acest lucru….

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

aici bfwritter.newline scrie textul dvs. în fișier. Și adăugați permisiunea

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

în fișierul manifest fără greș.

Nova

Am rezolvat această problemă cu următoarea bucată de cod în linie de comandă:

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

În cazul în care opțiunea „time” adaugă detalii ale câmpului de metadate pentru data, ora de invocare, prioritate/tag și PID al procesului care emite mesajul.

Apoi, în codul dvs. trebuie doar să faceți ceva similar cu acest lucru (utilizând android.util.Log):

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

Comentarii

  • Funcționează bine atunci când adb este conectat, dar nu funcționează atunci când dispozitivul este în modul autonom. Nu l-aș folosi în producție, dar este o soluție simplă în modul de depanare. –  > Por Julien Kronegg.
Nate

În general, trebuie să aveți un mâner de fișier înainte de a deschide fluxul. Aveți un handle fileOutputStream înainte de createNewFile() în blocul else. Fluxul nu creează fișierul dacă acesta nu există.

Nu este cu adevărat specific Android, dar este mult IO pentru acest scop. Ce se întâmplă dacă efectuați mai multe operații de „scriere” una după alta? Veți citi întregul conținut și veți scrie întregul conținut, ceea ce va lua timp și, mai ales, va consuma bateria.

Vă sugerez să folosiți java.io.RandomAccessFile, seek()’ing până la capăt, apoi writeChars() pentru a adăuga. Va fi un cod mult mai curat și probabil mult mai rapid.

Volker Voecking

Am creat o clasă simplă și ușoară (aproximativ 260 LoC) care extinde implementarea standard android.util.Log cu jurnalizare bazată pe fișiere:
Fiecare mesaj de jurnal este înregistrat prin android.util.Log și, de asemenea, scris într-un fișier text pe dispozitiv.

O puteți găsi pe github:
https://github.com/volkerv/FileLog

Comentarii

  • dont you thing trebuie să ne asigurăm că operațiile cu fișiere nu sunt efectuate pe firul UI. În cazul în care avem o cantitate mare de logare a fișierelor? –  > Por Jayshil Dave.
NickUnuchek

După o lungă perioadă de timp de investigație am constatat că:

  • android.util.Log în mod implicit, utilizați java.util.logging.Logger
  • LogCat utilizează logger cu numele "", , pentru a obține o instanță a acestuia folosiți LogManager.getLogManager().getLogger("")
  • Dispozitive Android adaugă la LogCat logger instanța de com.android.internal.logging.AndroidHandler după rularea aplicațiilor de depanare
  • Dar!!! com.android.internal.logging.AndroidHandler tipărește mesaje în logcat doar cu niveluri mai mari decât java.util.logging.Level.INFO cum ar fi (Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF)

Deci, pentru a scrie jurnalele în fișier, este suficient să se facă o simplă comandă rootLogger "" adăugați un 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
"
    }
}

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
        }
    }
}

Pentru a imprima toate jurnalele din aplicația dvs. utilizați:

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

Comentarii

  • Care este avantajul utilizării acestui logger „”. Nu văd nicio diferență față de un logger personalizat. sau îmi scapă ceva? –  > Por Abins Shaji.
xoxol_89

Această variantă este mult mai scurtă

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

Danylo Volokh

Puteți folosi biblioteca pe care am scris-o. Este foarte ușor de folosit:

Adăugați această dependență în fișierul gradle:

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

Inițializați biblioteca în clasa 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
    }

Acesta este modul în care utilizați biblioteca:

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

Și iată cum se recuperează jurnalele:

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

Aici este linkul către pagina github cu mai multe informații:https://github.com/danylovolokh/AndroidLogger

Sper că vă ajută.

Haider Malik

Multe dintre versiunile anterioare pe log4j nu funcționează acum (05/2019). Dar puteți folosi Hyperlog – pot confirma că funcționează.

  1. Adăugați această linie la dependențele dvs. & proiect de sincronizare

    implementation 'com.hypertrack:hyperlog:0.0.10'
    
  2. Creați o nouă clasă de aplicație (creați o nouă clasă java și extindeți Application). Apoi, în metoda onCreate, adăugați aceste linii:

    HyperLog.initialize(this);
    HyperLog.setLogLevel(Log.VERBOSE);
    
    HyperLog.getDeviceLogsInFile(this);
    
  3. Modificați fișierul manifest pentru a avea fișierul de aplicație definit.

    <application
        android_name=".AppClass"
        .....
    
  4. Diferite moduri de a înregistra:

    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. Găsiți fișierele de jurnal. Navigați la

    RootFolder/android/data/"appPackageName/LogFiles/
    

Comentarii

  • Am încercat această bibliotecă, în fișierul generat cu HyperLog.getDeviceLogsInFile(this); doar ultimul jurnal generat este acolo –  > Por mad_greasemonkey.
kader hussain
    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); }

încercați acest cod pentru scrierea jurnalului de erori în fișier

Tags: