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

Solution 1

Check out Log Collector as an example. Here is the relevant file.

The key is here:

ArrayList<String> commandLine = new ArrayList<String>();

Process process = Runtime.getRuntime().exec(commandLine);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

Solution 2

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) {

Solution 3

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


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 = > 0) {
        output.append(buffer, 0, read);

    // Waits for the command to finish.

    return output.toString();
} catch (IOException e) {

    throw new RuntimeException(e);

} catch (InterruptedException e) {

    throw new RuntimeException(e);

Solution 4

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 that actually does exactly what you want and it is used in to be displayed.

Solution 5

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(, "$it")
    } catch (e: InterruptedException) {
        Log.w(, "Cannot execute command [$command].", e)
    } catch (e: Exception) {
        Log.e(, "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.