Background: I'm working on application that will be used by limited users group and I will never put it on Store. App sometimes is having some troubles on clients devices and it seems like it would be very useful to me to have full access to logcat since I don't have access to devices. And I know that I have to give users "debug" app version - it's not a problem.
So I want to implement feature that allows user (eg. on my request) to redirect logcat to file, which can be sent to me. I already implemented redirecting to file, but I want to allow user for disabling saving to file since it gets big quite fast.
For redirecting to file I'm using
String cmd = "logcat -f " + file.getAbsolutePath();
Runtime.getRuntime().exec(cmd);
But once it's enabled I can't disable it. I mean stop saving to file. I tried with -c option with no luck.
What can I do?
Was asking myself the same thing...
This did the trick for me if anybody is still interested
Runtime.getRuntime().exec("logcat -f " + outputFile.getAbsolutePath() + " -d");
key is the "-d" here in the end.
You could also replace "-d" with "-t 1000" to print only the last 1000 lines to file and then stop.
Be aware that a new call to the same logfile will append logs. So you could delete that file if it already exists.
Runtime.getRuntime().exec() returns a process that you can kill, which will stop the logging.
// Start writing file
String cmd = "logcat -f " + file.getAbsolutePath();
Process logcatProcess = Runtime.getRuntime().exec(cmd);
// Stop writing file
logcatProcess.destroy();
You can switch it back to printing to stdout (default).
String cmd = "logcat -f stdout";
Runtime.getRuntime().exec(cmd);
I did not found solution to my problem, so it remains open. I just want to leave here my workaround as it might be useful.
So I decided to leave logcat printing to stdout and just dump it to file and then clear on button click. This solution have some advantages since logcat is separated in files with timestamps in names so I can look for problem depending on time when something happend.
You may want to call "ps | grep logcat" and kill it with its PID: "kill pid".
Related
I'm trying to redirect the getevent command in Android to a file on the device.
I tried. getevent > /path/to/file, but that didn't work. When I CTRL+C'd, the file was empty.
After further investigation, I discovered that it works if I use getevent's -c flag, which tells the process to terminate after a certain number of events are received. This leads me to believe that the problem is related to the fact that I'm killing the process. When I use tee instead of a >, I can see that the output does not show in stdout until the process finishes gracefully.
The problem of course is that getevent never terminates, and I can't use the -c flag because I won't know beforehand how many events are going to be received.
How can I redirect the getevent to a file in such a way that it is there even when the process is killed?
It's fine if the solution requires the device to be rooted.
Edit: I've discovered through further investigation, that if I ensure that at least 25 events have been sent, it writes to the file. But if I ensure 30 events have been sent, only those 25 events will be written to the file. This confirmed my suspicion, that it's a buffer issue.
In the end, I had to write a script calling getevent -c 1 in a loop.
I am using Monkeyrunner (automation) to test an app on an Android device (Samsung S2), and since it does not allow me to see image patterns on the screen, I have to rely on the adb logcat (using Windows) to look for specific messages in order to know when the next page has loaded for my automation script.
And in order to look for specific (unique) messages in the logcat, for my monkeyrunner script, I have to CLEAR out ALL the adb logs, then perform the search.
Is there a way to clear out only the line(s) that match a specific tag, message, text, or whatever(!), within the logcat log? Instead of clearing out everything?
Does the command line adb functionality allow you to clear specific lines, or is it an all or nothing kinda thing?
Clearing out all the logcat longs works, but it would be nice to ONLY clear out certain messages so that if/when there is an app crash, or some event where I need details for troubleshooting, I can see all the logs leading up to the crash (or significant event). Because if everything is cleared out, there is no way for me to see the logcat logs to troubleshoot whatever.
::: MORE INFORMATION :::
Here is the function I currently use to clear out all the logs.
def clearAdb():
p = subprocess.Popen("adb logcat -v time", shell=True, cwd="C:\Users\<USERNAME>AppData\Local\Android\sdk\platform-tools", stdout=subprocess.PIPE)
subprocess.Popen("adb logcat -c", shell=True, cwd="C:\Users\<USERNAME>AppData\Local\Android\sdk\platform-tools", stdout=subprocess.PIPE)
print("::: ADB cleared :::")
..and here's an example of how I am looking for the logcat log. This adb function waits indefinitely for a specific adb message, and process when seen.
def adb(message):
p = subprocess.Popen("adb logcat -v time", shell=True, cwd="C:\Users\<USERNAME>\AppData\Local\Android\sdk\platform-tools", stdout=subprocess.PIPE)
for line in p.stdout:
if message in line:
print("Got 'em")
break
else:
continue
...and this is how I currently use the functions together...
clearAdb()
adb("identifyGamePackage. com.tfg.nameofapplication")
To limit logcat output to messages which happened after certain moment you do not have to clear the log. Instead use logcat -T <timestamp> filter. Supported timestamp formats depend on the Android version - see -T paragraph in logcat -h output.
I want to make a simple script that starts recording and stops recording and sends the record as an E-mail attachment. Is that possible on Android? If not what language should I choose to create some alternative (for example an app)?
If you downvote follow, or at least tell me what's wrong in the comments.
Thank you in advance.
If you want run shell comand in Android app you can use this code:
Process process = Runtime.getRuntime().exec( " your comand here " );
Anyway there is no something like batch scripts. There is only applications.
I am doing set of steps using Android UIAutomator. I just want to collect logs during these steps.
Now am starting the adb logcat in terminal and running the ui automator seperately. Save the current logs to file before starting another test case.
Is there a way to collect logs for a particular time and clear the logs and start the next test case and collect logs for that test case.
Thanks in advance
You can filter by configurable log tags.
Log.d(TAG, message);
Specify separate tags for your groups in your tests and then you can easily grab just the ones you want at a time.
adb logcat -s "TAGNAME"
Run your test through fully so all logs are in the logcat then add the logs to a text file in their groupings by iterating through your tags in a script. Pseudo code:
for (TAG in MYTAGS) {
abd logcat -s TAG >> mylogfile
}
Add custom tag in your UI Automator script:
private static final String TAG = "Script_Name";
Log.d(TAG, "message");
Write a simple batch script to collect logs and start it before you run your script:
adb logcat -c //To clear previous logs
adb logcat -s Script_Name > Log.txt //Saves your Script specific logs into Log.txt
After some play around with rooted devices, I got stuck on the files. Let's say we have a file somewhere in the root folder which I want to read/write from my application. The only way I found so far is changing the file permission like
String [] cmd = { "su", "-c", "chmod", "777", path};
Process process = new ProcessBuilder(cmd).start();
process.waitFor();
This works fine, the problem is that I want to return back the original file permissions after I'm done with it.
Can anybody help me with getting a file/directory current permissions?
Do ls -l on file/directory and parse the output
EDIT BY OP: the solution is in this thread. This answer just pushed me in the right direction.