I have a problem with blocking buffer with the following code on my android application:
else if (tcpdumpButton.isChecked())
{
try
{
Process process1 = Runtime.getRuntime().exec("tcpdump");
BufferedReader osRes = new BufferedReader(new InputStreamReader(process1.getInputStream()));
StringBuffer output = new StringBuffer();
String line="";
while ((line = osRes.readLine()) != null)
{
output.append(line);
output.append("\n");
tv.setText(output);
setContentView(tv);
}
}
catch (Exception e)
{
throw e;
}
}
Since the tcpdump process is running continuously and never terminated i am unable to print the buffer contents on the screen.Can anybody tell me what i should do or give an example on how to read the buffer and print it on the screen without waiting for the process to terminate??
Sounds to me like the tcpdump process should be in its own thread.
You should take a look at multithreading in java - this way the main thread can continue running as per normal, and the additional thread can deal with the tcpdump and update the main thread with the status.
http://www.devarticles.com/c/a/Java/Multithreading-in-Java/
Related
First sorry for my bad English.
I have developed an app in Android Studio. It call tcpdump (Process process = Runtime.getRuntime().exec("su -c tcpdump -s 0 -v -w /sdcard/capture.pcap");). Initially it works correctly. However, tcpdump process is killed abruptly. Would anyone tell me why?
Thank you
It might tell you why on standard error:
final Process p = Runtime.getRuntime().exec(tcpdumpCommand);
final BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getErrorStream()));
(new Thread() {
public void run() {
while ((line = reader.readLine()) != null) {
Log.d("tcpdump", "stderr: " + line);
}
Log.d("tcpdump", "end of stderr");
}
}).start();
...and then look in logcat. Or try the same with getOutputStream() (for stdout) instead of getErrorStream().
Also if tcpdump was successfully capturing traffic and then abruptly stopped, one possible reason is you've filled the SD card.
I am trying to execute 'top' command with following code which is working correctly:
try {
Process proc = Runtime.getRuntime().exec("top");
InputStream is = proc.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is), 500);
StringBuilder output = new StringBuilder();
String line = "";
int count = 0;
while ((line = reader.readLine()) != null) {
if(line.trim().equals(""))
continue;
if (line.trim().startsWith("User")) {
count++;
if (count > 2)
break; //'top' command keeps repeating call to itself. we need to stop after 1 call
}
if (line.contains("PID")) {
mainInfo.append(output.toString());
output.delete(0,output.length());
continue;
}
output.append(line)
.append(CPUInfoUtil.SEPARATOR_LINE); //append this separator to help parsing
}
reader.close();
proc.destroy();
return output.toString();
} catch (FileNotFoundException e) {
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
This is returning me all processes including kernel/root processes. I want to get only system processes except woner=root. For that I tried following 'top' with following options, which didn't work:
Process proc = Runtime.getRuntime().exec(new String[]{"top","U","!root"});
I know I can also get running processes using following code but it does not provide additional information that 'top' provides (e.g. Cpu%, thread count etc):
((ActivityManager) act.getSystemService(Context.ACTIVITY_SERVICE)).getRunningServices(Integer.MAX_VALUE);
After doing a lot of homework I got this working! Following way 'top' can be used with as many options:
String[] cmd = {"sh","-c",
"top -m 100 -n 1"
};
Process proc = Runtime.getRuntime().exec(cmd);
I have use -m and -n options and its working great. See manual for whole list of options:
'top' options
I am using
Process psProc = Runtime.getRuntime().exec("top -n 1 -d 5");
to get all the process running and then calculate CPU usage for android apps.
I use ObjectAnimator and testing app on different devices. On some old slowly phones it animates too bad (no GPU, no memory etc), so I want to automatically switch user to second (lite) version of an app.
So how to detect what ObjectAnimator is slowly?
Is it have some framerate report? I found nothing.
Is Choreographer have same listener? it lists errors in catlog, but I want to get it in code.
01-22 05:55:15.775: INFO/Choreographer(3794): Skipped 33 frames! The application may be doing too much work on its main thread.
Note: I know how to parse catlog via system command, but it seems to me it is not a smart or fast solution.
Note2: I do not need to make things faster. I need to detect slow phone.
Ok, this solution works fine
It can be called from ObjAnimator's loop (listener - onRepeat, for example)
You can count events and make conclusion about speed of device.
p.s. it is not smart enought, but until nobody answered about native framerate report...
boolean getCatLog(){
boolean yes=false;
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output;
String lastLine = null;
while ((output = reader.readLine()) != null) {
lastLine = output;
}
if(lastLine!=null && lastLine.contains("Choreographer")){
Log.d(TAG,"yes!"); //do not remove!
yes=true;
}
reader.close();
process.waitFor();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return yes;
}
I have an application and I'd like to collect the LogCat messages of a specified level and tag.
Can I somehow get the accumulated messages at some point? I don't want to collect the messages one by one, it should be the sum of them like when I use adb to read the actual log. Is this possible?
Try this: Note that in Android 4 you will only see the log messages that were written by your own app unless you have root access.
public static String getLog(Context c) {
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder log = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append("\n");
}
return log.toString();
} catch (IOException e) {
return null;
}
}
Why not just write them to a file instead? LogCat is really for real-time logs. There are lots of good quality logging packages that can log to a file if that's what you want to do.
Just as an example:
How to write logs in text file when using java.util.logging.Logger
I am trying to read from the logcat output in my app. I am able to read in correctly, but it goes on reading it in endless loop. Somehow there seems no way to detect the end of stream.
Not sure what I am doing wrong.
Here is my code:
String baseCommand = "logcat -v time MyTag:D *:S";
Process process = null;
try {
process = Runtime.getRuntime().exec(baseCommand);
InputStreamReader reader = new InputStreamReader(process.getInputStream());
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine()) != null) {
Log.d("SomeOtherTag", line); //This line executes endlessly
}
} catch (IOException e) {
Log.e(DEBUG_TAG, "error in logging");
e.printStackTrace();
}
Logcat doesn't exit so the buffer is blocked.
Use 'logcat -d' in order to dump the log and then exit.
Hope this still helps, Yaron
Not positive but I believe you need to pass the logcat call if it has args in a String[] so it would be something like
String[] baseCommand = {"logcat", "-v", "time", "MyTag:D", "*:S"};
then the rest of your code.
The single string call is just the program name, not the args.