Log Menulis Android ke File teks

128

Saya Mencoba Menulis Log ke File Custom Log.txt pada File Android menggunakan kode Tambang ini tetapi kemudian metode ini membuat file tetapi tidak mengandung apa pun. Pada dasarnya saya ingin membaca konten file sebelumnya dan kemudian menambahkan data saya dengan konten yang ada.

Kode tersebut adalah sebagai berikut:

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();
            }
        }
y ramesh rao
sumber

Jawaban:

247

Semoga ini bisa membantu ...

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();
   }
}
lebih cepat
sumber
82
Jangan lupa untuk menambahkan izin untuk writing_external_storage di Manifest!
virusss8
5
Saya perlu menambahkan buf.flush (); beforebuf.close (); tetapi fungsi ini persis apa yang saya butuhkan. terima kasih
Csabi
1
dari mana saya harus memanggil fungsi ini sehingga ia menulis semua file log in aplikasi ???
uniruddh
10
Saya akan merekomendasikan restrukturisasi kode sehingga buf.close()ada di dalam finallyblok.
William Price
2
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />itulah yang dimaksud @ virusss8, tentu saja.
Bengt
29

Bagi mereka yang baru masuk Java pada umumnya dan Android logging

  1. Log4j adalah implementasi generik java logging dan sekarang merupakan proyek dari yayasan perangkat lunak Apache. Ini bukan Android spesifik dan memiliki beberapa ketidakcocokan dengan Android.
  2. SL4J bukan implementasi logging, Ini adalah lapisan abstraksi. Ini membantu menghindari situasi seperti, setiap dependensi perpustakaan pihak ke-3 untuk suatu proyek, mencoba menggunakan implementasi logging sendiri seperti Log4j. Sumber .

Beberapa opsi untuk masuk ke txt di Android ada di bawah ini

  1. Gunakan logcat -fseperti dalam jawaban ini untuk masuk ke file. Perhatikan bahwa dari Android 4.2, izin READ_LOGS tidak memiliki dampak apa pun dan setiap Aplikasi (kecuali telepon di-rooting) hanya dapat membaca lognya sendiri. Kerugiannya di sini adalah buffer logcat berbentuk lingkaran dan memiliki batas ukuran. Anda mungkin tidak mendapatkan log sebelumnya.
  2. Gunakan microlog4android (ditulis untuk perangkat seluler seperti Android) seperti pada jawaban sebelumnya . Mungkin ada cara, tapi saya tidak tahu, cara menggunakan microlog4Android untuk masuk ke penyimpanan internal aplikasi. Satu-satunya pilihan untuk jalur log adalah penyimpanan eksternal seperti sdcard dan jadi saya tidak bisa menggunakannya.
  3. Gunakan Log4j dengan android-logging-log4j . Apa yang dilakukan android-logging-log4j? Itu membuat Log4j lebih mudah digunakan di Android dengan memberikan dua fungsi.

    • opsi untuk mengirim log ke logcat selain file logging
    • cara sederhana untuk mengatur opsi konfigurasi Log4j seperti jalur file, ukuran file maks, jumlah cadangan dll dengan menyediakan kelas LogConfigurator.

    Contoh sederhana di bawah ini. Perhatikan bahwa loggerobjek dalam contoh di bawah ini adalah objek Log4j yang dikembalikan dan bukan kelas android-logging-log4j. Jadi android-logging-log4j hanya digunakan untuk mengkonfigurasi Log4j.

  4. Belum mencoba LogBack . LogBack dikembangkan oleh orang yang sama yang datang dengan perpustakaan Log4J 1.x dan SL4J. Tidak terkait dengan Log4j 2.x.

Langkah-langkah untuk menggunakan Log4j di Android.

  1. Tambahkan kedua log4j-1.2.x.jar dan android-logging-log4j-1.0.3.jar ke folder libs.

  2. Tambahkan izin hanya jika menggunakan penyimpanan eksternal
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  3. Tulis Log4jkelas pembantu

    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. Di kelas aktivitas

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

Sumber Contoh . Perhatikan bahwa, log4j 2.x (peningkatan fungsionalitas) yang ditulis ulang dari awal tidak kompatibel dengan log4j 1.x. Jadi, Anda harus menggunakan jar log4j 1.2.x dengan jar android-logging-log4j. Saya dapat masuk ke file internal aplikasi dan kemudian mengirim email file tersebutsetReadable(true, false)

Kiran
sumber
24

microlog4android bekerja untuk saya tetapi dokumentasinya sangat buruk. Yang perlu mereka tambahkan adalah ini tutorial cepat .

Ini adalah tutorial singkat yang saya temukan.

  1. Tambahkan variabel statis berikut dalam Aktivitas utama Anda:

    private static final Logger logger = LoggerFactory.getLogger();
  2. Tambahkan yang berikut ke onCreate()metode Anda :

    PropertyConfigurator.getConfigurator(this).configure();
  3. Buat file dengan nama microlog.propertiesdan simpan di assetsdirektori

  4. Edit microlog.propertiesfile sebagai berikut:

    microlog.level=DEBUG
    microlog.appender=LogCatAppender;FileAppender
    microlog.formatter=PatternFormatter
    microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
    
  5. Tambahkan pernyataan logging seperti ini:

    logger.debug("M4A");

Untuk setiap kelas Anda membuat objek logger seperti yang ditentukan dalam 1)

6. Anda dapat menambahkan izin berikut:

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

Inilah sumber untuk tutorial

Henry Bennett
sumber
4
FileAppender akan membuat file "microlog.txt" pada sdcard Anda (path lengkap dalam kasus saya adalah "/sdcard/microlog.txt).
Ruslan Yanchyshyn
2
Tutorial singkat ini harus menjadi bagian dari dokumentasi resmi Microlog4Android.
Johan Karlsson
Kesalahan: Android Dex: [project] com.android.dex.DexException: Beberapa file dex menentukan Lcom / google / code / microlog4android / Level; ?
10

Peringatan: Saya mungkin benar-benar salah paham dengan Anda, tetapi jika semua yang Anda inginkan adalah file log, mengapa berkeringat?

Masukkan ini ke file bat (ubah path ke direktori tools Anda, dan namaanda Anda tentu saja nama aplikasi Anda):

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"

Kemudian dalam kode Anda lakukan sesuatu yang mirip dengan ini:

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

Untuk membuat log, sambungkan kabel USB dan jalankan file bat Anda.

Salam

BeMeCollective
sumber
Jangan lupa mengimpor android.util.Log.
Spidey
Ia mengembalikan "kesalahan: lebih dari satu perangkat dan emulator - menunggu perangkat -" dan tidak lebih. Ada yang salah?
eros
20
Bagaimana cara kerjanya jika Anda tidak berada di dekat PC saat menjalankan aplikasi?
DDSports
@ DDSports tidak. Tetapi dia tidak mengerti inti dari pertanyaan
Ewoks
@DDSports Anda dapat menggunakan adb melalui wifi.
Daniel F
8

Gunakan slf4android lib.
Ini implementasi sederhana dari slf4j api menggunakan android java.util.logging. *.

Fitur:

  • masuk ke file di luar kotak
  • masuk ke tujuan lain oleh LoggerConfiguration.configuration().addHandlerToLogger
  • guncangkan perangkat Anda untuk mengirim log dengan tangkapan layar melalui email
  • sangat kecil, hanya butuh ~ 55kB

slf4android dikelola terutama oleh @miensol .

Baca lebih lanjut tentang slf4android di blog kami:

klimat
sumber
7

Anda harus melihat microlog4android. Mereka memiliki solusi yang siap untuk masuk ke file.

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

darius
sumber
12
Ini sepertinya perpustakaan yang bagus, tetapi dokumentasinya mengerikan. Saya benar-benar tidak tahu bagaimana cara membuatnya bekerja dan akhirnya membuat sendiri sesuatu.
Paul Lammertsma
@ PaulLammertsma: Saya pikir akan menyenangkan jika Anda berkontribusi ke Microlog4Android sebagai gantinya. FYI: memiliki API yang sama dengan Log4j. Maaf tentang dokumentasi yang buruk.
Johan Karlsson
@ Paul Lammertsma Bagaimana bisa APA SAJA menjadi bagus jika dokumentasinya seburuk itu sehingga Anda tidak bisa menggunakannya? Jika Anda tidak berhasil, itu omong kosong.
The Jan
7

Ini mungkin terlambat tetapi harap ini dapat membantu .. Coba ini ....

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

di sini bfwritter.newlinemenulis teks Anda ke dalam file. Dan tambahkan izinnya

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

dalam file manifes Anda tanpa gagal.

AndroidOptimist
sumber
6

Saya memecahkan masalah ini dengan potongan kode berikut dalam cara baris perintah:

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

Di mana opsi "waktu" menambahkan rincian bidang metadata untuk tanggal, waktu pemanggilan, prioritas / tag, dan PID dari proses mengeluarkan pesan.

Kemudian dalam kode Anda lakukan sesuatu yang mirip dengan ini (menggunakan android.util.Log):

Log.d("yourappname", "Your message");
Nova
sumber
4
Berfungsi dengan baik ketika adbterhubung, tetapi tidak berfungsi ketika perangkat dalam mode mandiri. Saya tidak akan menggunakannya dalam produksi, tetapi ini adalah solusi sederhana dalam mode debug.
Julien Kronegg
2

Secara umum, Anda harus memiliki pegangan file sebelum membuka aliran. Anda memiliki pegangan fileOutputStream sebelum createNewFile () di blok lain. Aliran tidak membuat file jika tidak ada.

Tidak terlalu spesifik untuk Android, tapi itu banyak IO untuk tujuan ini. Bagaimana jika Anda melakukan banyak operasi "tulis" satu demi satu? Anda akan membaca seluruh konten dan menulis seluruh konten, meluangkan waktu, dan yang lebih penting, masa pakai baterai.

Saya sarankan menggunakan java.io.RandomAccessFile, cari () sampai akhir, kemudian tulisChars () untuk menambahkan. Ini akan menjadi kode yang jauh lebih bersih dan kemungkinan jauh lebih cepat.

Nate
sumber
2

Saya telah membuat kelas yang sederhana dan ringan (sekitar 260 LoC) yang memperluas implementasi standar android.util.Log dengan pencatatan berbasis file:
Setiap pesan log dicatat melalui android.util.Log dan juga ditulis ke file teks pada perangkat.

Anda dapat menemukannya di github:
https://github.com/volkerv/FileLog

Volker Voecking
sumber
1
bukan apa-apa kami perlu memastikan operasi file tidak dilakukan pada utas UI. Kalau kita punya banyak file logging?
Jayshil Dave
2

Setelah lama penyelidikan saya menemukan bahwa:

  • android.util.Log secara default digunakan java.util.logging.Logger
  • LogCat menggunakan loggerdengan nama "", untuk mendapatkan contoh penggunaannyaLogManager.getLogManager().getLogger("")
  • Perangkat Android menambah loggerinstance LogCat com.android.internal.logging.AndroidHandlersetelah menjalankan aplikasi debug
  • Tapi!!! com.android.internal.logging.AndroidHandlermencetak pesan ke logcat hanya dengan level lebih dari java.util.logging.Level.INFOseperti ( Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF)

Jadi untuk menulis log ke file hanya dengan rootLogger "" menambahkan 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
        }
    }
}

Untuk mencetak semua penebang di aplikasi Anda gunakan:

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()
    }
NickUnuchek
sumber
Hai. Apa manfaatnya menggunakan "" penebang ini. Saya tidak melihat perbedaan dengan logger khusus. atau saya kehilangan sesuatu?
Abins Shaji
1

Varian ini jauh lebih pendek

coba {
    path File akhir = File baru (
            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 ();
}
xoxol_89
sumber
1

Anda dapat menggunakan perpustakaan yang saya tulis. Ini sangat mudah digunakan:

Tambahkan ketergantungan ini ke file gradle Anda:

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

Inisialisasi perpustakaan di kelas Aplikasi:

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
    }

Ini adalah bagaimana Anda menggunakan perpustakaan:

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

Dan inilah cara mengambil log:

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

Berikut ini tautan ke halaman github dengan informasi lebih lanjut: https://github.com/danylovolokh/AndroidLogger

Semoga ini bisa membantu.

Danylo Volokh
sumber
1

Banyak versi sebelumnya pada log4j tidak berfungsi sekarang (20/519). Tetapi Anda dapat menggunakan Hyperlog - Saya dapat memastikan itu berfungsi.

  1. Tambahkan baris ini ke proyek dependensi & sinkronisasi Anda

    implementation 'com.hypertrack:hyperlog:0.0.10'
  2. Buat kelas aplikasi baru (buat kelas java baru dan perluas Aplikasi). Kemudian dalam metode onCreate tambahkan baris ini:

    HyperLog.initialize(this);
    HyperLog.setLogLevel(Log.VERBOSE);
    
    HyperLog.getDeviceLogsInFile(this);
  3. Ubah file manifes untuk menetapkan file aplikasi.

    <application
        android:name=".AppClass"
        .....
  4. Berbagai cara untuk login:

    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. Temukan file log Anda. Navigasi ke

    RootFolder/android/data/"appPackageName/LogFiles/
Haider Malik
sumber
Saya mencoba perpustakaan ini, dalam file yang dihasilkan dengan HyperLog.getDeviceLogsInFile (ini); hanya log yang terakhir dibuat di sana
mad_greasemonkey