Saving Logcat to a text file in Android Device
Asked Answered
D

9

38

I had found some crashes while running the application in android device, which is not showing in emulator. So i need to save the Logcat in a text file in my device's memory or SD card. Could you please suggest me good method to do this?

Degraw answered 24/10, 2013 at 12:16 Comment(0)
W
88

Use an Application class at the beginning of your app. That allows a proper file and log handling.

Code below creates a log file at the following location:

/ExternalStorage/MyPersonalAppFolder/logs/logcat_XXX.txt

XXX is the current time in milliseconds. Every time you run your app, a new logcat_XXX.txt file will be created.

public class MyPersonalApp extends Application {

    /**
     * Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.
     */
    public void onCreate() {
        super.onCreate();

        if ( isExternalStorageWritable() ) {

            File appDirectory = new File( Environment.getExternalStorageDirectory() + "/MyPersonalAppFolder" );
            File logDirectory = new File( appDirectory + "/logs" );
            File logFile = new File( logDirectory, "logcat_" + System.currentTimeMillis() + ".txt" );

            // create app folder
            if ( !appDirectory.exists() ) {
                appDirectory.mkdir();
            }

            // create log folder
            if ( !logDirectory.exists() ) {
                logDirectory.mkdir();
            }

            // clear the previous logcat and then write the new one to the file
            try {
                Process process = Runtime.getRuntime().exec("logcat -c");
                process = Runtime.getRuntime().exec("logcat -f " + logFile);
            } catch ( IOException e ) {
                e.printStackTrace();
            }

        } else if ( isExternalStorageReadable() ) {
            // only readable
        } else {
            // not accessible
        }
    }

    /* Checks if external storage is available for read and write */
    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if ( Environment.MEDIA_MOUNTED.equals( state ) ) {
            return true;
        }
        return false;
    }

    /* Checks if external storage is available to at least read */
    public boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        if ( Environment.MEDIA_MOUNTED.equals( state ) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals( state ) ) {
            return true;
        }
        return false;
    }
}

you need the correct permissions and name of your application class in your .manifest file:

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

<application
    android:name=".MyPersonalApp"
    ... >

Edit:

if you want to save log of only some particular activities..

replace:

process = Runtime.getRuntime().exec("logcat -f " + logFile);

with:

process = Runtime.getRuntime().exec( "logcat -f " + logFile + " *:S MyActivity:D MyActivity2:D");
Wordage answered 31/5, 2016 at 9:16 Comment(21)
This is the best and most complete answer.Unlearned
Worked perfectly! Thanx so much!Doridoria
I wanna to thank you for this answer, very much! @HeisenBergNatalia
nut how do u stop the logcat from writing? or does it stops when onDestroy() is called?Actinomycosis
This code is specific to your application. It writes to log as long as your app is running.Wordage
another thing, when i tried something like this in my code, and closed the app, the second time i entered the app (few seconds later) it didn't went through Application's onCreate() but just through the Activity's onCreate() so it didn't create a new log file, but just contiued writing to old one... any suggestions for that?Actinomycosis
I think your app was still running in the background. Are you sure you closed the app or just minimized by pressing home button?Wordage
@HeisenBerg Thanks for the answer. I added this to my old existing app (whose main class extends the Activity rather than the Application class) and noticed that t least once it created overlapping logs, i.e. an old one kept going and a new one was created. Is there an easy way to fix that?Hexapod
Thank you, very useful! Small addition in case someone out there has trouble with it: Since android 6 "dangerous" permissions need to be obtained at runtime, see developer.android.com/training/permissions/requesting.html on how to request it, orr you can just give the permission from the settings.So if you have the above code, but the file is not being written your app is probably just missing the permission.Swaziland
Use flag -d to dump the log rather than streaming it continuously.Aires
How to keep saving all the log from anywhere in the app? with this code it only save two lines......Peerless
How i have to call this class or it is doing by its self like a service class?Oversew
Only the WRITE_EXTERNAL_STORAGE permission is enough. Also make sure to have enabled storage permission from Settings> your app> permissionsIgnoble
When I tried this code, there were many files created for one time as there were so many lines in the logs. This is will cause memory efficiency problems. can i make the entire log to be saved in same file? and how can i automatically save logs of say 3 days. after that if we try to save it, the first day's logs are automatically deleted.Thrave
Currently it creates new files with its name as "logcat + currentTimeInMillis". You may modify the code to append to the same file. As far is memory efficiency is concerned, I believe it's writing to only one file at a time.Wordage
ok thanks. Can you help me with how to delete the previous logs when new ones are added like saving the logs of about 3 days any time?Thrave
You will need to list all files #1845188 then check last modified and delete it #15043355Wordage
How to set max size of the file?Glynn
though process = Runtime.getRuntime().exec("logcat -f " + logFile); didn't work using Android 5.1 versino. but thank youAmeeameer
I am getting closer to what I did several years ago with one of my Apps! I just forgot howto... I remember I could extend Activity, override some method or methods I just don't remember, process any single Log produced by my App (to send them in error reports for example), then call super on that method/s and it's done!! Or perhaps I am too oblivious and it was just for handling crashes... I am just about to launch a beta version on some App and I want to provide Beta Testers some way to send me in their Report Forms some fragment of their LogCat history...Filar
READ_LOGS Permission is only granted to system apps.Ogre
S
15
adb shell logcat -t 500 > D:\logcat_output.txt

Go onto your terminal/command prompt and navigate to the folder with adb in it, if its not already added to your environmental variables and paste this command.

t is the number lines you need to view

D:\logcat_output.txt is where your logcat will get stored.

Smuggle answered 24/10, 2013 at 12:23 Comment(8)
Can u give a solution to write the file to my device when it is not connected to my Computer..?Degraw
I don't quite get your question, how are you going to access the android debug bridge when not connected to a computer?Smuggle
play.google.com/store/apps/…Smuggle
@Smuggle - the poster wants to start this, disconnect the cable, and have it keep recording.Skylab
how to sort by application? What add to this command 'adb logcat > D:\logcat_output.txt'Glynn
Isn't there a simple way to do this, by just connecting the Android device as an external storage medium via USB, without the need to install adb or any such tools? Can't we simply copy the logfile from the filesystem somehow?Akira
I found it remarkable that this answer was actually accepted by the author of the question!Rivet
How to Save only Log.d? Currently the other Logs are also being saved int he fileSjambok
C
10

Use -f option with logcat in your class:

Runtime.getRuntime().exec("logcat -f" + " /sdcard/Logcat.txt");

This will dump the logs to the file stored device.

Note that the path "/sdcard/" may not be available in all devices. You should use the standard APIs to access the external storage.

Couldst answered 7/3, 2014 at 11:1 Comment(1)
This blog post may help- journal.deviantdev.com/android-log-logcat-to-file-while-runtimeHyacinthie
A
8

As I cannot comment yet, I`ll post this as an answer

I did as @HeisenBerg said, worked fine for me, but since from android 6.0 on we have to ask for permission at Run Time, I had to add the following:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if(checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    }
}

And call

process = Runtime.getRuntime().exec("logcat -f " + logFile);

Only on the callback onRequestPermissionsResult

Airminded answered 18/4, 2017 at 13:57 Comment(0)
M
5

Apparently android.permission.READ_LOGS is only granted to system apps in latest versions of Android.

Mammary answered 22/12, 2018 at 17:52 Comment(2)
bad news and any suggestion on how to write logs to file?Freestanding
@Freestanding For your application logs, you have to use your own Logger class and redirect the logs to your file. For general device logs, try to get in touch with the device manufacturer and ask how to enable this feature. I know some brands do, like Samsung.Mammary
C
3

I adjusted Drunken Daddy's answer to not need Permissions and migrated it to Kotlin.

Use an Application class at the beginning of your app. That allows a proper file and log handling.

Code below creates a log file at the following location:

/Android/data/com.your.app/files/logs/logcat_XXX.txt

XXX is the current time in milliseconds. Every time you run your app, a new logcat_XXX.txt file will be created.

import android.app.Application
import java.io.File
import java.io.IOException

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        getExternalFilesDir(null)?.let { publicAppDirectory -> // getExternalFilesDir don't need storage permission
            val logDirectory = File("${publicAppDirectory.absolutePath}/logs")
            if (!logDirectory.exists()) {
                logDirectory.mkdir()
            }

            val logFile = File(logDirectory, "logcat_" + System.currentTimeMillis() + ".txt")
            // clear the previous logcat and then write the new one to the file
            try {
                Runtime.getRuntime().exec("logcat -c")
                Runtime.getRuntime().exec("logcat -f $logFile")
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
}

Set Application in AndroidManifest.xml:

<application
    android:name=".MyApplication"
    ... >
Cannoneer answered 9/3, 2021 at 12:23 Comment(1)
The file location has nothing in the /Android/data/ location. I am using Android 12.Ferne
K
2

Add the manifest permission:

uses-permission android:name="android.permission.READ_LOGS" 


private static final String COMMAND = "logcat -d -v time";


public static void fetch(OutputStream out, boolean close) throws IOException {
    byte[] log = new byte[1024 * 2];
    InputStream in = null;
    try {
        Process proc = Runtime.getRuntime().exec(COMMAND);
        in = proc.getInputStream();
        int read = in.read(log);
        while (-1 != read) {
            out.write(log, 0, read);
            read = in.read(log);
        }
    }
    finally {
        if (null != in) {
            try {
                in.close();
            }
            catch (IOException e) {
                // ignore
            }
        }

        if (null != out) {
            try {
                out.flush();
                if (close)
                    out.close();
            }
            catch (IOException e) {
                // ignore
            }
        }
    }
}

public static void fetch(File file) throws IOException {
    FileOutputStream fos = new FileOutputStream(file);
    fetch(fos, true);
}
Knitted answered 24/10, 2013 at 13:36 Comment(2)
How to write logs continuously to some file?? i guess this code will write the logs till the call made to this code.Icsh
The code above is just a snapshot of the log at a point in time. If you want to write logs continuously use Java's Logging w/ a FileLogger and write to that.Knitted
B
1

If you only need to save the logcat (without your coding) you can use aLogrec or aLogcat applications from Google Play.

Google Play Store: aLogcat & aLogrec

Braziel answered 9/1, 2014 at 8:19 Comment(1)
From Android Jelly Bean on, an app can't read the logs of another without being a system app.Shadwell
N
0

Drunken Daddy's answer is perfect. I would like to add though,

Environment.getExternalStorageDirectory()

is deprecated in API level 29 and Android Studio does not give you any warnings. Instead, you need to use

context.getExternalFilesDir(null);

which returns

/storage/emulated/0/Android/data/com.domain.myapp/files
Nonego answered 10/4, 2021 at 5:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.