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?
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");
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 -d
to dump the log rather than streaming it continuously. –
Aires process = Runtime.getRuntime().exec("logcat -f " + logFile);
didn't work using Android 5.1 versino. but thank you –
Ameeameer 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 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.
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.
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
Apparently android.permission.READ_LOGS is only granted to system apps in latest versions of Android.
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"
... >
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);
}
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
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
© 2022 - 2024 — McMap. All rights reserved.