Android Writing Logs to text File
Hope this can help...
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();
}
}
Saving Logcat to a text file in Android Device
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");
Save Logcat from Android app to txt file
This worked for me it saves it in the main storage with this code:
Log.w("before","Logcat save");
try {
Process process = Runtime.getRuntime().exec("logcat -d");
process = Runtime.getRuntime().exec( "logcat -f " + "/storage/emulated/0/"+"Logging.txt");
}catch(Exception e)
{
e.printStackTrace();
}
Log output to file and system log at the same time
After doing some more research, it seems the Android API does not provide a standard way to do this. There are two possible workarounds:
Mirror output at the source
System.out
andSystem.err
output, which is written to the console in desktop systems, writes to the log on Android. These two can be redirected into anyPrintStream
of your choice, which would give you all Java console output. You can subclassPrintStream
to duplicate its input, feeding it into the default stream as well as into a file of your choice.- Create a class which exposes the same methods as
android.util.Log
. In each method, call through to the respectiveandroid.util.Log
method and additionally log the data to a file. If you call your classLog
(but with a different package name, e.g.org.example.Log
), then all you need to do is replace imports ofandroid.util.Log
with an import of your class, and anyLog
method calls will go to your class.
Caveats: This will only give you data explicitly logged by your code (i.e. for which you have the source files), as well as anything that goes to System.out
or System.err
. It will not include log output from JAR libraries (if you cannot modify their source code), nor any output generated by the system (such as stack traces from default exception handlers) or by other processes (some of which may be system processes and report conditions related to your process).
Read the logs from the command line
This article explains how to read the logs from within Android. In a nutshell:
- Android includes a command line utility called
logcat
on the device, which will give you a continuous feed of log messages until stopped. (Try it byadb shell
ing into your device and running it. It has a bunch of command-line options to control its behavior. Not sure if it is present on all distributions, though.) - Launch this command via
Runtime.getRuntime().exec("logcat")
, then obtain the input stream of the process returned. This will give you an input stream of log messages. - According to the article, your app needs the
android.permission.READ_LOGS
permission to read logs.
I have read statements that certain versions of Android (4.2 was mentioned) do not allow this permission to be granted to non-system apps, though. According to my own tests, behavior without this permissions differ: Anbox will return the full logcat, while LineageOS (tested on 15.1) will only show log entries from the app which called it (including previous instances, presumably everything associated with the same Linux user). This can be a limitation or a welcome filter feature. YMMV.
logcat
conveniently has a command line option, -f
, to specify an output file. I tried
Runtime.getRuntime().exec("logcat -f " + absolutePathToLogFile);
and logcat keeps logging as long as the app’s process runs. Killing the app (by clicking the X in the title bar on Anbox) apparently also terminated the child process.
Now you can either run this code when your app starts up, or you can turn this functionality into a separate app which starts on boot and continuously collects logs for all apps.
Caveats: This may fill up your storage space quickly if you have some chatty apps running (which is why entries rotate out of the logcat so quickly in the first place). It is recommended to make log mirroring configurable (e.g. via Preferences) and/or ensure old files are deleted regularly. Also, if you keep the logcat
process running until your app terminates, you will not be able to access the file over MTP as there is no easy way to run the media scanner (if you scan the file while it is still written to, it will appear truncated over MTP until another media scan runs).
Related Topics
Httpclient Won't Import in Android Studio
How to Sign Android App With System Signature
Custom Drawable For Progressbar/Progressdialog
How to Hide Soft Keyboard on Android After Clicking Outside Edittext
What Is Activity.Finish() Method Doing Exactly
How to Send a File in Android from a Mobile Device to Server Using Http
Sending Message Through Whatsapp
Adb Android Device Unauthorized
Android.View.Inflateexception: Binary Xml File Line #12: Error Inflating Class ≪Unknown≫
Android Get Free Size of Internal/External Memory
Check If Application Is on Its First Run
How to Add a Button Dynamically in Android
Android Drawing Separator/Divider Line in Layout
Get Selected Item Using Checkbox in Listview
How to Disable Copy/Paste From/To Edittext