Is there any way to run terminal commands on my application and then access the data on my UI? Specifically top
.

- 169,610
- 28
- 168
- 175

- 11,350
- 16
- 58
- 89
5 Answers
Check out Log Collector as an example. Here is the relevant file.
The key is here:
ArrayList<String> commandLine = new ArrayList<String>();
commandLine.add("logcat");//$NON-NLS-1$
[...]
Process process = Runtime.getRuntime().exec(commandLine);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

- 76,846
- 14
- 164
- 167
-
so basically if I would like to run top, I could just replace commandLine with top and it should work fine right? I am getting an error so I guess I will need a little more help.. thanks.. – Shouvik Jul 28 '10 at 11:40
-
Do I need to surround the Process process = Runtime.getRuntime().exec(commandLine); with a try and catch because I keep getting this throws IOException. I have looked at the java examples seem to handle it that way... – Shouvik Jul 28 '10 at 12:33
-
Yes.. again, check out the link to see everything they do. You definitely need to do error checking - don't expect 'top' to be there on all phones. – EboMike Jul 28 '10 at 16:15
-
1This is now banned by Google – Andy M Oct 07 '20 at 13:23
Okay this is what exactly worked for me just in case anyone needs it in the future... :)
Surround in try and catch
try {
Process process = Runtime.getRuntime().exec("top -n 1 -d 1");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
} catch (InterruptedException e) {
e.printStackTrace();
}

- 14,215
- 14
- 85
- 114

- 11,350
- 16
- 58
- 89
-
2When I do that followed by String result = null; result = bufferedReader.readLine(); Log.i("OnClickListener", "result: " + result); It displays only "result:" (the 'result' string is empty). Any thoughts as to why this would be? Also, when I try process = Runtime.getRuntime().exec("/system/bin/ping abc"); instead, the 'result' string is null. Both of those commands work as expected from an 'adb shell' terminal. – David Doria Sep 17 '13 at 17:15
-
Sorry @DavidDoria, I have not touched android in 2 years now. It was something I tried my hand at while in college. You would be better off posting it as a question. – Shouvik Sep 20 '13 at 16:01
-
2I got it working. The problem was the that the first line from 'top' WAS empty (a new line, to create the table). The case of it returning null when there was actually output was because I needed to get stderror (getErrorStream) instead of stdout (getInputStream). – David Doria Sep 20 '13 at 17:38
We, can execute commands as follow, i was succesfull in doing this....! try like this, here we need to specify the complete path of command. to get the complete path of commmand, at ur terminal (android) type
*$ which ls
/system/bin*
try {
// Executes the command.
Process process = Runtime.getRuntime().exec("/system/bin/ls /sdcard");
// Reads stdout.
// NOTE: You can write to stdin of the command using
// process.getOutputStream().
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
// Waits for the command to finish.
process.waitFor();
return output.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
it also depends on what you are running in the terminal... if you are running "cat" on a file you can also do it like this.
final private String MEM_FILE = "/proc/meminfo";
public Long readMem() {
String[] segs;
FileReader fstream;
try {
fstream = new FileReader(MEM_FILE);
} catch (FileNotFoundException e) {
Log.e("readMem", "Could not read " + MEM_FILE);
return false;
}
BufferedReader in = new BufferedReader(fstream, 500);
String line;
try {
while ((line = in.readLine()) != null) {
if (line.indexOf("MemTotal:") > 0) {
Log.e("MemTotal", line);
segs = line.trim().split("[ ]+");
memTotal = Long.parseLong(segs[1]);
}
if (line.indexOf("MemFree:") > 0) {
Log.e("MemFree", line);
segs = line.trim().split("[ ]+");
memFree = Long.parseLong(segs[1]);
}
}
updateMem(); //call function to update textviews or whatever
return true;
} catch (IOException e) {
Log.e("readMem", e.toString());
}
return false;
}
EDIT: There is a perfect example for you in the android labs project called netmeter. There is a class called Top.java that actually does exactly what you want and it is used in TaskList.java to be displayed. http://code.google.com/p/android-labs/source/browse/#svn/trunk/NetMeter/src/com/google/android/netmeter

- 2,902
- 1
- 19
- 19
-
Not cat, I specifically want to run top and get the live results displayed on the screen. I am aware of applications which emulate the terminal on which I have found top working, so I was wondering how I could just pull the results of top and display them on the UI. – Shouvik Jul 28 '10 at 11:33
-
See my edits above for a working example of exactly what you want. – androidworkz Jul 28 '10 at 12:42
-
Hey thanks... Need to spend some time here, but I think this is it... You have been a great help! – Shouvik Jul 29 '10 at 05:05
-
For Kotlin enthusiasts, you can use the following
fun executeShell() {
val command: String = "top -n 1"
try {
val process: Process = Runtime.getRuntime().exec(command)
// Read the lines using BufferedReader
BufferedReader(InputStreamReader(process.inputStream)).forEachLine {
// Do something on each line read
Log.d(this::class.java.canonicalName, "$it")
}
} catch (e: InterruptedException) {
Log.w(this::class.java.canonicalName, "Cannot execute command [$command].", e)
} catch (e: Exception) {
Log.e(this::class.java.canonicalName, "Cannot execute command [$command].", e)
}
}
You won't even have to take care of closing the buffer, as forEachLine extension function takes care of it.

- 968
- 3
- 14
- 32